from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
from kivy.uix.label import Label
import cv2,os
import shutil
import csv
import numpy as np
import pandas as pd
from datetime import datetime
import time
from PIL import Image
import os.path, time
import datetime

class CreateAccountWindow(Screen):

    def submit(self):
            sm.current = "login"

    def TrackImages(self):
        recognizer = cv2.face.LBPHFaceRecognizer_create()
        recognizer.read("TrainingImageLabel/Trainner.yml")
        harcascadePath = "haarcascade_frontalface_default.xml"
        faceCascade = cv2.CascadeClassifier(harcascadePath);
        df=pd.read_csv("StudentDetails/StudentDetails.csv")
        cam = cv2.VideoCapture(0)
        font = cv2.FONT_HERSHEY_SIMPLEX
        col_names =  ['ID','Name','Date','Time']
        attendance = []
        while True:
            ret, im =cam.read()
            gray=cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
            faces=faceCascade.detectMultiScale(gray, 1.2,5)
            for(x,y,w,h) in faces:
                cv2.rectangle(im,(x,y),(x+w,y+h),(225,0,0),2)
                Id, conf = recognizer.predict(gray[y:y+h,x:x+w])
                if 'Id' in df and (conf < 50):
                    ts = time.time()
                    date = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d')
                    timeStamp = datetime.datetime.fromtimestamp(ts).strftime('%H:%M:%S')
                    aa=df.loc[df['Id'] == Id]['Name'].values
                    tt=str(Id)+"-"+aa
                    attendance = [Id,aa,date,timeStamp]

                else:
                    Id='Unknown'
                    tt=str(Id)
                if(conf > 75):
                    noOfFile=len(os.listdir("ImagesUnknown"))+1
                    cv2.imwrite("ImagesUnknown/Image"+str(noOfFile) + ".jpg", im[y:y+h,x:x+w])
                cv2.putText(im,str(tt),(x,y+h), font, 1,(255,255,255),2)
            cv2.imshow('im',im)
            if (cv2.waitKey(1)==ord('q')):
                break
        ts = time.time()
        date = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d')
        exists = os.path.isfile("Attendance/Attendance_" + date + ".csv")
        if exists:
            df1=pd.read_csv("Attendance/Attendance_" + date + ".csv")
            if Id in df1['ID']:
                print("Attendance Marked")
            else:
                with open("Attendance/Attendance_" + date + ".csv", 'a+') as csvFile1:
                    writer = csv.writer(csvFile1)
                    writer.writerow(attendance)
                csvFile1.close()

        else:
            with open("Attendance\Attendance_" + date + ".csv", 'a+') as csvFile1:
                writer = csv.writer(csvFile1)
                writer.writerow(col_names)
                writer.writerow(attendance)
            csvFile1.close()
        cam.release()
        cv2.destroyAllWindows()
class LoginWindow(Screen):
    namee = ObjectProperty(None)
    rollno = ObjectProperty(None)

    def goback(self):
            sm.current = "create"

    def loginBtn(self):
        a = self.namee.text
        b = self.rollno.text
        TakeImages(b ,a)
        TrainImages()
        getImagesAndLabels('TrainingImage')

class WindowManager(ScreenManager):
    pass

def TakeImages(Id ,name):
    if(int(Id)!=0):
        cam = cv2.VideoCapture(0)
        harcascadePath = "haarcascade_frontalface_default.xml"
        detector=cv2.CascadeClassifier(harcascadePath)
        sampleNum=0
        while(True):
            ret, img = cam.read()
            gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
            faces = detector.detectMultiScale(gray, 1.3, 5)
            for (x,y,w,h) in faces:
                cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
                sampleNum=sampleNum+1
                cv2.imwrite("TrainingImage/ "+name +"."+Id +'.'+ str(sampleNum) + ".jpg", gray[y:y+h,x:x+w])
                cv2.imshow('frame',img)
            if cv2.waitKey(100) & 0xFF == ord('q'):
                break
            elif sampleNum>100:
                break
        cam.release()
        cv2.destroyAllWindows()
        row = [Id , name]
        with open('StudentDetails/StudentDetails.csv','a+') as csvFile:
            writer = csv.writer(csvFile)
            writer.writerow(row)
        csvFile.close()

def TrainImages():
    recognizer = cv2.face_LBPHFaceRecognizer.create()
    harcascadePath = "haarcascade_frontalface_default.xml"
    detector =cv2.CascadeClassifier(harcascadePath)
    faces,Id = getImagesAndLabels("TrainingImage")
    recognizer.train(faces, np.array(Id))
    recognizer.save("TrainingImageLabel/Trainner.yml")

def getImagesAndLabels(path):
    imagePaths=[os.path.join(path,f) for f in os.listdir(path)]

    faces=[]
    Ids=[]
    for imagePath in imagePaths:
        pilImage=Image.open(imagePath).convert('L')
        imageNp=np.array(pilImage,'uint8')
        Id=int(os.path.split(imagePath)[-1].split(".")[1])
        faces.append(imageNp)
        Ids.append(Id)
    return faces,Ids

kv = Builder.load_file("my.kv")

sm = WindowManager()

screens = [CreateAccountWindow(name="create"),LoginWindow(name="login")]
for screen in screens:
    sm.add_widget(screen)

class MyMainApp(App):
    def build(self):
        return sm

if __name__ == "__main__":
    MyMainApp().run()


import random

class Card:

    def __init__(self):
        self.card_items = []
        self.positions = []
        data = random.sample(range(1, 90), 15)
        self.split(data, 3)
        lol = lambda lst, sz: [lst[i:i + sz] for i in range(0, len(lst), sz)]
        for i in range(3):
            self.positions = lol(data, 5)
        for items in self.positions:
            items.sort()
            for i in range(4):
                random_pos = random.randint(1, 9)
                items.insert(random_pos, '#')
            self.card_items.append(items)

    def __str__(self):
        return f"{self.card_items}"

    def show_card(self, name, player_type):
        print(f'------------{name} {player_type}----------------------')
        for row in self.card_items:
            print(row)
        print('----------------------------------------')

    def split(self, arr, size):
        arrs = []
        while len(arr) > size:
            pice = arr[:size]
            arrs.append(pice)
            arr = arr[size:]
        arrs.append(arr)
        return arrs

if __name__ == '__main__':
    test = Card()
    test.show_card('test', 'human')


def decomposite(number):#number=4444
    Asum=0
    Bsum=0
    for i in str(number):
        if i == "4":#4
            zeStr=""
            zero=(len(str(number))-1)-str(number).index(i)#zero=2
            for _ in range(zero):
                zeStr+="0"
            A="1"+zeStr#A=100
            B="1"+zeStr#B=100
            A=2*int(A)#A=200
            B=2*int(B)#B=200
            Asum+=A#Asum=2200
            Bsum+=B#Bsum=2200
        else:          #9
            zeStr=""
            zero=(len(str(number))-1)-str(number).index(i)#zero=2-0
            for _ in range(zero):
                zeStr+="0"
            A="1"+zeStr#A=100
            A=int(i)*int(A) #A=900
            Asum+=A        #Asum=900
    return Asum,Bsum

t=int(input())
for _ in range(t):
    number=int(input())
    A,B=decomposite(number)
    print("{} {}".format(A,B))
'''
Output

3
4
940
4444

Case #1: 2 2
Case #2: 852 88
Case #3: 667 3777'''


#!/usr/bin/env python

'''
HOW TO USE THIS SCRIPT WITH UCSF CHIMERA:
   -To view simulation movies in UCSF Chimera, from the dropdown menu go to
        Tools -> MD/Ensemble Analysis -> MD Movie
   -This will open a pop-up window labeled 'Get Ensemble Info' (as of Chimera 1.9).
   -Make sure the parameters of this window are as follows:
        Trajectory format: PDB
        PDB frames contained in: single file
        File: browse to the .pdb file generated by this script, which
              will be in the same directory that your trajectory.dat is in
        Use frames 'first' through 'last'
   -Once ready hit 'OK', which will bring up a second pop-up window, 'MD Movie: ...'.
   -To apply the Chimera commands file to your movie, from the dropdown menu go to
        Per-Frame -> Define Script
   -This will bring up another window 'Per-Frame Commands'. At the top of this window
   make sure 'Interpret script as ' is set to 'Chimera commands'. Next, in the bottom
   left of this window click 'Insert Text File'. Browse to the .com file generated by
   this script that is paired with the appropriate .pdb file.
   -And finally, select 'Apply' and then 'OK'.
'''

import sys, os
from nb_simdata import *
from nb_visfunctions import *

def main(conffile_name, topfile_name):
    sd = NBSimulationData()
    sd.load_topology_data(topfile_name)

    # chimera commands
    com_list = get_chimera_commands(sd)
    chimera_file = conffile_name + '.com'
    out = open(chimera_file, 'w')
    for command in com_list:
        print >> out, command
    out.close()

    conffile = open(conffile_name, 'r')
    outfile_name = conffile_name + '.pdb'
    outfile = open (outfile_name, 'w')
    conf_num = 0

    # 'stream_config_data' will return true while there are still
    # configurations to read from the file.
    # it also takes care of file closing
    while sd.stream_config_data(conffile, outfile, conf_num):
        pdb_str = get_pdb_str(sd, conf_num)
        outfile.write(pdb_str)
        conf_num += 1

if __name__ == "__main__":
    conffile_name = sys.argv[1]
    topfile_name = sys.argv[2]
    main(conffile_name, topfile_name)


menuList = [["커피",3000], ["햄버거",5400], ["돈까스",4500], ["오므라이스",5000]]
isExist = False

while True:
    print("1.메뉴선택 2.설정 0.종료")
    manage = (int)(input("원하시는 기능을 선택하세요 : "))

    if manage == 1:
        print()
        print(menuList)
        print()
        menu = input("메뉴를 입력하세요 : ")
        count=0

        for i in menuList:
            if i[0]==menu:
                isExist=True
                break
            count+=1

        if isExist==True:
            print("%s는 %d원 입니다." % (menuList[count][0],menuList[count][1]))
            money = (int)(input("금액을 투입하세요 : "))
            if money - menuList[count][1] >= 0:
                print("주문되었습니다. 거스름돈은 %d입니다\n" %(money-menuList[count][1]))
            else:
                print("금액이 부족합니다\n")
        elif isExist==False:
            print("판매하지 않습니다\n")

    elif manage == 2:
        print("1. 메뉴 추가 2. 메뉴 삭제")
        menuMan = (int)(input("번호를 선택하세요 : "))
        if menuMan == 1:
            nameTemp = input("메뉴이름을 입력하세요 : ")
            moneyTemp = (int)(input("가격을 입력하세요 : "))
            menuList.append([nameTemp,moneyTemp])
        elif menuMan ==2:
            count = 0
            delTemp = input("삭제할 음식의 이름을 입력하세요 : ")
            for i in menuList:
                if i[0]==delTemp:
                    break
                count+=1
            menuList.pop(count)

    elif manage == 0:
        break
    else:
        print("다시 입력하세요\n")


from argparse import ArgumentParser
from enum import Enum
import logging

logger = logging.getLogger(__name__)

def fill_from_dict(defaults, a_dict):
    set_values = []
    for arg, val in a_dict.items():
        if val is None:
            continue
        set_values.append(arg)
        parts = arg.split('.')  # set nested objects with names like obj1.attr
        toset = defaults
        for part in parts[:-1]:
            toset = toset.__dict__[part]
        name = parts[-1]
        d = toset.__dict__[name]
        if isinstance(d, Enum):
            toset.__dict__[name] = type(d)[val]
        else:
            toset.__dict__[name] = val
    return set_values

def _nested_get(obj, arg):
    parts = arg.split('.')  # set nested objects with names like obj1.attr
    toget = obj
    for part in parts[:-1]:
        if not hasattr(toget, '__dict__') or part not in toget.__dict__:
            return None
        toget = toget.__dict__[part]
    return toget.__dict__[parts[-1]]

def name_value_list(obj, prefix=''):
    name_values = []
    for attr, value in obj.__dict__.items():
        # ignore members that start with '_'
        if attr.startswith('_'):
            continue
        if hasattr(value, '__dict__'):
            name_values.extend(name_value_list(value, prefix=prefix + attr + '.'))
        else:
            name_values.append((prefix+attr, value))
    return name_values

def fill_from_args(defaults):
    """
    Builds an argument parser, parses the arguments, updates and returns the object 'defaults'
    :param defaults: an object with fields to be filled from command line arguments
    :return:
    """
    parser = ArgumentParser()
    # if defaults has a __required_args__ we set those to be required on the command line
    required_args = []
    names_values = name_value_list(defaults)
    # print(names_values)
    names = set([n for n, v in names_values])
    if hasattr(defaults, '__required_args__'):
        required_args = defaults.__required_args__
        for reqarg in required_args:
            if reqarg.startswith('_'):
                raise ValueError(f'arguments should not start with an underscore ({reqarg})')
            if reqarg not in names:
                raise ValueError(f'argument "{reqarg}" is required, but not present in __init__')
    for attr, value in names_values:
        help_str = None
        # if it is a tuple, we assume the second is the help string
        # if type(value) is tuple and len(value) == 2 and type(value[1]) is str:
        #     help_str = value[1]
        #     value = value[0]

        # check if it is a type we can take on the command line
        if type(value) not in [str, int, float, bool] and not isinstance(value, Enum):
            raise ValueError(f'Error on {attr}: cannot have {type(value)} as argument')
        if type(value) is bool and value:
            raise ValueError(f'Error on {attr}: boolean arguments (flags) must be false by default')

        # also handle str to enum conversion
        t = type(value)
        if isinstance(value, Enum):
            t = str

        # don't pass defaults to argparse, just pass None we'll keep the default value if the arg value is None
        if t is bool:
            # support bool with store_true (required false by default)
            parser.add_argument('--'+attr, default=None, action='store_true', help=help_str)
        else:
            parser.add_argument('--'+attr, type=t, default=None, help=help_str, required=(attr in required_args))
    args = parser.parse_args()
    # now update the passed object with the arguments
    defaults.__passed_args__ = fill_from_dict(defaults, args.__dict__)
    # call _post_argparse() if the method is defined
    try:
        defaults._post_argparse()
    except AttributeError:
        pass
    return defaults


import numpy as np
import random

import matplotlib.pyplot as plt

def save_points_to_file(filename, points):
    with open(filename, "w") as f:
        for point in points:
            f.write(f"{point[0]} {point[1]}\n")

def get_points_from_file(filename):
    with open('points/'+filename) as f:
        points = []
        lines = f.read().splitlines()
        for line in lines:
            x, y = map(float, line.split())
            points.append((x, y))
        return points

def gen_shape(a, b, x0, y0, func, radian_low=0, radian_high=np.pi):
    return [func(t, a, b, x0, y0) for t in np.arange(radian_low, radian_high, np.pi/60)]

def gen_rand_shape(min_p, max_p, func, random_limit=10):
    a = random.randint(-random_limit, random_limit)
    b = random.randint(-random_limit, random_limit)

    x0 = random.randint(-random_limit, random_limit)
    y0 = random.randint(-random_limit, random_limit)

    return [func(t, a, b, x0, y0) for t in np.arange(0, np.pi, 4*np.pi / random.randint(min_p, max_p))]

def line(t, a, b, x0, y0):
    return a*t + x0, b*t + y0

def zigzag_line(t, a, b, x0, y0):
    return a*t + x0, b*t + + random.normalvariate(y0, y0 / 100)

def ellipse(t, a, b, x0, y0):
    return a*np.cos(t) + x0, b*np.sin(t) + y0

def plot_points(points):
    plt.plot(*zip(*points), marker='o', markersize=3, color='r', ls='')
    plt.savefig("output//points_plot.png")

if __name__ == "__main__":
    points = gen_shape(10, 10, 30, 20, ellipse, radian_high=np.pi/3)
    points = points + gen_shape(5, 5, 0, 20, ellipse, radian_low=2*np.pi/3, radian_high=1.2*np.pi)
    points = points + gen_shape(1, -0.1, 5, 5, zigzag_line, radian_high=3*np.pi)
    points = points + gen_shape(1.5, 0.5, 20, 8, zigzag_line, radian_high=3*np.pi)
    points = points + gen_shape(1.5, -0.2, 10, 30, line, radian_high=2*np.pi)

    save_points_to_file("points/line.txt", points)
    plot_points(points)


length = int(input())
arr = []

for _ in range(length):
    arr.append(int(input()))

for i in arr:
    if i >= 1:
        print('You are the future of Tencent!')
    else:
        print('Good luck and Enjoy TPC!')


import time
time = int(time.strftime("%H"))

if (time >= 21 or time < 6) :
    print ("Good Night")

elif (time >= 18 and time < 21) :
    print("Good Evening")

elif (time >= 12 and time < 18) :
    print("Good Afternoon")

else :
    print("Good Morning")

age = int(input("Enter your age : "))

if (age >= 18) :
    print("You can drive!!")

else :
    print("You cannot drive")

budget = int(input("Enter your budget : "))
apple_rate = int(input("Enter apple rate : "))
if (budget/apple_rate >= 0.1) :
    print ("Buy", budget/apple_rate, "kg apple")

else :
    print("I'll buy some peanut")


"""Media URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/3.0/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
from django.urls import path

from excel import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.CreateStationView.as_view(), name='create_station'),
    path('station/', views.StationView.as_view(), name='station'),
    path('package/<int:id_station>/', views.PackageView.as_view(), name='package'),
    path('create_package/', views.CreatePackageView.as_view(), name='create_package'),
    path('period_year/<int:id_station>/', views.PeriodYearView.as_view(), name='period_year'),
    path('create_periodyear/', views.CreatePeriodYearView.as_view(), name='create_periodyear'),
    path('period_month/<int:id_station>/', views.PeriodMonthView.as_view(), name='period_month'),
    path('create_periodmonth/', views.CreatePeriodMonthView.as_view(), name='create_periodmonth'),
    #path('index/<int:id_package>/', views.IndexPackageView.as_view(), name='index'),
    path('create_index/', views.CreateIndexPackageView.as_view(), name='create_index'),
    path('calculate_min/', views.CalculateMin.as_view(), name='cpp_min'),
    path('calculate_max/', views.CalculateMax.as_view(), name='cpp_max'),
    path('calculate/', views.Calculate.as_view(), name='cpp'),
    path('delete_station/<int:station_id>/', views.StationDelete.as_view(), name='delete_station'),
    path('delete_package/<int:package_id>/', views.PackageDelete.as_view(), name='delete_package'),
    path('package/', views.PackageViewAll.as_view(), name='packages_all'),
    path('period_year/', views.YearViewAll.as_view(), name='years_all'),
    path('period_month/', views.MonthViewAll.as_view(), name='months_all'),
    path('indexes/', views.IndexViewAll.as_view(), name='indexes_all'),
    path('delete_year/<int:year_id>/', views.YearDelete.as_view(), name='delete_year'),
    path('delete_index/<int:index_id>/', views.IndexDelete.as_view(), name='delete_index'),
    path('delete_month/<int:month_id>/', views.MonthDelete.as_view(), name='delete_month'),

]


# File:         model_trainer.py
# Date:         2023/07/13
# Description:  ModelTrainer class to train neural networks for Challenge #2

from os import path, makedirs
from typing import Optional
import sys

import numpy as np
from tqdm import tqdm
import torch
from torch.optim.adamw import AdamW
from torch.nn import Module
from torch.utils.data import Dataset, DataLoader, Subset, random_split
from torchvision.ops import nms

sys.path.append("./utils")
from coco_utils import get_coco_api_from_dataset
from coco_eval import CocoEvaluator
from engine import _get_iou_types

sys.path.append("./models")
from fasterrcnn_models import (
    FasterRcnnResnet50FpnV2,
    FasterRcnnMobileNetV3LargeFpn,
    FasterRcnnMobileNetV3Large320Fpn,
)

class ModelTrainer:
    """
    A training worker for neural network models used in challenge #2

    Loads an initial state of a neural network model, trains it using some parameters
    and a given dataset. After each epoch, the model weights and losses (training &
    validation) are exported in a checkpoint file.
    """

    def __init__(
        self,
        model: Module,
        dataset: Dataset,
        dataset_validation: Optional[Dataset],
        epochs_count: int,
        batch_size: int,
        learning_rate: int,
        workers_count: int,
        device: torch.device = torch.device("cpu"),
        load_checkpoint_file: str = "",
        model_name: str = "model",
        checkpoints_dir: str = "checkpoints",
    ) -> None:
        self.__model = model.to(device)
        self.__device = device

        self.__starting_epoch = 0
        self.__epochs_count = epochs_count
        self.__batch_size = batch_size
        self.__workers_count = workers_count

        self.__optimizer = AdamW(model.parameters(), lr=learning_rate)

        self.__epoch = 0
        self.__train_data_loader = None
        self.__validation_data_loader = None

        # Stored globally to keep track of all losses in each checkpoint
        self.__training_losses = []

        self.__model_name = model_name  # Checkpoints will be saved with this name
        self.__checkpoints_dir = path.abspath(checkpoints_dir)
        if not path.exists(self.__checkpoints_dir):
            makedirs(self.__checkpoints_dir)

        # Load training and validation datasets
        self.__dataset = dataset
        self.__dataset_validation = dataset_validation

        # Check if we actually have a validation dataset, otherwise create one
        if self.__dataset_validation is None:
            self.__dataset, self.__dataset_validation = self.__split_dataset(
                dataset, (0.8, 0.2), randomize=True
            )

        # Just before starting, load a checkpoint file if available
        if len(load_checkpoint_file) > 0:
            self.__load_checkpoint(load_checkpoint_file)

    def __split_dataset(
        self,
        dataset: Dataset,
        ratios: list[float],
        randomize: bool = False,
    ) -> list[Subset]:
        """
        Split a unique dataset into multiple subset datasets

        Parameters
        ----------
        dataset : Dataset
            Main dataset to split
        ratios : list[float]
            Ratios (normalized or not) defining the dataset split (variable length)
        randomize : bool, optional
            Split the main dataset randomly, by default False

        Returns
        -------
        list[Subset]
            Split datasets

        Raises
        ------
        ValueError
            Invalid splitting ratios
        """
        if len(ratios) == 0:
            raise ValueError("Ratios cannot be an empty list")
        if any(r < 0 for r in ratios):
            raise ValueError(f"Each ratio must be in ]0 - 1] ; got {ratios}")

        ratios_sum = sum(ratios)
        normalized_ratios = [r / ratios_sum for r in ratios]

        split_datasets = []

        if randomize:
            split_datasets = random_split(dataset, normalized_ratios)
        else:
            split_datasets = []
            start_idx = 0
            for r in normalized_ratios[:-1]:
                num_data = int(len(dataset) * r)  # type: ignore
                split_datasets.append(
                    Subset(dataset, range(start_idx, start_idx + num_data))
                )
                start_idx += num_data

            # Last subset takes the rest, not using last ratio due to possible rounding difference
            last_subset = Subset(dataset, range(start_idx, len(dataset)))
            split_datasets.append(last_subset)

        return split_datasets

    def run(self):
        """
        Main entry point to start training
        """
        # Prepare validation data (batch size should be 1 for inference)
        self.__validation_data_loader = DataLoader(
            self.__dataset_validation,
            batch_size=1,
            num_workers=self.__workers_count,
            collate_fn=collate_fn,
            drop_last=True,
        )

        # Training
        for self.__epoch in range(
            self.__starting_epoch,
            self.__starting_epoch + self.__epochs_count,
        ):
            # Prepare training data, reshuffle for each epoch
            self.__train_data_loader = DataLoader(
                self.__dataset,
                batch_size=self.__batch_size,
                num_workers=self.__workers_count,
                shuffle=True,
                collate_fn=collate_fn,
            )

            training_losses = self.__train()
            self.__validate()

            # Update the history of training & validation losses
            self.__training_losses.append(training_losses)

            # Save the checkpoint (including training & validation losses)
            self.__save_checkpoint()

    def __train(self) -> np.ndarray:
        """
        Train model weights and track performance

        Returns
        -------
        ndarray (batches x 5)
            Losses of each batch during this epoch
            (combined, classification, localization, objectness, region proposal)
        """
        losses = np.zeros((0, 5))

        # Training -> gradient computation, model outputs losses directly
        self.__model.train()

        # Iterate training data with status bar
        tqdm_iterator = tqdm(self.__train_data_loader, desc=f"Epoch {self.__epoch}")
        for _, (images, targets) in enumerate(tqdm_iterator):
            # Assign tensors to target computing device
            images = list(image.to(self.__device) for image in images)
            targets = [{k: v.to(self.__device) for k, v in t.items()} for t in targets]

            # Set gradient to zero to prevent gradient accumulation
            self.__optimizer.zero_grad()

            # Inference prediction by model
            loss_dict = self.__model(images, targets)

            # Obtain loss function and back propagate to obtain gradient
            combined_loss = sum(loss for loss in loss_dict.values())
            combined_loss.backward()

            # Manually track the individual losses (to print epoch summary)
            if (
                isinstance(self.__model, FasterRcnnResnet50FpnV2)
                or isinstance(self.__model, FasterRcnnMobileNetV3LargeFpn)
                or isinstance(self.__model, FasterRcnnMobileNetV3Large320Fpn)
            ):
                loss_classifier = loss_dict["loss_classifier"].item()
                loss_box_reg = loss_dict["loss_box_reg"].item()
                loss_objectness = loss_dict["loss_objectness"].item()
                loss_rpn_box_reg = loss_dict["loss_rpn_box_reg"].item()
            else:
                loss_classifier = loss_dict["classification"].item()
                loss_box_reg = loss_dict["bbox_regression"].item()
                loss_objectness = 0
                loss_rpn_box_reg = 0

            # Check if the losses are NaN, indicating issues with the gradient
            if (
                np.isnan(loss_classifier)
                or np.isnan(loss_box_reg)
                or np.isnan(loss_objectness)
                or np.isnan(loss_rpn_box_reg)
            ):
                raise RuntimeError("NaN loss during training")

            # Update the global losses array
            losses = np.vstack(
                [
                    losses,
                    [
                        combined_loss.item(),
                        loss_classifier,
                        loss_box_reg,
                        loss_objectness,
                        loss_rpn_box_reg,
                    ],
                ]
            )

            # Weight learning
            self.__optimizer.step()

            # Store performance metrics and update loss on status bar
            tqdm_iterator.set_postfix_str(f"Combined Loss: {combined_loss.item():.3e}")

        print(
            f"Epoch {self.__epoch}: Combined loss {np.mean(losses[:, 0]):.4f} ; "
            f"Classification loss {np.mean(losses[:, 1]):.4f} ; "
            f"Localization loss {np.mean(losses[:, 2]):.4f} ; "
            f"Objectness loss {np.mean(losses[:, 3]):.4f} ; "
            f"Region Proposal loss {np.mean(losses[:, 4]):.4f}"
        )

        return losses

    def __validate(self) -> None:
        """
        Validate model weights and track performance (no training)
        """
        # Convert to COCO format for Pytorch vision to compute mean Average Precision (mAP)
        coco = get_coco_api_from_dataset(self.__validation_data_loader.dataset)
        iou_types = _get_iou_types(self.__model)
        coco_evaluator = CocoEvaluator(coco, iou_types)

        # Evaluation mode (the network will output predictions instead of losses)
        self.__model.eval()

        # Turn off gradient to prevent autograd in backward pass, saves memory
        tqdm_iterator = tqdm(
            self.__validation_data_loader, desc=f"Validation {self.__epoch}"
        )
        with torch.no_grad():
            for images, targets in tqdm_iterator:
                # Assign tensors to target computing device
                images = list(image.to(self.__device) for image in images)
                # Targets will only be used for loss computation
                targets = [
                    {k: v.to(self.__device) for k, v in t.items()} for t in targets
                ]

                # Inference prediction by model and obtain predictions (instead of loss)
                outputs = self.__model(images)
                outputs = [{k: v for k, v in t.items()} for t in outputs]

                # Perform Non-Maximum Suppression (NMS) on the bounding boxes
                bboxes_idx_to_keep = nms(
                    boxes=outputs[0]["boxes"],
                    scores=outputs[0]["scores"],
                    iou_threshold=0.3,
                )
                final_outputs = [
                    {k: v[bboxes_idx_to_keep] for k, v in outputs[0].items()}
                ]

                # Compute mean Average Precision (mAP) using COCO evaluator
                res = {
                    target["image_id"].item(): output
                    for target, output in zip(targets, final_outputs)
                }
                coco_evaluator.update(res)

        # Print mean performance for this epoch
        coco_evaluator.synchronize_between_processes()
        coco_evaluator.accumulate()
        coco_evaluator.summarize()

    def __save_checkpoint(self) -> None:
        """
        Save the model weights, optimizer states, training losses and validation losses
        inside a checkpoint file.
        """
        target_checkpoint_path = path.join(
            self.__checkpoints_dir,
            f"{self.__model_name}_epoch-{self.__epoch}.pt",
        )
        torch.save(
            {
                "epoch": self.__epoch,
                "model_state_dict": self.__model.state_dict(),
                "optimizer_state_dict": self.__optimizer.state_dict(),
                "training_losses": self.__training_losses,
            },
            target_checkpoint_path,
        )

    def __load_checkpoint(self, checkpoint_file_path: str) -> None:
        """
        Load a checkpoint file (model weights, optimizer weights, training losses) to
        resume training a network.

        Parameters
        ----------
        checkpoint_file_path : str
            Absolute path to the checkpoint file to load

        Raises
        ------
        RuntimeError
            Invalid or inexistant checkpoint file
        """
        print(f"ModelTrainer: loading checkpoint {checkpoint_file_path}")

        # Make sure the target checkpoint file exists
        if not path.exists(checkpoint_file_path):
            raise RuntimeError(f"Checkpoint {checkpoint_file_path} does not exist.")
        if not path.isfile(checkpoint_file_path):
            raise (f"{checkpoint_file_path} is not a file.")

        checkpoint = torch.load(checkpoint_file_path, map_location=self.__device)
        self.__starting_epoch = checkpoint["epoch"] + 1
        self.__model.load_state_dict(checkpoint["model_state_dict"])
        self.__optimizer.load_state_dict(checkpoint["optimizer_state_dict"])
        self.__training_losses = checkpoint["training_losses"]

def parameters_count(model: Module) -> tuple[int, int]:
    """
    Compute the numbers of parameters in a model

    Parameters
    ----------
    model : Module
        Neural network model

    Returns
    -------
    tuple[int, int]
        Total count of parameters, Trainable parameters count
    """
    return [
        sum(p.numel() for p in model.parameters()),
        sum(p.numel() for p in model.parameters() if p.requires_grad),
    ]

def collate_fn(batch):
    return tuple(zip(*batch))


#股票池设置
market = "text"#预测股票池
benchmark = "SH600000"#回测基准
#模型设置
model = "LGBModel"#训练模型
model_path = "qlib.contrib.model.gbdt"#模型路径
#模型超参数设置，根据模型设置的不同，设置不同模型的超参数
model_kwargs = {
            "loss": "mse",
            "colsample_bytree": 0.8879,
            "learning_rate": 0.0421,
            "subsample": 0.8789,
            "lambda_l1": 205.6999,
            "lambda_l2": 580.9768,
            "max_depth": 8,
            "num_leaves": 210,
            "num_threads": 20,
        }
#因子库设置
factor = "Alpha158"
factor_path = "qlib.contrib.data.handler"#因子库位置
#训练时间设置
train_segments = {
                "train": ("2020-01-01", "2020-05-31"),
                "valid": ("2020-06-01", "2020-06-30"),
                "test": ("2020-07-01", "2020-09-30"),
            }
#数据处理基本设置
data_handler_config = {
    "start_time": "2020-01-01",
    "end_time": "2020-09-30",
    "fit_start_time": "2020-01-01",
    "fit_end_time": "2020-05-31",
    "instruments": market,
    #利用内部预处理方法设置因子，数据预处理，Alpha158
    "infer_processors":{
        "class":"FilterCol",#从内置因子库中挑选因子
        "kwargs":{
            "fields_group":"feature",
            "col_list":["RESI5", "WVMA5", "RSQR5", "KLEN", "RSQR10", "CORR5", "CORD5", "CORR10",
                            "ROC60", "RESI10", "VSTD5", "RSQR60", "CORR60", "WVMA60", "STD5",
                            "RSQR20", "CORD60", "CORD10", "CORR20", "KLOW"
                        ]
                        },
        "class": "RobustZScoreNorm",#标准化方式
        "kwargs":{
            "fields_group":"feature",
            "clip_outlier":"true"
                        },
        "class": "Fillna",#缺失值处理方法
        "kwargs":{
            "fields_group":"feature",
                        },
    },
    #自定义因子
    "data_loader":{
        "class": "QlibDataLoader",
        "kwargs":{
            "config":{
                "feature":{#利用基础量价数据计算因子
                    ["Resi($close, 15)/$close", "Std(Abs($close/Ref($close, 1)-1)*$volume, 5)/(Mean(Abs($close/Ref($close, 1)-1)*$volume, 5)+1e-12)", "Rsquare($close, 5)", "($high-$low)/$open", "Rsquare($close, 10)", "Corr($close, Log($volume+1), 5)", "Corr($close/Ref($close,1), Log($volume/Ref($volume, 1)+1), 5)", "Corr($close, Log($volume+1), 10)", "Rsquare($close, 20)", "Corr($close/Ref($close,1), Log($volume/Ref($volume, 1)+1), 60)", "Corr($close/Ref($close,1), Log($volume/Ref($volume, 1)+1), 10)", "Corr($close, Log($volume+1), 20)", "(Less($open, $close)-$low)/$open"]
                    ["RESI5", "WVMA5", "RSQR5", "KLEN", "RSQR10", "CORR5", "CORD5", "CORR10", "RSQR20", "CORD60", "CORD10", "CORR20", "KLOW"]
                },
                "label":{["Ref($close, -2)/Ref($close, -1) - 1"]#自定义标签
                    ["LABEL0"]},
                "freq":"day",
            },

        },
    },
    'label':['Ref($open, -2) / Ref($open, -1) - 1']#利用内置因子库时设置标签
}
#回测参数
topk = 10#选股范围
n_drop = 3#筛选替换个数
backtest_start_time = "2020-07-01"#回测开始时间
backtest_end_time = "2020-09-30"#回测结束时间

#导入包
import qlib
import pandas as pd
from qlib.config import REG_CN
from qlib.utils import exists_qlib_data, init_instance_by_config
from qlib.workflow import R
from qlib.workflow.record_temp import SignalRecord, PortAnaRecord
from qlib.utils import flatten_dict
provider_uri = "~/.qlib/qlib_data/cn_data"  # target_dir
if not exists_qlib_data(provider_uri):
    print(f"Qlib data is not found in {provider_uri}")
    sys.path.append(str(scripts_dir))
    from get_data import GetData
    GetData().qlib_data(target_dir=provider_uri, region=REG_CN)
qlib.init(provider_uri=provider_uri, region=REG_CN)
#任务配置
task = {
    "model": {
        "class": model,
        "module_path": model_path,
        "kwargs": model_kwargs,
    },
    "dataset": {
        "class": "DatasetH",
        "module_path": "qlib.data.dataset",
        "kwargs": {
            "handler": {
                "class": factor,
                "module_path": factor_path,
                "kwargs": data_handler_config,
            },
            "segments": train_segments,
        },
    },
}
# model initiaiton
model = init_instance_by_config(task["model"])
dataset = init_instance_by_config(task["dataset"])

# start exp to train model
with R.start(experiment_name="train_model"):
    R.log_params(**flatten_dict(task))
    model.fit(dataset)
    R.save_objects(trained_model=model)
    rid = R.get_recorder().id

# prediction, backtest & analysis
port_analysis_config = {
    "executor": {
        "class": "SimulatorExecutor",
        "module_path": "qlib.backtest.executor",
        "kwargs": {
            "time_per_step": "day",
            "generate_portfolio_metrics": True,
        },
    },
    "strategy": {
        "class": "TopkDropoutStrategy",
        "module_path": "qlib.contrib.strategy.signal_strategy",
        "kwargs": {
            "model": model,
            "dataset": dataset,
            "topk": topk,
            "n_drop": n_drop,
        },
    },
    "backtest": {
        "start_time":backtest_start_time,
        "end_time": backtest_end_time,
        "account": 100000000,
        "benchmark": benchmark,
        #"verbose":True,
        "exchange_kwargs": {
            "freq": "day",
            "limit_threshold": 0.095,
            "deal_price": "close",
            "open_cost": 0.0005,
            "close_cost": 0.0015,
            "min_cost": 5,
        },
    },
}
# backtest and analysis
with R.start(experiment_name="backtest_analysis"):
    recorder = R.get_recorder(recorder_id=rid, experiment_name="train_model")
    model = recorder.load_object("trained_model")
    # prediction
    recorder = R.get_recorder() #记录类 记录了训练的时间 id
    ba_rid = recorder.id #获取记录id
    sr = SignalRecord(model, dataset, recorder)
    sr.generate()#生成交易方向
    # backtest & analysis
    par = PortAnaRecord(recorder, port_analysis_config, "day")
    par.generate()


# for i in range(1,11):
#     print(f"abu bakar  ::  {i}")

#  sum 1-21 numbers

# total=0
# for i in range(1,21):
#     total +=i

# print(total)

# number=input("enter more than one numbers")
# # number=int(number)
# total=0
# for i in range(0 , len(number)+ 1):
#     total+=i
# print(total)

# ask username input and show index and numbers
name=input("enter your name")
temp=""
for i in range(0 , len(name)+1):
    if name[i] not in temp:
        print(f"{name[i]}  :  {name.count(name[i])}")
    temp+=name[i]


from main.models import Entry
from main import db

def init():
    entry1 = Entry(jcode = '0001', temp = '36.1')
    db.session.add(entry1)
    db.session.commit()
    entry2 = Entry(jcode = '0002', temp = '35.8')
    db.session.add(entry2)
    db.session.commit()
    entries = Entry.query.all()
    entries


#####
# Clean and split the corpus of Twitter tweet text that I'l use to train the word2vec model
#####

import os
import pickle
import string
import re
from nltk import bigrams

# Clean the text
# Lowercase, remove punctuation, unicode, and links
def clean_tweet(tweet):
    printable = set(string.printable)
    punctuation = set(string.punctuation)
    tweet = filter(lambda x: x not in punctuation, tweet)
    tweet = filter(lambda x: x in printable, tweet)
    tweet = re.sub(r'http\S+', '', tweet)
    return tweet.lower()

def get_bigrams_from_tweet(tweet):
    # Return a list of bigram tuples
    tweet_split = tweet.split()
    return list(bigrams(tweet_split))

# Load the pickled list of Tweet text
# Tweets are from the US and Canada and are written in English
with open('bigram_twitter_corpus.pickle') as f:
        tweets_list = pickle.load(f)

# Clean the tweets
cleaned_tweets = [clean_tweet(tweet[0]) for tweet in tweets_list]
print('Finished cleaning the tweets')

# Dump each word into a .txt file, each line on a unique line
f = open('bigram_corpusfile.txt', 'w')
for tweet in cleaned_tweets:
    for word in tweet.split():
        f.write(word)
        f.write(' ')
    f.write('\n')

    tweet_bigrams = get_bigrams_from_tweet(tweet)
    for bigram in tweet_bigrams:
        f.write(' '.join(bigram))
        f.write('\n')

f.close()


import os
import discord
import time
import logging
import json
import threading
import requests
from discord.ext import commands

try: from pystyle import Colors, Colorate
except (ModuleNotFoundError): os.system("pip install pystyle"); from pystyle import Colors, Colorate

logging.basicConfig(
    level=logging.INFO,
    format="\033[38;5;21m[\033[0m%(asctime)s.%(msecs)03d\033[38;5;21m] \033[0m%(message)s\033[0m",
    datefmt="%H:%M:%S"
)

class ready(commands.Cog):

    def __init__(self, client):
        self.client = client
        self.clear = lambda: os.system("cls; clear")
        self.delay = 1
        self.version = 0.4

    async def menu(self):
        os.system("cls & mode 100, 25 & title Rex Nuker V4")
        try: await self.client.change_presence(status=discord.Status.invisible)
        except Exception: pass
        print(Colorate.Horizontal(Colors.blue_to_cyan, menu, 1))
        print()
        logging.info("Welcome to Rex V4! - Krypton")
        logging.info("Client loaded as {}".format(self.client.user))

    @commands.Cog.listener()
    async def on_connect(self):
        self.clear()
        await self.menu()

    @commands.Cog.listener()
    async def on_command_error(self, ctx, error):
        try: await ctx.message.delete()
        except: pass
        logging.error(error)

file = open("settings.json", encoding="utf8")
json = json.load(file)
prefix = json["Nuke Settings"]["Prefix"]

menu = f"""
                            ▄▄▄  ▄▄▄ .▐▄• ▄      ▐ ▄ ▄• ▄▌▄ •▄ ▄▄▄ .▄▄▄
                            ▀▄ █·▀▄.▀· █▌█▌▪    •█▌▐██▪██▌█▌▄▌▪▀▄.▀·▀▄ █·
                            ▐▀▀▄ ▐▀▀▪▄ ·██·     ▐█▐▐▌█▌▐█▌▐▀▀▄·▐▀▀▪▄▐▀▀▄
                            ▐█•█▌▐█▄▄▌▪▐█·█▌    ██▐█▌▐█▄█▌▐█.█▌▐█▄▄▌▐█•█▌
                            .▀  ▀ ▀▀▀ •▀▀ ▀▀    ▀▀ █▪ ▀▀▀ ·▀  ▀ ▀▀▀ .▀  ▀
           ──────────────────────────────────────────────────────────────────────────────
                ────────────────────────────────────────────────────────────────────
                                         * Nuke Commands *
                   +────────────────────────────────────────────────────────────+
                   | {prefix}nuke - Destroys Server     | {prefix}prune - Prune Members       |
                   | {prefix}massban - Bans All Members | {prefix}lag - Audit Hangs Server    |
                   | {prefix}cc - Creates Channels      | {prefix}spam - Spams Messages       |
                   | {prefix}rc - Creates Roles         | {prefix}testban - Tests Mass Ban    |
                   +────────────────────────────────────────────────────────────+
-
│ Created By Krypton
| Version: 4.1
-
"""

def setup(client):
    client.add_cog(ready(client))


import pytest
from src.repository.abc import MongoDbRepository
from src.unit_of_work import MongoDBUnitOfWork
from tests.conftest import session_mock, mock_settings, mock_request
from tests.integration.test_mongo import insert_users

@pytest.fixture
async def uow_object(session_mock, mock_request):
    return MongoDBUnitOfWork(mock_request, session_mock)

@pytest.fixture
async def uow_factory(uow_object):
    async with uow_object(MongoDbRepository) as uow_session:
        yield uow_session

async def test_uow(uow_factory, session_mock):
    await insert_users(session_mock)
    count = await uow_factory.client.test.users.count_documents(
        {}, session=uow_factory.session
    )
    assert 3 == count

async def test_uow_back_committed_work_by_default(session_mock, uow_object):
    async with uow_object(MongoDbRepository) as uow_session:
        await insert_users(session_mock)
        await uow_session.commit()
    count = await uow_object.client.test.users.count_documents({})
    assert 3 == count

async def test_uow_back_uncommitted_work_by_default(session_mock, uow_object):
    async with uow_object(MongoDbRepository):
        await insert_users(session_mock)

    count = await uow_object.client.test.users.count_documents({})
    assert 0 == count

async def test_uow_rolls_back_on_error(session_mock, uow_object):
    class MyException(Exception):
        pass

    with pytest.raises(MyException):
        async with uow_object(MongoDbRepository):
            await insert_users(session_mock)
            raise MyException()

    count = await uow_object.client.test.users.count_documents({})
    assert 0 == count


# inventory.py
stuff = {"rope": 1, "torch": 6, "gold coin": 42, "dagger": 1, "arrow": 12}

def displayInventory(inventory):
    print("Inventory:")
    item_total = 0
    for name, amount in inventory.items():
        print(str(amount) + " " + name)
        item_total += amount
    print("Total number of items: " + str(item_total))

displayInventory(stuff)


def statement_if():
    s = 1
    k = 0
    if s == 1:
        k = 1
    elif s == 2:
        k = 2
    else:
        k = 3

    assert k == 1

def statement_for():
    """for/in/break/continue/else"""
    lst = [-1, 0, 1, 2, 3, 4, 25, 37]
    k = 0
    p = 0
    for i in lst:
        if i > 10:
            break
        if i < 0:
            continue
            k += i
    else:  # execute this part if no break happened
        p = 1
    assert k == 10
    assert p == 0

if __name__ == '__main__':
    statement_if()


import classd
from flask import Flask, render_template, request, Response, redirect, session  #21-05-31 response, redirect 추가, 21-06-09 session 추가
from a import money_pung, logincheck #21-05-31 logincheck 추가
app = Flask(__name__)

# 로그인 처리(세션 비밀키 값, 세션에 필요)
app.secret_key = b'aaa!111/'

#   서버를 의미.
#   php와 같이 주소/에시.php 처럼 구분을 위한 페이지이름을 의미.
@app.route('/')
def hello():
    # 응답 및 첫페이지
    return render_template("main.html")

# 로그아웃(session 제거)
@app.route('/logout')
def logout():
    session.pop('email', None) #세션 아웃시 pop으로 세션을 제거해줘야 함.
    return redirect('/') #메인으로 돌려보냄.

@app.route('/money')
def money():
    #로그인된 사용자들만 돈뻥 페이지가 보이게
    #세션 체크
    if 'email' in session:
        return render_template("money.html")
    else:
        return redirect('/login')

@app.route('/signup')
def su():
    return render_template("signup.html")

@app.route('/login')
def lg():
    return render_template("login.html")

# 회원가입 페이지
@app.route('/signup', methods=['GET', 'POST'])
def signup():
    if request.method == 'GET':
        return render_template("signup.html")
    else:
        email = request.form['email']
        pswd = request.form['pswd']
        username = request.form['username']
        # 위 데이터를 데이터베이스에 저장해서 로그인할때
        # 사용해야하는데....
        classd.insert_member(email, pswd, username)
        #데이터베이스에 데이터가 들어간후 메인 페이지로 넘어감.
        return redirect('/')
        #return "{}
{}
{}
 회원 정보".format(email, pswd, username)
        #결과값은 페이지이후에 적은 이메일 패스워드 이름 회원 정보 라고 출력이 된다. 이부분을 나중에 SQL연동해서 사용.

# 로그인 페이지
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template("login.html")
    else:
        email = request.form['email']
        pswd = request.form['pswd']
        #a.py에서 logincheck를 불러서 사용함.
        #msg는 메시지를 의미함
        #msg = logincheck(email,pswd)

        #classd에서 email과 pswd를 불러옴.
        ret = classd.select_member(email, pswd)
        if ret != None:
            session['email'] = email
            return redirect('/')
        else:
            return redirect('/login')
        # return "{}
{}
{}".format(email, pswd, msg) #{}순서대로 email, pswd, msg가 출력된다.
        # 가입과 마찬가지로 페이지 이후 적은 이메일 패스워드 로그인처리 라고 출력이 된다.

@app.route('/show', methods=['GET', 'POST'])
def show():
    if request.method == 'GET':
        return "Get 으로 들어온 페이지"
    else:
    # form으로 전달된 데이터를 받아서 뻥튀기
        money = request.form['money']
        #money 의 값이 문자열이기 때문에 숫자로 변경
        print("전달된 값은 : ", int (money)*2)
        #돈을 이제 출력해줌.
    im = money_pung(int(money)) #뻥튀기 함수 사용
    return render_template("show.html", money=im)
        #return "당신의 능력을 보여줘~ 얍
{}원 드립니다.".format(money_pung(int money))

@app.route('/showmoney')
def sm():
    #여러줄의 코드를 쓰고싶으면 따옴표(')을 3개 찍어서 작성해준다.
    #render_template 사용시 1번째줄에 import ~~ 뒤에 render_template을 꼭 작성하여 주어야한다.
    return render_template("showmoney.html")

if __name__ == '__main__':
    app.run()


# 76. Minimum Window with - Target Characters - sliding window O(n)
class Solution:
    def minWindow(self, s, t):
        targetCharToFreq = self.buildCharToFreq(t)
        sourceCharToFreq = {}
        n = len(targetCharToFreq)
        matched = 0

        window = ""
        minLen = sys.maxsize
        l = 0
        for r in range(len(s)):
            sourceCharToFreq[s[r]] = sourceCharToFreq.get(s[r], 0) + 1
            if s[r] in targetCharToFreq and sourceCharToFreq[s[r]] == targetCharToFreq[s[r]]:
                    matched += 1

            while matched == n:
                windowLen = r - l + 1
                if windowLen < minLen:
                    minLen = windowLen
                    window = s[l: r + 1]

                sourceCharToFreq[s[l]] -= 1
                if s[l] in targetCharToFreq and sourceCharToFreq[s[l]] < targetCharToFreq[s[l]]:
                    matched -= 1

                l += 1

        return window

    def buildCharToFreq(self, s):
        targetCharToFreq = {}
        for c in s:
            targetCharToFreq[c] = targetCharToFreq.get(c, 0) + 1

        return targetCharToFreq

01-Array/05-subarray/76. Minimum Window with Target Characters.py


# Import libraries
import random
import json
import pickle
import numpy as np
import tensorflow as tf
import nltk
from nltk.stem import WordNetLemmatizer

# Initialize WordNetLemmatizer for word lemmatization
lemmatizer = WordNetLemmatizer()

# Load intents from JSON file
with open('intents.json', 'r') as file:
    intents = json.load(file)

# Lists to store words, classes, and documents
words = []
classes = []
documents = []
ignoreLetters = ['?', '!', '.', ',']

# Preprocess the intents and patterns
for intent in intents['intents']:
    for pattern in intent['patterns']:
        # Tokenize the pattern into a list of words
        wordList = nltk.word_tokenize(pattern)
        words.extend(wordList)
        # Store the document as a tuple of word list and intent tag
        documents.append((wordList, intent['tag']))
        # Add the intent tag to classes if it's not already present
        if intent['tag'] not in classes:
            classes.append(intent['tag'])

# Normalize words by lemmatization and remove duplicates
words = {lemmatizer.lemmatize(word.lower())
         for word in words if word not in ignoreLetters}

classes = sorted(set(classes))

# Save words and classes to pickle files for later use
pickle.dump(list(words), open('words.pkl', 'wb'))
pickle.dump(classes, open('classes.pkl', 'wb'))

# Prepare training data in a format suitable for training a neural network
training = []
outputEmpty = [0] * len(classes)

for document in documents:
    bag = []
    wordPatterns = document[0]
    wordPatterns = [lemmatizer.lemmatize(
        word.lower()) for word in wordPatterns]
    for word in words:
        bag.append(1) if word in wordPatterns else bag.append(0)

    outputRow = list(outputEmpty)
    outputRow[classes.index(document[1])] = 1
    training.append(bag + outputRow)

# Shuffle the training data to ensure randomization
random.shuffle(training)
training = np.array(training)

# Split training data into input features (trainX) and output labels (trainY)
trainX = training[:, :len(words)]
trainY = training[:, len(words):]

# Create a sequential neural network model using Keras
model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(
    128, input_shape=(len(trainX[0]),), activation='relu'))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.Dense(64, activation='relu'))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.Dense(len(trainY[0]), activation='softmax'))

# Configure the optimizer and compile the model
sgd = tf.keras.optimizers.SGD(learning_rate=0.01, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy',
              optimizer=sgd, metrics=['accuracy'])

# Train the model on the prepared data
model.fit(trainX, trainY, epochs=200, batch_size=5, verbose=1)

# Save the trained model for later use
model.save('sudeep_model.keras')

# Training complete
print('Done Training')


from setuptools import setup
from torch.utils.cpp_extension import BuildExtension, CUDAExtension
from os.path import join

project_root = 'GPUEPM'
sources = [join(project_root, file) for file in [
    "essential_matrix.cu",
    "epm_wrapper.cpp"
]]

setup(
    name='GPUEPM',
    ext_modules=[
        CUDAExtension('GPUEPM',
            sources), # extra_compile_args, extra_link_args
        ],
    cmdclass={
        'build_ext': BuildExtension
    }
)


from django.urls import path
from . import views
from cart.contexts import cart_contents  # accessed via ajax

urlpatterns = [
    path('', views.all_products, name='products'),
    path('<int:product_id>', views.product_details, name='product_details'),
    path('delete_from_cart/<item_id>/', views.delete_from_cart,
         name='delete_from_cart'),
    path('cart_contents/', cart_contents, name='cart_contents'),
    path('add/', views.add_product, name='add_product'),
    path('edit/<int:product_id>/', views.edit_product, name='edit_product'),
    path('delete/<int:product_id>/', views.delete_product,
         name='delete_product'),
    path('add_review/<int:product_id>/', views.add_review, name='add_review'),
    path('update_review/<int:review_id>/<int:rating_id>/', views.update_review,
         name='update_review'),
    path('delete_review/<int:review_id>/', views.delete_review,
         name='delete_review'),
    path('add_tracks/', views.add_tracks, name='add_tracks'),
    path('delete_track/<int:track_id>/', views.delete_track,
         name='delete_track'),
]


import numpy as np
import scipy.special as ss
import matplotlib.pyplot as plt
import neupy as ne
import pickle

class neuralNetwork:

    #TODO : add one more layer + dropout
    def __init__(self, inputnodes, hiddennodes, hiddennodes2, outputnodes, learningrate, epochs):
        self.inodes = inputnodes
        self.hnodes = hiddennodes
        self.hnodes2 = hiddennodes2
        self.onodes = outputnodes
        self.lr = learningrate
        self.epochs = epochs
        self.wih = np.random.normal(0.0, pow(self.hnodes, -0.5), (self.hnodes, self.inodes))
        self.whh2 = np.random.normal(0.0, pow(self.hnodes2, -0.5), (self.hnodes2, self.hnodes))
        self.wh2o = np.random.normal(0.0, pow(self.onodes, -0.5), (self.onodes, self.hnodes2))
        self.activation_function = lambda x: ss.expit(x)
        pass

    def train(self, inputs_list, targets_list):
        inputs = np.array(inputs_list, ndmin=2).T
        targets = np.array(targets_list, ndmin=2).T

        hidden_inputs = np.dot(self.wih, inputs)
        hidden_outputs = self.activation_function(hidden_inputs)

        hidden2_inputs = np.dot(self.whh2, hidden_outputs)
        hidden2_outputs = self.activation_function(hidden2_inputs)

        final_inputs = np.dot(self.wh2o, hidden2_outputs)
        final_outputs = self.activation_function(final_inputs)

        output_errors = targets - final_outputs
        # output_errors = self.cross_entropy(final_outputs, targets)
        hidden2_errors = np.dot(self.wh2o.T, output_errors)
        hidden_errors = np.dot(self.whh2.T,hidden2_errors)
        # input_errors = np.dot(self.wih,hidden_errors)

        self.wh2o += self.lr * np.dot((output_errors * final_outputs * (1.0 - final_outputs)), np.transpose(hidden2_outputs))
        self.whh2 += self.lr * np.dot((hidden2_errors * hidden2_outputs * (1.0 - hidden2_outputs)), np.transpose(hidden_outputs))
        self.wih += self.lr * np.dot((hidden_errors * hidden_outputs * (1.0 - hidden_outputs)), np.transpose(inputs))
        pass

    def query(self, input_list):
        inputs = np.array(input_list, ndmin = 2).T

        hidden_inputs = np.dot(self.wih,inputs)
        hidden_outputs = self.activation_function(hidden_inputs)

        hidden2_inputs = np.dot(self.whh2,hidden_outputs)
        hidden2_outputs = self.activation_function(hidden2_inputs)

        final_inputs = np.dot(self.wh2o, hidden2_outputs)
        final_outputs = self.activation_function(final_inputs)
        # final_outputs = self.softmax(final_inputs)

        return final_outputs

    def deserialize(self,path):
        f = open(path, 'rb')
        weights = pickle.load(f)
        self.wih = weights[0]
        self.whh2 = weights[1]
        self.wh2o = weights[2]
        f.close()

    def train_mnist(self,path):
        file = load(path)
        for e in range(self.epochs):
                for record in file:
                    all_values = record.split(',')
                    inputs = (np.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01
                    targets = np.zeros(self.onodes) + 0.01
                    targets[int(all_values[0])] = 0.99
                    self.train(inputs,targets)

    def test_mnist(self, path):
        file2 = load(path)
        for record in file2:
            all_values = record.split(',')
            correct_label = int(all_values[0])
            # print(correct_label, "correct answer")
            inputs = (np.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01
            outputs = n.query(inputs)
            label = np.argmax(outputs)
            # print(label, "network's answer")
            if( label == correct_label):
                scorecard.append(1)
            else:
                scorecard.append(0)

        scorecard_array = np.asarray(scorecard)
        print ("performance = ", scorecard_array.sum() /  scorecard_array.size)

    def softmax(self,x):
        return np.exp(x) / np.sum(np.exp(x), axis=0)

    def cross_entropy(self,predictions, targets, epsilon=1e-12):
        predictions = np.clip(predictions, epsilon, 1. - epsilon)
        N = predictions.shape[0]
        ce = -np.sum(targets*np.log(predictions+1e-9))/N
        return ce

def load(path):
    data_file = open(path, "r")
    data_list = data_file.readlines()
    data_file.close()
    return data_list

if __name__ == "__main__":
    # file = load("bigger/mnist_train.csv")
    # file2 = load("bigger/mnist_test.csv")

    input_nodes = 784
    hidden_nodes = 150
    hidden_nodes2 = 150
    output_nodes = 10
    learning_rate = 0.1
    scorecard = []
    epochs = 1

    n = neuralNetwork(input_nodes,hidden_nodes,hidden_nodes2,output_nodes,learning_rate,epochs)

    # train
    # for e in range(epochs):
    #     for record in file:
    #         all_values = record.split(',')
    #         inputs = (np.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01
    #         targets = np.zeros(output_nodes) + 0.01
    #         targets[int(all_values[0])] = 0.99
    #         n.train(inputs,targets)

    n.train_mnist("bigger/mnist_train.csv")

    n.serialize()

    # n.deserialize()

    n.test_mnist("bigger/mnist_test.csv")

    # print(file[0].split(',')[0])
    # print(n.query(np.asfarray(file[0].split(',')[1:])))

    #query
    # for record in file2:
    #     all_values = record.split(',')
    #     correct_label = int(all_values[0])
    #     print(correct_label, "correct answer")
    #     inputs = (np.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01
    #     outputs = n.query(inputs)
    #     label = np.argmax(outputs)
    #     # print(label, "network's answer")
    #     if( label == correct_label):
    #         scorecard.append(1)
    #     else:
    #         scorecard.append(0)

    # scorecard_array = np.asarray(scorecard)
    # print ("performance = ", scorecard_array.sum() /  scorecard_array.size)


from django.db.models import Q #allows for searches in multiple fields.
from xml.etree.ElementTree import Comment
from django.shortcuts import redirect, render, get_object_or_404

from .models import Post,Category
from .forms import CommentForm

# Create your views here.
def detail(request, category_slug, slug):
    post = get_object_or_404(Post, slug=slug, status=Post.ACTIVE)

    # to verify the input of the comment and save it only if it's valid
    if request.method == 'POST':  #checks if it's a post request which means data has been sent
        form= CommentForm(request.POST) #request.Post gets the data from the post command and sends it to the (comment object)form
        if form.is_valid():
            comment = form.save(commit=False)  # the comment form cannot save without pionting to the foreignkey which is the post(else crash), hence we save the form in a comment object
            comment.post=post  #get the post that is related to the comment and assign it to the foreignkey,else it will throw an error as the [post] attribute is a foreign key and must be known to properly link the comment
            comment.save()  #now save the comment object as all the fields are complete

            return redirect('post_detail',slug=slug)
    else:
        form = CommentForm()

    form = CommentForm()
    return render(request, 'blog/detail.html', {'post':post, 'form':form})

def category(request, slug):
    category = get_object_or_404(Category, slug=slug,)
    posts = category.posts.filter(status=Post.ACTIVE)

    return render(request, 'blog/category.html', {'category':category, 'posts':posts})

def search(request):
    query = request.GET.get('query','') #used to get parameters of the search feature
    posts = Post.objects.filter(status=Post.ACTIVE).filter(Q(title__icontains=query) | Q(intro__icontains= query) | Q(body__icontains= query)) #the icontains, negates the lowercase searching

    return render(request, 'blog/search.html', {'posts': posts, 'query':query})


from typing import List, Tuple

from bip_utils.bech32.bech32 import Bech32Const, Bech32Encodings, Bech32Utils
from bip_utils.bech32.bech32_base import Bech32BaseUtils, Bech32DecoderBase, Bech32EncoderBase
from bip_utils.utils.misc import BytesUtils

class SegwitBech32Const:
    """Class container for Segwit Bech32 constants."""

    # Separator
    SEPARATOR: str = Bech32Const.SEPARATOR
    # Checksum length
    CHECKSUM_STR_LEN: int = Bech32Const.CHECKSUM_STR_LEN
    # Minimum witness program length in bytes
    WITNESS_PROG_MIN_BYTE_LEN: int = 2
    # Maximum witness program length in bytes
    WITNESS_PROG_MAX_BYTE_LEN: int = 40
    # Witness version for Bech32 encoding
    WITNESS_VER_BECH32: int = 0
    # Witness version maximum value
    WITNESS_VER_MAX_VAL: int = 16
    # Accepted data lengths when witness version is zero
    WITNESS_VER_ZERO_DATA_BYTE_LEN: Tuple[int, int] = (20, 32)

class SegwitBech32Encoder(Bech32EncoderBase):
    """
    Segwit Bech32 encoder class.
    It provides methods for encoding to Segwit Bech32 format.
    """

    @classmethod
    def Encode(cls,
               hrp: str,
               wit_ver: int,
               wit_prog: bytes) -> str:
        """
        Encode to Segwit Bech32.

        Args:
            hrp (str)       : HRP
            wit_ver (int)   : Witness version
            wit_prog (bytes): Witness program

        Returns:
            str: Encoded address

        Raises:
            ValueError: If the data is not valid
        """
        return cls._EncodeBech32(hrp,
                                 [wit_ver] + Bech32BaseUtils.ConvertToBase32(wit_prog),
                                 SegwitBech32Const.SEPARATOR)

    @staticmethod
    def _ComputeChecksum(hrp: str,
                         data: List[int]) -> List[int]:
        """
        Compute the checksum from the specified HRP and data.

        Args:
            hrp (str)       : HRP
            data (list[int]): Data part

        Returns:
            list[int]: Computed checksum
        """
        encoding = (Bech32Encodings.BECH32
                    if data[0] == SegwitBech32Const.WITNESS_VER_BECH32
                    else Bech32Encodings.BECH32M)

        return Bech32Utils.ComputeChecksum(hrp, data, encoding)

class SegwitBech32Decoder(Bech32DecoderBase):
    """
    Segwit Bech32 decoder class.
    It provides methods for decoding Segwit Bech32 format.
    """

    @classmethod
    def Decode(cls,
               hrp: str,
               addr: str) -> Tuple[int, bytes]:
        """
        Decode from Segwit Bech32.

        Args:
            hrp (str) : Human readable part
            addr (str): Address

        Returns:
            tuple[int, bytes]: Witness version (index 0) and witness program (index 1)

        Raises:
            Bech32ChecksumError: If the checksum is not valid
            ValueError: If the bech32 string is not valid
        """

        # Decode string
        hrp_got, data = cls._DecodeBech32(addr,
                                          SegwitBech32Const.SEPARATOR,
                                          SegwitBech32Const.CHECKSUM_STR_LEN)
        # Check HRP
        if hrp != hrp_got:
            raise ValueError(
                f"Invalid format (HRP not valid, expected {hrp}, got {hrp_got})"
            )

        # Convert back from base32 (remove witness version)
        conv_data = Bech32BaseUtils.ConvertFromBase32(data[1:])

        # Check data length
        if (len(conv_data) < SegwitBech32Const.WITNESS_PROG_MIN_BYTE_LEN
                or len(conv_data) > SegwitBech32Const.WITNESS_PROG_MAX_BYTE_LEN):
            raise ValueError(f"Invalid format (witness program length not valid: {len(conv_data)})")
        # Check witness version
        wit_ver = data[0]
        if wit_ver > SegwitBech32Const.WITNESS_VER_MAX_VAL:
            raise ValueError(f"Invalid format (witness version not valid: {wit_ver})")
        if wit_ver == 0 and not len(conv_data) in SegwitBech32Const.WITNESS_VER_ZERO_DATA_BYTE_LEN:
            raise ValueError(f"Invalid format (length not valid: {len(conv_data)})")

        return wit_ver, BytesUtils.FromList(conv_data)

    @staticmethod
    def _VerifyChecksum(hrp: str,
                        data: List[int]) -> bool:
        """
        Verify the checksum from the specified HRP and converted data characters.

        Args:
            hrp  (str)      : HRP
            data (list[int]): Data part

        Returns:
            bool: True if valid, false otherwise
        """
        encoding = (Bech32Encodings.BECH32
                    if data[0] == SegwitBech32Const.WITNESS_VER_BECH32
                    else Bech32Encodings.BECH32M)

        return Bech32Utils.VerifyChecksum(hrp, data, encoding)


from copy import deepcopy
from datetime import datetime, timedelta, timezone

import ciso8601
import pytz
from flask import url_for
from invenio_accounts.testutils import login_user_via_session
from invenio_circulation.api import get_loan_for_item
from invenio_circulation.search.api import LoansSearch
from utils import check_timezone_date, flush_index, get_json, postdata

from rero_ils.modules.items.api import Item
from rero_ils.modules.items.utils import item_pid_to_object
from rero_ils.modules.libraries.api import LibrariesSearch, Library
from rero_ils.modules.loans.api import Loan, get_due_soon_loans, \
    get_last_transaction_loc_for_item, get_overdue_loans
from rero_ils.modules.loans.models import LoanAction, LoanState
from rero_ils.modules.notifications.api import NotificationsSearch
from rero_ils.modules.notifications.dispatcher import Dispatcher
from rero_ils.modules.notifications.models import NotificationType
from rero_ils.modules.notifications.utils import number_of_notifications_sent
from rero_ils.modules.operation_logs.api import OperationLogsSearch

def test_loans_search(
    client, loan_pending_martigny, rero_json_header, librarian_martigny,
    yesterday
):
    """Test record retrieval."""
    login_user_via_session(client, librarian_martigny.user)
    loan = loan_pending_martigny
    original_loan = deepcopy(loan)

    # STEP#1 :: CHECK FACETS ARE PRESENT INTO SEARCH RESULT
    url = url_for('invenio_records_rest.loanid_list',
                  exclude_status=LoanState.ITEM_RETURNED)
    res = client.get(url, headers=rero_json_header)
    data = get_json(res)
    facet_keys = ['end_date', 'misc_status', 'owner_library', 'patron_type',
                  'pickup_library', 'request_expire_date', 'status',
                  'transaction_library']
    assert all(key in data['aggregations'] for key in facet_keys)
    assert data['hits']['total']['value'] == 1

    # STEP#2 :: REQUEST EXPIRED
    #   Update the loan to simulate that this request is now expired.
    params = {'misc_status': 'expired_request'}
    url = url_for('invenio_records_rest.loanid_list', **params)
    res = client.get(url, headers=rero_json_header)
    data = get_json(res)
    assert data['hits']['total']['value'] == 0

    loan['request_expire_date'] = yesterday.isoformat()
    loan.update(loan, dbcommit=True, reindex=True)
    res = client.get(url, headers=rero_json_header)
    data = get_json(res)
    assert data['hits']['total']['value'] == 1

    # STEP#3 :: LOAN IS OVERDUE
    #   Update the loan to be overdue and test the API search.
    params = {'misc_status': 'overdue'}
    url = url_for('invenio_records_rest.loanid_list', **params)
    res = client.get(url, headers=rero_json_header)
    data = get_json(res)
    assert data['hits']['total']['value'] == 0

    loan['end_date'] = yesterday.isoformat()
    loan.update(loan, dbcommit=True, reindex=True)
    res = client.get(url, headers=rero_json_header)
    data = get_json(res)
    assert data['hits']['total']['value'] == 1

    # RESET THE LOAN (for next tests)
    loan.update(original_loan, dbcommit=True, reindex=True)

def test_loan_access_permissions(client, librarian_martigny,
                                 loc_public_saxon,
                                 patron_martigny,
                                 item_lib_sion,
                                 item2_lib_sion,
                                 patron_sion_multiple,
                                 librarian_sion,
                                 patron_sion,
                                 patron2_martigny,
                                 circulation_policies,
                                 loan_pending_martigny,
                                 item_lib_martigny,
                                 loc_public_sion
                                 ):
    """Test loans read permissions."""
    # ensure we have loans from the two configured organisation.
    login_user_via_session(client, librarian_sion.user)
    res, _ = postdata(
        client,
        'api_item.checkout',
        dict(
            item_pid=item_lib_sion.pid,
            patron_pid=patron_sion.pid,
            transaction_location_pid=loc_public_saxon.pid,
            transaction_user_pid=librarian_martigny.pid,
        )
    )
    assert res.status_code == 200

    loan_pids = Loan.get_all_pids()
    loans = [Loan.get_record_by_pid(pid) for pid in loan_pids]
    loans_martigny = [
        loan for loan in loans if loan.organisation_pid == 'org1']
    loans_sion = [loan for loan in loans if loan.organisation_pid == 'org2']
    assert loans
    assert loan_pids
    assert loans_martigny
    assert loans_sion

    # test query filters with a user who is librarian and patron in org2 and
    # patron in org1
    login_user_via_session(client, librarian_sion.user)
    # create a loan for itself
    res, _ = postdata(
        client,
        'api_item.checkout',
        dict(
            item_pid=item2_lib_sion.pid,
            patron_pid=patron_sion_multiple.pid,
            transaction_location_pid=loc_public_sion.pid,
            transaction_user_pid=librarian_sion.pid,
        )
    )
    assert res.status_code == 200

    # act as multiple patron
    login_user_via_session(client, patron_sion_multiple.user)
    # without query filter I should have 3 loans one of mine and two
    # in my employed organisation, the other patron loan of my patron org
    # should be filtered
    loan_list = url_for(
        'invenio_records_rest.loanid_list',
        q=f'')
    res = client.get(loan_list)
    assert res.status_code == 200
    data = get_json(res)
    assert len(data['hits']['hits']) == 3

    # see only my loan
    loan_list = url_for(
        'invenio_records_rest.loanid_list',
        q=f'patron_pid:{patron_sion_multiple.pid}')
    res = client.get(loan_list)
    assert res.status_code == 200
    data = get_json(res)
    assert len(data['hits']['hits']) == 1

    # checkin the item to put it back to it's original state
    login_user_via_session(client, librarian_sion.user)

    res, data = postdata(
        client,
        'api_item.checkin',
        dict(
            item_pid=item2_lib_sion.pid,
            transaction_location_pid=loc_public_sion.pid,
            transaction_user_pid=librarian_sion.pid,
        )
    )
    assert res.status_code == 200

    res, _ = postdata(
        client,
        'api_item.checkin',
        dict(
            item_pid=item_lib_sion.pid,
            transaction_location_pid=loc_public_saxon.pid,
            transaction_user_pid=librarian_martigny.pid,
        )
    )
    assert res.status_code == 200

def test_due_soon_loans(client, librarian_martigny,
                        lib_martigny_data, lib_martigny,
                        patron_martigny, loc_public_martigny,
                        item_type_standard_martigny,
                        item_lib_martigny,
                        circ_policy_short_martigny, yesterday):
    """Test overdue loans."""
    login_user_via_session(client, librarian_martigny.user)
    item = item_lib_martigny
    item_pid = item.pid
    patron_pid = patron_martigny.pid
    can, reasons = item.can_delete
    assert can
    assert reasons == {}
    assert item.is_available()
    assert not get_last_transaction_loc_for_item(item_pid)
    assert not item.patron_has_an_active_loan_on_item(patron_martigny)

    from rero_ils.modules.circ_policies.api import CircPolicy
    circ_policy = CircPolicy.provide_circ_policy(
        item.organisation_pid,
        item.library_pid,
        patron_martigny.patron_type_pid,
        item.item_type_pid
    )
    circ_policy['reminders'][0]['days_delay'] = 7
    circ_policy['checkout_duration'] = 3
    circ_policy.update(circ_policy, dbcommit=True, reindex=True)

    # Remove library exception date to ensure to not been annoyed by
    # closed dates.
    custom_lib_data = deepcopy(lib_martigny_data)
    custom_lib_data['exception_dates'] = []
    lib_martigny.update(custom_lib_data, dbcommit=True, reindex=True)
    flush_index(LibrariesSearch.Meta.index)

    # checkout
    res, data = postdata(
        client,
        'api_item.checkout',
        dict(
            item_pid=item_pid,
            patron_pid=patron_pid,
            transaction_location_pid=loc_public_martigny.pid,
            transaction_user_pid=librarian_martigny.pid,
        )
    )
    assert res.status_code == 200
    loan_pid = data.get('action_applied')[LoanAction.CHECKOUT].get('pid')
    # To be considered as 'due_soon', we need to update the loan start date
    # to figure than start_date occurs before due_date.
    loan = Loan.get_record_by_pid(loan_pid)
    start_date = ciso8601.parse_datetime(loan.get('start_date'))
    loan['start_date'] = (start_date - timedelta(days=30)).isoformat()
    loan.update(loan, dbcommit=True, reindex=True)

    due_soon_loans = list(get_due_soon_loans())
    assert due_soon_loans[0].get('pid') == loan_pid

    # test due date regarding multiple timezones
    checkout_loan = Loan.get_record_by_pid(loan_pid)
    loan_date = ciso8601.parse_datetime(checkout_loan.get('end_date'))

    # as instance timezone is Europe/Zurich, it should be either 21 or 22
    check_timezone_date(pytz.utc, loan_date, [21, 22])

    # should be 14:59/15:59 in US/Pacific (because of daylight saving time)
    check_timezone_date(pytz.timezone('US/Pacific'), loan_date, [14, 15])
    check_timezone_date(pytz.timezone('Europe/Amsterdam'), loan_date)

    # checkin the item to put it back to it's original state
    res, _ = postdata(
        client,
        'api_item.checkin',
        dict(
            item_pid=item_pid,
            pid=loan_pid,
            transaction_location_pid=loc_public_martigny.pid,
            transaction_user_pid=librarian_martigny.pid
        )
    )
    assert res.status_code == 200

    # reset lib
    lib_martigny.update(lib_martigny_data, dbcommit=True, reindex=True)

def test_overdue_loans(client, librarian_martigny,
                       patron_martigny, loc_public_martigny,
                       item_type_standard_martigny,
                       item_lib_martigny, item2_lib_martigny,
                       patron_type_children_martigny,
                       circ_policy_short_martigny,
                       patron3_martigny_blocked):
    """Test overdue loans."""
    login_user_via_session(client, librarian_martigny.user)
    item = item_lib_martigny
    item_pid = item.pid
    patron_pid = patron_martigny.pid

    # checkout
    res, data = postdata(
        client,
        'api_item.checkout',
        dict(
            item_pid=item_pid,
            patron_pid=patron_pid,
            transaction_location_pid=loc_public_martigny.pid,
            transaction_user_pid=librarian_martigny.pid,
        )
    )
    assert res.status_code == 200, "It probably failed while \
        test_due_soon_loans fail"

    loan_pid = data.get('action_applied')[LoanAction.CHECKOUT].get('pid')
    loan = Loan.get_record_by_pid(loan_pid)
    end_date = datetime.now(timezone.utc) - timedelta(days=7)
    loan['end_date'] = end_date.isoformat()
    loan.update(
        loan,
        dbcommit=True,
        reindex=True
    )

    overdue_loans = list(get_overdue_loans(patron_pid=patron_pid))
    assert overdue_loans[0].get('pid') == loan_pid
    assert number_of_notifications_sent(loan) == 0

    notification = loan.create_notification(
        _type=NotificationType.OVERDUE).pop()
    Dispatcher.dispatch_notifications([notification.get('pid')])
    flush_index(NotificationsSearch.Meta.index)
    flush_index(LoansSearch.Meta.index)
    flush_index(OperationLogsSearch.Meta.index)
    assert number_of_notifications_sent(loan) == 1
    # Check notification is created on operation logs
    assert len(list(
        OperationLogsSearch()
        .get_logs_by_notification_pid(notification.get('pid')))) == 1

    # Try a checkout for a blocked user :: It should be blocked
    res, data = postdata(
        client,
        'api_item.checkout',
        dict(
            item_pid=item2_lib_martigny.pid,
            patron_pid=patron3_martigny_blocked.pid,
            transaction_location_pid=loc_public_martigny.pid,
            transaction_user_pid=librarian_martigny.pid,
        )
    )
    assert res.status_code == 403
    assert 'This patron is currently blocked' in data['message']

    # checkin the item to put it back to it's original state
    res, _ = postdata(
        client,
        'api_item.checkin',
        dict(
            item_pid=item_pid,
            pid=loan_pid,
            transaction_location_pid=loc_public_martigny.pid,
            transaction_user_pid=librarian_martigny.pid,
        )
    )
    assert res.status_code == 200

def test_last_end_date_loans(client, librarian_martigny,
                             patron_martigny, loc_public_martigny,
                             item_lib_martigny,
                             circ_policy_short_martigny):
    """Test last_end_date of loan."""
    login_user_via_session(client, librarian_martigny.user)
    item = item_lib_martigny
    item_pid = item.pid
    patron_pid = patron_martigny.pid

    # checkout the item
    res, data = postdata(
        client,
        'api_item.checkout',
        dict(
            item_pid=item_pid,
            patron_pid=patron_pid,
            transaction_location_pid=loc_public_martigny.pid,
            transaction_user_pid=librarian_martigny.pid,
        )
    )
    assert res.status_code == 200

    loan_pid = data.get('action_applied')[LoanAction.CHECKOUT].get('pid')
    loan = Loan.get_record_by_pid(loan_pid)
    assert loan['end_date'] == loan['last_end_date']

    end_date = loan['end_date']

    # checkin the item
    res, _ = postdata(
        client,
        'api_item.checkin',
        dict(
            item_pid=item_pid,
            pid=loan_pid,
            transaction_location_pid=loc_public_martigny.pid,
            transaction_user_pid=librarian_martigny.pid,
        )
    )
    assert res.status_code == 200

    loan = Loan.get_record_by_pid(loan_pid)
    # check last_end_date is the last end_date
    assert loan['last_end_date'] == end_date
    # check end_date is equal to transaction_date
    assert loan['end_date'] == loan['transaction_date']

def test_checkout_item_transit(client, mailbox, item2_lib_martigny,
                               librarian_martigny,
                               librarian_saxon,
                               patron_martigny,
                               loc_public_saxon, lib_martigny,
                               loc_public_martigny,
                               circulation_policies):
    """Test checkout of an item in transit."""
    assert item2_lib_martigny.is_available()
    mailbox.clear()

    # request
    login_user_via_session(client, librarian_martigny.user)
    loc_public_martigny['notification_email'] = 'dummy_email@fake.domain'
    loc_public_martigny['send_notification'] = True
    loc_public_martigny.update(
        loc_public_martigny.dumps(),
        dbcommit=True,
        reindex=True
    )

    res, data = postdata(
        client,
        'api_item.librarian_request',
        dict(
            item_pid=item2_lib_martigny.pid,
            pickup_location_pid=loc_public_saxon.pid,
            patron_pid=patron_martigny.pid,
            transaction_library_pid=lib_martigny.pid,
            transaction_user_pid=librarian_martigny.pid
        )
    )
    assert res.status_code == 200
    actions = data.get('action_applied')
    loan_pid = actions[LoanAction.REQUEST].get('pid')
    assert not item2_lib_martigny.is_available()

    assert len(mailbox) == 1
    assert mailbox[-1].recipients == [
        loc_public_martigny['notification_email']]

    loan = Loan.get_record_by_pid(loan_pid)
    assert loan['state'] == LoanState.PENDING

    # reset the location
    del loc_public_martigny['notification_email']
    del loc_public_martigny['send_notification']
    loc_public_martigny.update(
        loc_public_martigny.dumps(),
        dbcommit=True,
        reindex=True
    )

    # validate request
    res, _ = postdata(
        client,
        'api_item.validate_request',
        dict(
            item_pid=item2_lib_martigny.pid,
            pid=loan_pid,
            transaction_library_pid=lib_martigny.pid,
            transaction_user_pid=librarian_martigny.pid
        )
    )
    assert res.status_code == 200
    assert not item2_lib_martigny.is_available()
    item = Item.get_record_by_pid(item2_lib_martigny.pid)
    assert not item.is_available()

    loan = Loan.get_record_by_pid(loan_pid)
    assert loan['state'] == LoanState.ITEM_IN_TRANSIT_FOR_PICKUP

    login_user_via_session(client, librarian_saxon.user)
    # receive
    res, _ = postdata(
        client,
        'api_item.receive',
        dict(
            item_pid=item2_lib_martigny.pid,
            pid=loan_pid,
            transaction_library_pid=lib_martigny.pid,
            transaction_user_pid=librarian_martigny.pid
        )
    )
    assert res.status_code == 200
    assert not item2_lib_martigny.is_available()
    item = Item.get_record_by_pid(item2_lib_martigny.pid)
    assert not item.is_available()

    loan_before_checkout = get_loan_for_item(item_pid_to_object(item.pid))
    assert loan_before_checkout.get('state') == LoanState.ITEM_AT_DESK
    # checkout
    res, _ = postdata(
        client,
        'api_item.checkout',
        dict(
            item_pid=item2_lib_martigny.pid,
            patron_pid=patron_martigny.pid,
            transaction_location_pid=loc_public_martigny.pid,
            transaction_user_pid=librarian_martigny.pid,
        )
    )
    assert res.status_code == 200
    item = Item.get_record_by_pid(item2_lib_martigny.pid)
    loan_after_checkout = get_loan_for_item(item_pid_to_object(item.pid))
    assert loan_after_checkout.get('state') == LoanState.ITEM_ON_LOAN
    assert loan_before_checkout.get('pid') == loan_after_checkout.get('pid')

def test_timezone_due_date(client, librarian_martigny,
                           patron_martigny, loc_public_martigny,
                           item_type_standard_martigny,
                           item3_lib_martigny,
                           circ_policy_short_martigny,
                           lib_martigny):
    """Test that timezone affects due date regarding library location."""
    # Login to perform action
    login_user_via_session(client, librarian_martigny.user)

    # Close the library all days. Except Monday.
    del lib_martigny['exception_dates']
    lib_martigny['opening_hours'] = [
        {
            "day": "monday",
            "is_open": True,
            "times": [
                {
                    "start_time": "07:00",
                    "end_time": "19:00"
                }
            ]
        },
        {
            "day": "tuesday",
            "is_open": False,
            "times": []
        },
        {
            "day": "wednesday",
            "is_open": False,
            "times": []
        },
        {
            "day": "thursday",
            "is_open": False,
            "times": []
        },
        {
            "day": "friday",
            "is_open": False,
            "times": []
        },
        {
            "day": "saturday",
            "is_open": False,
            "times": []
        },
        {
            "day": "sunday",
            "is_open": False,
            "times": []
        }
    ]
    lib_martigny.update(lib_martigny, dbcommit=True, reindex=True)

    # Change circulation policy
    checkout_duration = 3
    item = item3_lib_martigny
    item_pid = item.pid
    patron_pid = patron_martigny.pid
    from rero_ils.modules.circ_policies.api import CircPolicy
    circ_policy = CircPolicy.provide_circ_policy(
        item.organisation_pid,
        item.library_pid,
        patron_martigny.patron_type_pid,
        item.item_type_pid
    )
    circ_policy['reminders'][0]['days_delay'] = 7
    circ_policy['checkout_duration'] = checkout_duration
    circ_policy.update(
        circ_policy,
        dbcommit=True,
        reindex=True
    )

    # Checkout the item
    res, data = postdata(
        client,
        'api_item.checkout',
        dict(
            item_pid=item_pid,
            patron_pid=patron_pid,
            transaction_location_pid=loc_public_martigny.pid,
            transaction_user_pid=librarian_martigny.pid,
        )
    )
    assert res.status_code == 200

    # Get Loan date (should be in UTC)
    loan_pid = data.get('action_applied')[LoanAction.CHECKOUT].get('pid')
    loan = Loan.get_record_by_pid(loan_pid)
    loan_end_date = loan.get('end_date')

    # Get next library open date (should be next monday after X-1 days) where
    # X is checkout_duration
    soon = datetime.now(pytz.utc) + timedelta(days=(checkout_duration-1))
    lib = Library.get_record_by_pid(item.library_pid)
    lib_datetime = lib.next_open(soon)

    # Loan date should be in UTC (as lib_datetime).
    loan_datetime = ciso8601.parse_datetime(loan_end_date)

    # Compare year, month and date for Loan due date: should be the same!
    fail_msg = "Check timezone for Loan and Library. \
It should be the same date, even if timezone changed."
    assert loan_datetime.year == lib_datetime.year, fail_msg
    assert loan_datetime.month == lib_datetime.month, fail_msg
    assert loan_datetime.day == lib_datetime.day, fail_msg
    # Loan date differs regarding timezone, and day of the year (GMT+1/2).
    check_timezone_date(pytz.utc, loan_datetime, [21, 22])

def test_librarian_request_on_blocked_user(
        client, item_lib_martigny, lib_martigny,
        librarian_martigny, loc_public_martigny,
        patron3_martigny_blocked,
        circulation_policies):
    """Librarian request on blocked user returns a specific 403 message."""
    assert item_lib_martigny.is_available()

    # request
    login_user_via_session(client, librarian_martigny.user)
    res, data = postdata(
        client,
        'api_item.librarian_request',
        dict(
            item_pid=item_lib_martigny.pid,
            patron_pid=patron3_martigny_blocked.pid,
            pickup_location_pid=loc_public_martigny.pid,
            transaction_library_pid=lib_martigny.pid,
            transaction_user_pid=librarian_martigny.pid
        )
    )
    assert res.status_code == 403
    data = get_json(res)
    assert 'blocked' in data.get('message')


# Brady Young
# This file contains the node definitions for both the output
# and hidden layers. Each calculates their errors and updates their weights
# in slightly different ways in my implementation so they each have their own class.

import numpy as np
import Activations as activate

# Class to hold the data members of subclasses
class Node:
    def __init__(self, outputs, inputs):
        self.weights = np.random.rand(outputs, inputs)
        self.weights -= 0.5  # Scales the weights
        self.activated = []  # List to hold activated values for each node
        self.error = None  # Holds the error value for each node

# Defines the node functions for the Hidden Layer #
class Hidden(Node):
    # Creates a list of each hidden node's activated values
    def activation(self, array, activation):
        self.activated = []

        if activation is "sig":
            for a in array:
                self.activated.append(activate.sigmoid(a))
        else:
            for a in array:
                self.activated.append(activate.arctan(a))

        # attach bias
        self.activated.append(1)
        # convert activated list to numpy array
        self.activated = np.array(self.activated)

    #  -Calculates each nodes error based on output node error and current activations
    #  -Sets the error for each node
    #  -Removes the bias from activated list and error list
    #    The bias is included up to the error calculation,
    #    but is removed afterwards because the bias node value
    #    is static
    def calcError(self, output, activation):
        if activation is "sig":
            term_two = (1 - self.activated)
            term_three = output.weights * output.error.reshape((-1, 1))
            error = self.activated * term_two * np.sum(term_three, axis=0)

            # Error is set to none after updating weights
            if self.error is None:
                self.error = error
            else:
                self.error += error

        # Arctan derivative
        else:
            term_one = output.weights * output.error.reshape((-1, 1))
            term_one = np.sum(term_one, axis=0)
            error = 1 / (1 + term_one)

            if self.error is None:
                self.error = error
            else:
                self.error += error

    # Updates the weight values based on the error and learning rate
    def update(self, features, params):
        self.error = np.delete(self.error, params.num_hidden)  # bias removed
        change = params.rate * np.outer(self.error, features)
        self.weights += (change / params.batch_size)

        # Clear the error for next batch
        self.error = None

# Defines the node functions for the output layer
class Output(Node):
    # Creates a list of each output node's activated values
    def activation(self, array, activation):
        self.activated = []
        if activation is "sig":
            for a in array:
                self.activated.append(activate.sigmoid(a))

        else:
            for a in array:
                self.activated.append(activate.arctan(a))

        self.activated = np.array(self.activated)

    # Calculates error for output nodes
    def calcError(self, target, activation):
        if activation is "sig":
            term_two = 1 - self.activated
            term_three = target - self.activated
            error = self.activated * term_two * term_three

            if self.error is None:
                self.error = error
            else:
                self.error += error

        else:
            term_one = target - self.activated
            error = 1 / (1 + term_one)

            if self.error is None:
                self.error = error
            else:
                self.error += error

    # Updates the output node weights
    def update(self, inputs, params):
        if hasattr(inputs, 'activated'):
            change = params.rate * np.outer(self.error, inputs.activated)
        else:
            change = params.rate * np.outer(self.error, inputs)

        self.weights += (change / params.batch_size)
        self.error = None