# Shreeharsha Satish, 201665390

import random
import datetime

class BasicAccount:
    '''
    This class describes a basic account at a bank. It has a global account number, name and users cannot overdraft

    It also has methods for depositing or withdrawing money, closing the account, printing the balance and getting
    general information on the account. You can also get a new card with an expiry date 3 years to the month on
    which the method is called.

    '''
    overdraft = False
    acNum = 0

    #  __init__(self, acName, openingBalance) - to initialize the bank account
    #  parameters - acName: string of name of account holder, openingBalance: float number of initial deposit
    #  doesn't return anything
    def __init__(self, acName, openingBalance):
        BasicAccount.acNum += 1
        self.acNum = BasicAccount.acNum
        self.name = acName
        self.overdraftLimit = 0
        self.initialOverdraft = 0
        self.balance = 0
        self.deposit(openingBalance)  # Use the deposit function to set openingBalance because of its error handling
        self.overdraft = BasicAccount.overdraft

    #  __str__(self) - summarizes the account
    #  parameters - self
    #  returns the name, acNum and balance
    def __str__(self):
        return f"Hello {self.name}, Your account number: {self.acNum}, Your balance amount is: £{self.balance}. You do not have a Premium Account to apply for an overdraft"

    #  deposit(self, amount) - allows money to be deposited to an account
    #  parameters - amount: float of money to be added to account
    #  returns nothing
    def deposit(self, amount):
        try:
            if(amount < 0):
                raise ValueError
            else:
                self.balance += amount
                return

        except ValueError:
            print("Invalid deposit amount")

    #  withdraw(self, amount) - allows money to be withdrawn from an account
    #  parameters - amount: float of money to be withdrawn from account depending on overdraft availability
    #  returns nothing
    def withdraw(self, amount):
        try:
            if(self.balance - amount >= 0):  # amount < Balance
                self.balance -= amount
                print(f"{self.name} has withdrawn £{amount}. New balance is £{self.balance}")

            else:
                if(self.overdraft == True and self.overdraftLimit + self.balance - amount >= 0):  # Check overdraft and limit
                    self.overdraftLimit = self.overdraftLimit + self.balance - amount
                    self.balance = self.overdraftLimit - self.initialOverdraft
                    print(f"{self.name} has withdrawn £{amount}. New balance is £{self.balance} and overdraft available is £{self.overdraftLimit}")
                    return

                elif(self.overdraft == True and self.overdraftLimit + self.balance - amount < 0):
                    print(f"You have exceeded your overdraft limit, cannot withdraw £{amount}")
                    return

                else:
                    print(f"You don't have an overdraft with your basic account, cannot withdraw £{amount}")
                    return

        except ValueError:
            print("Invalid withdrawal amount")

    #  getAvailableBalance(self)
    #  parameters - self (the object in question)
    #  returns the total balance available (actual balance + overdraft in case positive balance and just overdraft otherwise)
    def getAvailableBalance(self):
        if(self.balance > 0):
            return self.balance+self.overdraftLimit
        else:
            return self.overdraftLimit

    #  getBalance(self)
    #  parameters - self (the object in question)
    #  returns the net money (actual balance) which can be negative if you've overdrafted
    def getBalance(self):
        return self.balance

    #  printBalance(self)
    #  parameters - self (the object in question)
    #  prints the Balance instead of returning
    def printBalance(self):
        print(self.balance)
        return

    #  getName(self)
    #  parameters - self (the object in question)
    #  returns acName: string account holder name
    def getName(self):
        return self.name

    #  getAcNum(self)
    #  parameters - self (the object in question)
    #  returns acName: string format of account number
    def getAcNum(self):
        return str(self.acNum)

    #  issueNewCard(self)
    #  parameters - self (the object in question)
    #  returns nothing, prints description of the card created and its expiry date, 3 years from the month on which it was created
    def issueNewCard(self):
        self.cardNum = str(f'{random.randrange(0, (10**16)-1)}'.zfill(16))
        self.start = datetime.datetime.today().strftime('%m/%d/%Y')
        self.cardExp = (int(self.start.split('/')[0]),int(self.start.split('/')[-1][2:])+3)
        print(f"Hello, your new card has been issued, 16 digtit number: {self.cardNum} ; Expiry date: {self.cardExp}")
        return

    #  closeAccount(self)
    #  parameters - self (the object in question)
    #  returns True if account can be closed (no due overdraft) False otherwise
    def closeAccount(self):
        if(self.overdraft and self.balance < 0):
            print(f"Cannot close your account because it is overdrawn by £{-self.balance}")
            return False
        else:
            self.withdraw(self.balance)
            return True

class PremiumAccount(BasicAccount):  #inherits from the BasicAccount class
    '''
    This class is just like BasicAccount and inherits all methods but you can also overdraft and withdraw
    amounts up to the limit with this premium account.

    Also, the welcome message is more... welcoming

    '''

    overdraft = True

    #  __init__(self, acName, openingBalance, initialOverdraft) - to initialize the bank account
    #  parameters - acName: string of name of account holder, openingBalance: float number of initial deposit, initialOverdraft: float number of initial Overdraft
    #  doesn't return anything
    def __init__(self, acName, openingBalance, initialOverdraft):
        BasicAccount.acNum += 1
        self.acNum = BasicAccount.acNum
        self.name = acName
        self.overdraft = PremiumAccount.overdraft
        self.balance = 0
        self.initialOverdraft = 0
        self.overdraftLimit = 0
        self.deposit(openingBalance)  # Use the deposit function to set openingBalance because of its error handling
        self.setOverdraftLimit(initialOverdraft)  # Use the setOverdraftLimit function to set overdraft because of its error handling
        self.initialOverdraft = self.overdraftLimit  # Store the initialOverdraft as an instance variable, needed when closing account

    #  setOverdraftLimit(self) - sets overdraft limit
    #  parameters - newLimit: float number of new overdraft
    #  returns nothing
    def setOverdraftLimit(self, newLimit):
        try:
            if(newLimit < 0):
                raise ValueError
            else:  # The conditions below check whether the new overdraft limit is bigger or if it is made lesser, whether all the overdraft has been paid back
                if(newLimit >= self.overdraftLimit):
                    self.initialOverdraft = newLimit + self.initialOverdraft - self.overdraftLimit  # This is to prevent any fraud from the use of this function
                    self.overdraftLimit = newLimit
                    return
                elif(newLimit < self.overdraftLimit and self.initialOverdraft==self.overdraftLimit):  # Freely change limit if nothing has been overdrafted
                    self.initialOverdraft = newLimit
                    self.overdraftLimit = newLimit
                    return
                else:
                    print("You cannot reduce your overdraft without paying it back, try again.")
                    return

        except ValueError:
            print("Invalid value entered, you need to enter a positive overdraft value")

    #  __str__(self) - summarizes the account
    #  parameters - self
    #  returns the name, acNum, balance and overdraft available
    def __str__(self):
        return f"Welcome {self.name}, You are a Premium Account holder. Your account number: {self.acNum}, Your balance amount: £{self.balance}, Overdraft amount available: £{self.overdraftLimit}"


from linebot import LineBotApi
from dotenv import load_dotenv
import os

class Member(object):
    def __init__(self) -> None:
        load_dotenv()

        # make sure that download folder exists, ledger and record folder
        self.__fileFolder = os.path.join(os.getcwd(), 'files')
        if not os.path.exists(self.__fileFolder):
            os.makedirs(self.__fileFolder)

        self.__memberFile = os.path.join(self.__fileFolder, 'members.txt')
        if not os.path.exists(self.__memberFile):
            f = open(self.__memberFile, 'w')
            f.close()

        # line_bot_api
        self.__line_bot_api = LineBotApi(os.getenv('LINE_CHANNEL_ACCESS_TOKEN'))

    @staticmethod
    def GET_ALL_NICKNAME() -> list:
        filePath = os.path.join(os.path.join(os.getcwd(), 'files'), 'members.txt')
        if not os.path.exists(filePath):
            return list()

        result = list()
        with open(filePath, 'r') as f:
            for line in f.readlines():
                nickName = line.rstrip('\n').split(' ')[1]
                result.append(nickName)

        return result

    def __checkID(self, id) -> bool:
        with open(self.__memberFile, 'r') as f:
            for line in f.readlines():
                s = line.rstrip('\n')
                spl = s.split(' ')
                if (spl[0] == id):
                    return True

        return False

    def __checkNameValidation(self, name) -> bool:
        with open(self.__memberFile, 'r') as f:
            for line in f.readlines():
                line = line.rstrip('\n')
                spl = line.split(' ')
                name = name.lower()
                if name in spl[1].lower() or spl[1].lower() in name:
                    return True

        return False

    def getMembers(self) -> str:
        result = str()

        with open(self.__memberFile, 'r') as f:
            for line in f.readlines():
                nickName = line.rstrip('\n').split(' ')[1]
                userName = line.rstrip('\n').split(' ')[2]
                result += f'{nickName}: {userName}\n'

        return result

    def checkMemberExist(self, name) -> str:
        with open(self.__memberFile, 'r') as f:
            for line in f.readlines():
                nickName = line.rstrip('\n').split(' ')[1]
                userName = line.rstrip('\n').split(' ')[2]
                if name.lower() in nickName.lower() or nickName.lower() in name.lower():
                    return 'Exist'

        return 'Not Exist'

    def addMember(self, nickName, userID, roomID) -> str:
        if (self.__checkNameValidation(nickName) == True):
            raise Exception('the name is invalid')
        # elif (self.__checkID(userID) == True and False):
        #     # temp remove for testing
        #     raise Exception('the user id has already existed')

        # create member file if not exist
        self.__memberFile = os.path.join(self.__fileFolder, 'members.txt')
        if not os.path.exists(self.__memberFile):
            f = open(self.__memberFile, 'w')
            f.close()

        profile = self.__line_bot_api.get_group_member_profile(roomID, userID)
        with open(self.__memberFile, 'a') as f:
            f.write(f'{userID} {nickName} {profile.display_name}\n')

        return f'add member "{profile.display_name}" "{nickName}": SUCCESS'

if __name__ == '__main__':
    m = Member()


#!/usr/bin/env python3
import pwd

from argparse import ArgumentParser

from os import chdir
from pathlib import PurePath, Path

from client_backend.fs_db_io import FSDatabase
from client_backend.fs_db_file import *
from client_backend.fs_db_users import *

from stat import S_IRWXU, S_IRWXG, S_IRWXO

FS_DB = FSDatabase('.fs_db_rdbsh')
ROOTFS_PATH = Path('setup/rootfs/')

# Should create root user (uid/gid = 0) & nobody user (uid/gid = 99)

def _to_db_path(path):
    try:
        if path.anchor:
            currentPath = Path().resolve()
            path = path.relative_to(currentPath)
        return PurePath("/").joinpath(path)
    except ValueError:
        print(f"Warning: Could not locate'{path}' in Relational Database File System Root ({ROOTFS_PATH} by default)")
        return None

def insertDataIntoDB(x, fs_db):
    print(f'Copying & Uploading: {x.as_posix()}')
    if x.is_symlink():
        SymbolicLink(fs_db, _to_db_path(x), create_if_missing=True, linked_path=_to_db_path(x.resolve(strict=False)))
    elif x.is_dir():
        Directory(fs_db, _to_db_path(x), create_if_missing=True)
        for x_child in x.iterdir():
            insertDataIntoDB(x_child, fs_db)
    elif x.is_file():
        db_file = RegularFile(fs_db, _to_db_path(x), create_if_missing=True, contents="")
        # NOTE: Unix doesn't return the original creator, so we just call the user the author
        # NOTE: Also API doesn't support changing the author
        # db_file.author = user
        user = User(fs_db, x.stat().st_uid, create_if_missing=True, user_name=x.owner())
        group = Group(fs_db, x.stat().st_gid, create_if_missing=True, group_name=x.group())
        db_file.owner = user
        db_file.group_owner = group
        db_file.permissions = x.stat().st_mode & (S_IRWXU | S_IRWXG | S_IRWXO)
        with x.open('rb') as f:
            db_file.write(f.readlines())
    else:
        print('Warning: Encountered unsupported file type', x.as_posix())

if __name__ == "__main__":
    parser = ArgumentParser(description="Upload files to your MySQL File System")
    parser.add_argument("custom_rdb_fs_root",
        help=f"The path realtive to {ROOTFS_PATH} to upload from, otherwise upload from {ROOTFS_PATH} by default",
        nargs='?',
        default='.')

    args = parser.parse_args()

    chdir(Path(ROOTFS_PATH).joinpath(args.custom_rdb_fs_root))
    insertDataIntoDB(Path(), FS_DB)


from typing import List
import collections

class Solution:
    def findOrder(self, numCourses: int, prerequisites: List[List[int]]) -> List[int]:
        indeg = [0] * numCourses
        ans = []
        edges = collections.defaultdict(list)
        for edge in prerequisites:
            edges[edge[1]].append(edge[0])
            indeg[edge[0]] += 1
        q = collections.deque(
            [idx for idx, val in enumerate(indeg) if val == 0])
        while q:
            node = q.pop()
            ans.append(node)
            for out in edges[node]:
                indeg[out] -= 1
                if indeg[out] == 0:
                    q.appendleft(out)
        return ans if len(ans) == numCourses else []

if __name__ == "__main__":
    s = Solution()
    print()


"""indices

Revision ID: 4888e69ac49
Revises: 23ed581b6dc
Create Date: 2015-12-22 23:07:18.886827

"""

# revision identifiers, used by Alembic.
revision = '4888e69ac49'
down_revision = '23ed581b6dc'

from alembic import op
import sqlalchemy as sa

def upgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.create_index('ix_session_start_time', 'session', [sa.text('start_time DESC')], unique=False)
    op.create_index('ix_test_start_time', 'test', [sa.text('start_time DESC')], unique=False)
    ### end Alembic commands ###

def downgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.drop_index('ix_test_start_time', table_name='test')
    op.drop_index('ix_session_start_time', table_name='session')
    ### end Alembic commands ###


# -*- coding: utf-8 -*-
"""
Created on Sunday Dec. 24th
============================================================
@author: Tiger

Add:
        - loss plot only accumulated loss
        - validation over 1000 images per epoch
        - smaller kernel size
        - smaller image crop
        - RAM???
"""
""" Install for Pytorch:

     1) must first install cuda
     2) conda install pytorch torchvision cudatoolkit=10.2 -c pytorch   # Must indicate cuda version???

     3) pip install torchio

     torch.__version__

     *** must add device(device) ==> to send things to GPU!

     ***crazy speed up with line below
     torch.backends.cudnn.benchmark = True

     torch.backends.cudnn.deterministic=True

     ***For uninstall:
     conda install pytorch torchvision cudatoolkit=10.2 -c pytorch

     put import statements at top of file or may crash???

     Add main function so can do multi-threading?
     no classes within main function

     use volatile == True for inference mode???
"""

""" ALLOWS print out of results on compute canada """
import matplotlib
matplotlib.rc('xtick', labelsize=8)
matplotlib.rc('ytick', labelsize=8)
#matplotlib.use('Agg')
import matplotlib.pyplot as plt

""" Libraries to load """
import numpy as np
from plot_functions_CLEANED import *
from data_functions_CLEANED import *
from data_functions_3D import *
from tracker import *
import glob, os
import datetime
import time
from natsort import natsort_keygen, ns
natsort_key1 = natsort_keygen(key = lambda y: y.lower())      # natural sorting order

import torch
from torch import nn
import torch.nn.functional as F
import torch.optim as optim
from UNet_pytorch import *
from UNet_pytorch_online import *
from PYTORCH_dataloader import *
from HD_loss import *

from sklearn.model_selection import train_test_split

from unet_nested import *

torch.backends.cudnn.benchmark = True
torch.backends.cudnn.enabled = True

if __name__ == '__main__':

    """ Define GPU to use """
    device = torch.device("cuda:1" if torch.cuda.is_available() else "cpu")
    print(device)

    """" Input paths """
    HD = 0; alpha = 1; dist_loss = 0; deep_sup = 0;
    #s_path = './(1) Checkpoints_full_auto_no_spatialW_TRACKER/';
    #s_path = './(2) Checkpoints_full_auto_spatialW/'

    #s_path = './(3) Checkpoints_full_auto_no_spatialW_nested_unet/'

    s_path = './(4) Checkpoints_full_auto_no_spatialW_large_TRACKER/'

    #s_path = './(5) Checkpoints_full_auto_no_spatialW_large_TRACKER_switch_norm/'

    s_path = './(6) Checkpoints_full_auto_no_spatialW_large_TRACKER_NO_NEXT_SEG/'

    s_path = './(7) Checkpoints_full_auto_no_spatialW_large_TRACKER_CROP_PADS_NO_NEXT_SEG_skipped/'; next_seg = 0;

    #s_path = './(8) Checkpoints_full_auto_no_spatialW_large_TRACKER_CROP_PADS_YES_NEXT_SEG/'; next_seg = 1;

    s_path = './(9) Checkpoints_full_auto_no_spatialW_large_TRACKER_CROP_PADS_NO_NEXT_hausdorf/'; next_seg = 0; HD = 1; alpha = 1;

    #s_path = './(10) Checkpoints_full_auto_no_spatialW_large_TRACKER_CROP_PADS_NO_NEXT/'; next_seg = 0;

    input_path = '/media/user/storage/Data/(2) cell tracking project/a_training_data_GENERATE_FULL_AUTO/Training_cell_track_full_auto_COMPLETED_crop_pads/'

    resume = 0
    """ TO LOAD OLD CHECKPOINT """
    # Read in file names
    onlyfiles_check = glob.glob(os.path.join(s_path,'check_*'))
    onlyfiles_check.sort(key = natsort_key1)

    # """ load mean and std """
    mean_arr = np.load('./normalize_pytorch_CLEANED/mean_VERIFIED.npy')
    std_arr = np.load('./normalize_pytorch_CLEANED/std_VERIFIED.npy')

    num_workers = 2;

    save_every_num_epochs = 1;    plot_every_num_epochs = 1;    validate_every_num_epochs = 1;

    deep_supervision = False;

    """ Load filenames from tiff """
    images = glob.glob(os.path.join(input_path,'*_crop_input_cur.tif'))    # can switch this to "*truth.tif" if there is no name for "input"
    images.sort(key=natsort_keygen(alg=ns.REAL))  # natural sorting
    examples = [dict(input=i,seed          = i.replace('_crop_input_cur.tif','_crop_input_cur_seed.tif'),
                             cur_full_seg  = i.replace('_crop_input_cur.tif','_crop_input_cur_seg_FULL.tif'),
                             next_input    = i.replace('_crop_input_cur.tif','_crop_input_next.tif'),
                             next_full_seg = i.replace('_crop_input_cur.tif','_crop_input_next_seg_FULL.tif'),
                             truth         = i.replace('_crop_input_cur.tif','_crop_truth.tif')) for i in images]

    # ### REMOVE FULL TIMESERIES from training data
    idx_skip = []
    for idx, im in enumerate(examples):
        filename = im['input']
        if 'MOBPF_190105w_1_cuprBZA_10x' in filename:
            print('skip')
            idx_skip.append(idx)

    ### USE THE EXCLUDED IMAGE AS VALIDATION/TESTING
    examples_test = examples[0:len(idx_skip)]

    examples = [i for j, i in enumerate(examples) if j not in idx_skip]

    counter = list(range(len(examples)))

    if not onlyfiles_check:   ### if no old checkpoints found, start new network and tracker

        """ Hyper-parameters """
        deep_sup = False
        switch_norm = False
        sp_weight_bool = 0
        #transforms = initialize_transforms(p=0.5)
        #transforms = initialize_transforms_simple(p=0.5)
        transforms = 0
        batch_size = 4;
        test_size = 0.1

        if next_seg:
            in_channels = 4
        else:
            in_channels = 3

        """ Initialize network """
        kernel_size = 7
        pad = int((kernel_size - 1)/2)
        unet = UNet_online(in_channels=in_channels, n_classes=2, depth=5, wf=4, kernel_size = kernel_size, padding= int((kernel_size - 1)/2),
                            batch_norm=True, batch_norm_switchable=switch_norm, up_mode='upsample')
        #unet = NestedUNet(num_classes=2, input_channels=2, deep_sup=deep_sup, padding=pad, batch_norm_switchable=switch_norm)
        #unet = UNet_3Plus(num_classes=2, input_channels=2, kernel_size=kernel_size, padding=pad)

        unet.train()
        unet.to(device)
        print('parameters:', sum(param.numel() for param in unet.parameters()))

        """ Select loss function *** unimportant if using HD loss """
        if not HD:    loss_function = torch.nn.CrossEntropyLoss(reduction='none')
        else:         loss_function = 'Haussdorf'

        """ Select optimizer """
        lr = 1e-5; milestones = [20, 100]  # with AdamW slow down
        optimizer = torch.optim.AdamW(unet.parameters(), lr=lr, betas=(0.9, 0.999), eps=1e-08, weight_decay=0.01, amsgrad=False)

        """ Add scheduler """
        scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones, gamma=0.1, last_epoch=-1)

        """ initialize index of training set and validation set, split using size of test_size """

        idx_train, idx_valid, empty, empty = train_test_split(counter, counter, test_size=test_size, random_state=2018)

        """ initialize training_tracker """
        # idx_valid = idx_skip
        # idx_train = counter

        tracker = tracker(batch_size, test_size, mean_arr, std_arr, idx_train, idx_valid, deep_sup=deep_sup, switch_norm=switch_norm, alpha=alpha, HD=HD,
                                          sp_weight_bool=sp_weight_bool, transforms=transforms, dataset=input_path)

        tracker.next_seg = next_seg

    else:
        """ Find last checkpoint """
        last_file = onlyfiles_check[-1]
        split = last_file.split('check_')[-1]
        num_check = split.split('.')
        checkpoint = num_check[0]
        checkpoint = 'check_' + checkpoint

        print('restoring weights from: ' + checkpoint)
        check = torch.load(s_path + checkpoint, map_location=lambda storage, loc: storage)
        #check = torch.load(s_path + checkpoint, map_location='cpu')
        #check = torch.load(s_path + checkpoint, map_location=device)

        tracker = check['tracker']

        unet = check['model_type']
        optimizer = check['optimizer_type']
        scheduler = check['scheduler_type']
        unet.load_state_dict(check['model_state_dict'])
        unet.to(device)
        optimizer.load_state_dict(check['optimizer_state_dict'])
        scheduler.load_state_dict(check['scheduler'])
        loss_function = check['loss_function']

        print('parameters:', sum(param.numel() for param in unet.parameters()))

        """ Clean up checkpoint file """
        del check
        torch.cuda.empty_cache()

    """
        Time for 50 iterations (batch size 2)
        411.34 ==> 0 workers
        183.78438819999997 ==> 2 workers
        127 ==> 4 workers ==> 60 secs training generator time
        111.03402260000001 ==> no transform
        109 ==> 6 workers ==> 90 secs training generator time
        110.0 ==> 6 workers WITH DIRECT LOADING FROM BCOLZ ==> 30 secs generator tim
        max is 1000 samples loaded with batch size 2 and even with batch size 1???

        On Titan:
            time for 50 batch size 2 ==> 71 secs
            time for 50 batch size 4 ==> 116 secs (with transforms)

    """

    """ Create datasets for dataloader """
    training_set = Dataset_tiffs(tracker.idx_train, examples, tracker.mean_arr, tracker.std_arr,
                                           sp_weight_bool=tracker.sp_weight_bool, transforms = tracker.transforms, next_seg=tracker.next_seg)
    val_set = Dataset_tiffs(tracker.idx_valid, examples, tracker.mean_arr, tracker.std_arr,
                                      sp_weight_bool=tracker.sp_weight_bool, transforms = 0, next_seg=tracker.next_seg)

    """ Create training and validation generators"""
    val_generator = data.DataLoader(val_set, batch_size=tracker.batch_size, shuffle=False, num_workers=num_workers,
                    pin_memory=True, drop_last = True)

    training_generator = data.DataLoader(training_set, batch_size=tracker.batch_size, shuffle=True, num_workers=num_workers,
                      pin_memory=True, drop_last=True)

    print('Total # training images per epoch: ' + str(len(training_set)))
    print('Total # validation images: ' + str(len(val_set)))

    """ Epoch info """
    train_steps_per_epoch = len(tracker.idx_train)/tracker.batch_size
    validation_size = len(tracker.idx_valid)
    epoch_size = len(tracker.idx_train)

    print('Total # training images per epoch: ' + str(len(training_set)))
    print('Total # validation images: ' + str(len(val_set)))

    """ Epoch info """
    train_steps_per_epoch = len(tracker.idx_train)/tracker.batch_size
    validation_size = len(tracker.idx_valid)
    epoch_size = len(tracker.idx_train)

    """ Start training """
    starter = 0
    for cur_epoch in range(len(tracker.train_loss_per_epoch), 10000):
         unet.train
         loss_train = 0
         jacc_train = 0

         """ check and plot params during training """
         for param_group in optimizer.param_groups:
               #tracker.alpha = 0.5
               param_group['lr'] = 1e-6   # manually sets learning rate
               cur_lr = param_group['lr']
               tracker.lr_plot.append(cur_lr)
               tracker.print_essential()

         iter_cur_epoch = 0;
         ce_train = 0; dc_train = 0; hd_train = 0;
         for batch_x, batch_y, spatial_weight in training_generator:
                starter += 1
                if starter == 1:
                    start = time.perf_counter()
                if starter == 50:
                    stop = time.perf_counter(); diff = stop - start; print(diff)

                # PRINT OUT THE SHAPE OF THE INPUT
                if iter_cur_epoch == 0:
                    print('input size is' + str(batch_x.shape))

                """ Plot for debug """
                # np_inputs = np.asarray(batch_x.numpy()[0], dtype=np.uint8)
                # np_labels = np.asarray(batch_y.numpy()[0], dtype=np.uint8)
                # np_labels[np_labels > 0] = 255

                # imsave(s_path + str(iterations) + '_input.tif', np_inputs)
                # imsave(s_path + str(iterations) + '_label.tif', np_labels)

                # in_max = plot_max(np_inputs, plot=0)
                # lb_max = plot_max(np_labels, plot=0)

                # imsave(s_path + str(iterations) + '_max_input.tif', in_max)
                # imsave(s_path + str(iterations) + '_max_label.tif', lb_max)

                """ Load data ==> shape is (batch_size, num_channels, depth, height, width)
                     (1) converts to Tensor
                     (2) normalizes + appl other transforms on GPU
                     (3) ***add non-blocking???
                     ***INPUT LABELS MUST BE < 255??? or else get CudNN error

                """
                inputs, labels = transfer_to_GPU(batch_x, batch_y, device,  tracker.mean_arr, tracker.std_arr)

                """ zero the parameter gradients"""
                optimizer.zero_grad()

                """ forward + backward + optimize """
                output_train = unet(inputs)

                """ calculate loss: includes HD loss functions """
                if tracker.HD:
                    loss, tracker, ce_train, dc_train, hd_train = compute_HD_loss(output_train, labels, tracker.alpha, tracker,
                                                                                ce_train, dc_train, hd_train, val_bool=0)
                else:
                     if deep_sup:   ### IF DEEP SUPERVISION
                        # compute output
                        loss = 0
                        for output in output_train:
                             loss += loss_function(output, labels)
                        loss /= len(output_train)
                        output_train = output_train[-1]  # set this so can eval jaccard later

                     else:   ### IF NORMAL LOSS CALCULATION
                        loss = loss_function(output_train, labels)
                        if torch.is_tensor(spatial_weight):   ### WITH SPATIAL WEIGHTING
                             spatial_tensor = torch.tensor(spatial_weight, dtype = torch.float, device=device, requires_grad=False)
                             weighted = loss * spatial_tensor
                             loss = torch.mean(weighted)

                        else:  ### NO WEIGHTING AT ALL
                             loss = torch.mean(loss)

                loss.backward()
                optimizer.step()

                """ Training loss """
                """ ********************* figure out how to do spatial weighting??? """
                """ Training loss """
                tracker.train_loss_per_batch.append(loss.cpu().data.numpy());  # Training loss
                loss_train += loss.cpu().data.numpy()

                """ Calculate Jaccard on GPU """
                jacc = jacc_eval_GPU_torch(output_train, labels)
                jacc = jacc.cpu().data.numpy()

                jacc_train += jacc # Training jacc
                tracker.train_jacc_per_batch.append(jacc)

                tracker.iterations = tracker.iterations + 1
                iter_cur_epoch += 1
                if tracker.iterations % 100 == 0:
                     print('Trained: %d' %(tracker.iterations))

         tracker.train_loss_per_epoch.append(loss_train/iter_cur_epoch)
         tracker.train_jacc_per_epoch.append(jacc_train/iter_cur_epoch)

         """ Should I keep track of loss on every single sample? and iteration? Just not plot it??? """
         loss_val = 0; jacc_val = 0
         precision_val = 0; sensitivity_val = 0; val_idx = 0;
         iter_cur_epoch = 0;
         ce_val = 0; dc_val = 0; hd_val = 0;
         total_FPs = 0; total_TPs = 0; total_FNs = 0; total_TNs = 0;
         if cur_epoch % validate_every_num_epochs == 0:

              with torch.set_grad_enabled(False):  # saves GPU RAM
                  unet.eval()
                  for batch_x_val, batch_y_val, spatial_weight in val_generator:

                        """ Transfer to GPU to normalize ect... """
                        inputs_val, labels_val = transfer_to_GPU(batch_x_val, batch_y_val, device, mean_arr, std_arr)
                        output_val = unet(inputs_val)

                        """ calculate loss
                                include HD loss functions """
                        if tracker.HD:
                            loss, tracker, ce_val, dc_val, hd_val = compute_HD_loss(output_val, labels_val, tracker.alpha, tracker,
                                                                                ce_val, dc_val, hd_val, val_bool=1)
                        else:
                            if deep_sup:
                                # compute output
                                loss = 0
                                for output in output_val:
                                     loss += loss_function(output, labels_val)
                                loss /= len(output_val)
                                output_val = output_val[-1]  # set this so can eval jaccard later
                            else:

                                loss = loss_function(output_val, labels_val)
                                if torch.is_tensor(spatial_weight):
                                       spatial_tensor = torch.tensor(spatial_weight, dtype = torch.float, device=device, requires_grad=False)
                                       weighted = loss * spatial_tensor
                                       loss = torch.mean(weighted)
                                elif dist_loss:
                                       loss  # do not do anything if do not need to reduce

                                else:
                                       loss = torch.mean(loss)

                        """ Training loss """
                        tracker.val_loss_per_batch.append(loss.cpu().data.numpy());  # Training loss
                        loss_val += loss.cpu().data.numpy()

                        """ Calculate jaccard on GPU """
                        jacc = jacc_eval_GPU_torch(output_val, labels_val)
                        jacc = jacc.cpu().data.numpy()

                        jacc_val += jacc
                        tracker.val_jacc_per_batch.append(jacc)

                        """ Convert back to cpu """
                        output_val = output_val.cpu().data.numpy()
                        output_val = np.moveaxis(output_val, 1, -1)

                        """ Calculate # of TP, FP, FN, TN for every image in the batch"""
                        batch_y_val = batch_y_val.cpu().data.numpy()
                        labels_val = labels_val.cpu().data.numpy()
                        for b_idx in range(len(batch_y_val)):

                            # get image from current batch
                            seg_val = np.argmax(output_val[b_idx], axis=-1)
                            cur_label = labels_val[b_idx]

                            ### (1) If is TN or FN, the seg_val is blank
                            if not np.count_nonzero(seg_val):

                                ### It is a true negative if the seg_val is ALSO blank
                                if not np.count_nonzero(cur_label):
                                   total_TNs += 1

                                else:
                                   ### otherwise, calculate number of FN's
                                   # seg_val[seg_val > 0] = 1
                                   # labelled = measure.label(seg_val)
                                   # cc_coloc = measure.regionprops(labelled)

                                   total_FNs += 1

                            else:
                                ### (2) otherwise, test for TP and FP
                                only_coloc, TP, FP = find_overlap_objs(cur_label, seg_val)

                                total_TPs += TP
                                total_FPs += FP

                        #zzz
                        val_idx = val_idx + tracker.batch_size
                        print('Validation: ' + str(val_idx) + ' of total: ' + str(validation_size))
                        iter_cur_epoch += 1

              accuracy = (total_TPs + total_TNs)/(total_TPs + total_TNs + total_FPs + total_FNs)
              sensitivity = total_TPs/(total_TPs + total_FNs);
              precision = total_TPs/(total_TPs + total_FPs);

              tracker.val_loss_per_eval.append(loss_val/iter_cur_epoch)
              tracker.val_jacc_per_eval.append(jacc_val/iter_cur_epoch)

              tracker.plot_prec.append(precision)
              tracker.plot_sens.append(sensitivity)

              tracker.plot_acc.append(accuracy)

              """ Add to scheduler to do LR decay """
              scheduler.step()

         """ calculate new alpha for next epoch """
         if tracker.HD:
            tracker.alpha = alpha_step(ce_train, dc_train, hd_train, iter_cur_epoch)

         if cur_epoch % plot_every_num_epochs == 0:

              """ Plot sens + precision + jaccard + loss """
              plot_metric_fun(tracker.plot_acc, tracker.plot_acc, class_name='', metric_name='accuracy', plot_num=29)
              plt.figure(29); plt.savefig(s_path + 'Accuracy.png')

              plot_metric_fun(tracker.plot_sens, tracker.plot_sens_val, class_name='', metric_name='sensitivity', plot_num=30)
              plt.figure(30); plt.savefig(s_path + 'Sensitivity.png')

              plot_metric_fun(tracker.plot_prec, tracker.plot_prec_val, class_name='', metric_name='precision', plot_num=31)
              plt.figure(31); plt.savefig(s_path + 'Precision.png')

              plot_metric_fun(tracker.train_jacc_per_epoch, tracker.val_jacc_per_eval, class_name='', metric_name='jaccard', plot_num=32)
              plt.figure(32); plt.savefig(s_path + 'Jaccard.png')

              plot_metric_fun(tracker.train_loss_per_epoch, tracker.val_loss_per_eval, class_name='', metric_name='loss', plot_num=33)
              plt.figure(33); plt.yscale('log'); plt.savefig(s_path + 'loss_per_epoch.png')

              plot_metric_fun(tracker.lr_plot, [], class_name='', metric_name='learning rate', plot_num=35)
              plt.figure(35); plt.savefig(s_path + 'lr_per_epoch.png')

              """ Plot metrics per batch """
              plot_metric_fun(tracker.train_jacc_per_batch, [], class_name='', metric_name='jaccard', plot_num=34)
              plt.figure(34); plt.savefig(s_path + 'Jaccard_per_batch.png')

              plot_cost_fun(tracker.train_loss_per_batch, tracker.train_loss_per_batch)
              plt.figure(18); plt.savefig(s_path + 'global_loss.png')
              plt.figure(19); plt.savefig(s_path + 'detailed_loss.png')
              plt.figure(25); plt.savefig(s_path + 'global_loss_LOG.png')
              plt.close('all')

              plot_depth = 8
              output_train = output_train.cpu().data.numpy()
              output_train = np.moveaxis(output_train, 1, -1)
              seg_train = np.argmax(output_train[0], axis=-1)

              # convert back to CPU
              batch_x = batch_x.cpu().data.numpy()
              batch_y = batch_y.cpu().data.numpy()
              batch_x_val = batch_x_val.cpu().data.numpy()

              seg_val = np.argmax(output_val[0], axis=-1)

              plot_trainer_3D_PYTORCH_cell_track_AUTO(seg_train, seg_val, batch_x[0, 0:2, ...], batch_x_val[0, 0:2, ...], batch_y[0], batch_y_val[0],
                                       s_path, tracker.iterations, plot_depth=plot_depth)

         """ To save (every x iterations) """
         if cur_epoch % save_every_num_epochs == 0:

               save_name = s_path + 'check_' +  str(tracker.iterations)
               torch.save({
                'tracker': tracker,

                'model_type': unet,
                'optimizer_type': optimizer,
                'scheduler_type': scheduler,

                'model_state_dict': unet.state_dict(),
                'optimizer_state_dict': optimizer.state_dict(),
                'scheduler': scheduler.state_dict(),
                'loss_function': loss_function,

                }, save_name)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import dash
import dash_core_components as dcc
import dash_html_components as html
import networkx as nx
import plotly.graph_objs as go

import pandas as pd
from colour import Color
from datetime import datetime
from textwrap import dedent as d
import json

# import the css template, and pass the css template into dash
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.title = "Transaction Network"

YEAR=[2010, 2019]
ACCOUNT="A0001"

##############################################################################################################################################################
def network_graph(yearRange, AccountToSearch):
    G = nx.random_geometric_graph(200, 0.125)
    edge_x = []
    edge_y = []
    for edge in G.edges():
        x0, y0 = G.nodes[edge[0]]['pos']
        x1, y1 = G.nodes[edge[1]]['pos']
        edge_x.append(x0)
        edge_x.append(x1)
        edge_x.append(None)
        edge_y.append(y0)
        edge_y.append(y1)
        edge_y.append(None)

    edge_trace = go.Scatter(
        x=edge_x, y=edge_y,
        line=dict(width=0.5, color='#888'),
        hoverinfo='none',
        mode='lines')

    node_x = []
    node_y = []
    for node in G.nodes():
        x, y = G.nodes[node]['pos']
        node_x.append(x)
        node_y.append(y)

    node_trace = go.Scatter(
        x=node_x, y=node_y,
        mode='markers',
        hoverinfo='text',
        marker=dict(
            showscale=True,
            # colorscale options
            #'Greys' | 'YlGnBu' | 'Greens' | 'YlOrRd' | 'Bluered' | 'RdBu' |
            #'Reds' | 'Blues' | 'Picnic' | 'Rainbow' | 'Portland' | 'Jet' |
            #'Hot' | 'Blackbody' | 'Earth' | 'Electric' | 'Viridis' |
            colorscale='YlGnBu',
            reversescale=True,
            color=[],
            size=10,
            colorbar=dict(
                thickness=15,
                title='Node Connections',
                xanchor='left',
                titleside='right'
            ),
            line_width=2))
    figure = go.Figure(data=[edge_trace, node_trace],
             layout=go.Layout(
                title='
Network graph made with Python',
#                 titlefont_size=16,
                showlegend=False,
                hovermode='closest',
                margin=dict(b=20,l=5,r=5,t=40),
                annotations=[ dict(
                    text="Python code:  https://plot.ly/ipython-notebooks/network-graphs/",
                    showarrow=False,
                    xref="paper", yref="paper",
                    x=0.005, y=-0.002 ) ],
                xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
                yaxis=dict(showgrid=False, zeroline=False, showticklabels=False))
                )
    return figure
######################################################################################################################################################################
# styles: for right side hover/click component
styles = {
    'pre': {
        'border': 'thin lightgrey solid',
        'overflowX': 'scroll'
    }
}

app.layout = html.Div([
    #########################Title
    html.Div([html.H1("Transaction Network Graph")],
             className="row",
             style={'textAlign': "center"}),
    #############################################################################################define the row
    html.Div(
        className="row",
        children=[
            ##############################################left side two input components
            html.Div(
                className="two columns",
                children=[
                    dcc.Markdown(d("""
                            **Time Range To Visualize**

                            Slide the bar to define year range.
                            """)),
                    html.Div(
                        className="twelve columns",
                        children=[
                            dcc.RangeSlider(
                                id='my-range-slider',
                                min=2010,
                                max=2019,
                                step=1,
                                value=[2010, 2019],
                                marks={
                                    2010: {'label': '2010'},
                                    2011: {'label': '2011'},
                                    2012: {'label': '2012'},
                                    2013: {'label': '2013'},
                                    2014: {'label': '2014'},
                                    2015: {'label': '2015'},
                                    2016: {'label': '2016'},
                                    2017: {'label': '2017'},
                                    2018: {'label': '2018'},
                                    2019: {'label': '2019'}
                                }
                            ),
                            html.Br(),
                            html.Div(id='output-container-range-slider')
                        ],
                        style={'height': '300px'}
                    ),
                    html.Div(
                        className="twelve columns",
                        children=[
                            dcc.Markdown(d("""
                            **Account To Search**

                            Input the account to visualize.
                            """)),
                            dcc.Input(id="input1", type="text", placeholder="Account"),
                            html.Div(id="output")
                        ],
                        style={'height': '300px'}
                    )
                ]
            ),

            ############################################middle graph component
            html.Div(
                className="eight columns",
                children=[dcc.Graph(id="my-graph",
                                    figure=network_graph(YEAR, ACCOUNT))],
            ),

            #########################################right side two output component
            html.Div(
                className="two columns",
                children=[
                    html.Div(
                        className='twelve columns',
                        children=[
                            dcc.Markdown(d("""
                            **Hover Data**

                            Mouse over values in the graph.
                            """)),
                            html.Pre(id='hover-data', style=styles['pre'])
                        ],
                        style={'height': '400px'}),

                    html.Div(
                        className='twelve columns',
                        children=[
                            dcc.Markdown(d("""
                            **Click Data**

                            Click on points in the graph.
                            """)),
                            html.Pre(id='click-data', style=styles['pre'])
                        ],
                        style={'height': '400px'})
                ]
            )
        ]
    )
])

###################################callback for left side components
@app.callback(
    dash.dependencies.Output('my-graph', 'figure'),
    [dash.dependencies.Input('my-range-slider', 'value'), dash.dependencies.Input('input1', 'value')])
def update_output(value,input1):
    YEAR = value
    ACCOUNT = input1
    return network_graph(value, input1)
    # to update the global variable of YEAR and ACCOUNT
################################callback for right side components
@app.callback(
    dash.dependencies.Output('hover-data', 'children'),
    [dash.dependencies.Input('my-graph', 'hoverData')])
def display_hover_data(hoverData):
    return json.dumps(hoverData, indent=2)

@app.callback(
    dash.dependencies.Output('click-data', 'children'),
    [dash.dependencies.Input('my-graph', 'clickData')])
def display_click_data(clickData):
    return json.dumps(clickData, indent=2)

if __name__ == '__main__':
    app.run_server(debug=True)


import heapq
from collections import defaultdict

n, m = map(int, input().split())
c = [0] * (n + 1)
g = defaultdict(set)
for _ in range(m):
    a, b = map(int, input().split())
    if b not in g[a]:
        g[a].add(b)
        c[b] += 1

q = []
for i in range(1, n + 1):
    if c[i] == 0:
        heapq.heappush(q, i)

s = []
while q:
    x = heapq.heappop(q)
    s.append(x)
    for y in g[x]:
        if c[y] == 0:
            continue
        c[y] -= 1
        if c[y] == 0:
            heapq.heappush(q, y)

if sum(c) == 0:
    print(' '.join(map(str, s)))
else:
    print('-1')


import ast
from typing import Any, Generator, List, Tuple, Type

MSG = "UTC001 don't use datetime.utcnow(), use datetime.now(timezone.utc) instead"  # noqa: E501

class Visitor(ast.NodeVisitor):
    def __init__(self) -> None:
        self.assignments: List[Tuple[int, int]] = []

    def visit_Call(self, node: ast.Call) -> None:
        if isinstance(node.func, ast.Name) and node.func.id == "utcnow":
            self.assignments.append((node.lineno, node.col_offset))

        self.generic_visit(node)

    def visit_Attribute(self, node: ast.Attribute) -> None:
        if (
            isinstance(node.value, ast.Attribute)
            and node.attr == "utcnow"
            and node.value.attr == "datetime"
        ) or (
            isinstance(node.value, ast.Name)
            and node.attr == "utcnow"
            and node.value.id == "datetime"
        ):
            self.assignments.append((node.lineno, node.col_offset))

        self.generic_visit(node)

class Plugin:
    name = "Ban utcnow()"
    version = "0.2.0"

    def __init__(self, tree: ast.AST):
        self._tree = tree

    def run(self) -> Generator[Tuple[int, int, str, Type[Any]], None, None]:
        visitor = Visitor()
        visitor.visit(self._tree)
        for line, col in visitor.assignments:
            yield line, col, MSG, type(self)


from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
import sys
import UI
import cv2
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
import math
from numpy.fft import fft2, ifft2
import pickle
import torch
import torch.nn as nn
import pandas as pd
import random
from torchvision import models
import tqdm
from torch.utils.data import DataLoader
import torchvision.transforms as transforms
import torchvision
import include
import os
from torch.utils.tensorboard import SummaryWriter

class ExampleApp(QtWidgets.QMainWindow, UI.Ui_MainWindow):
    def __init__(self, parent=None):
        super(ExampleApp, self).__init__(parent)
        self.setupUi(self)
        self.load_button.clicked.connect(self.click_load_Button)
        self.seperate_button.clicked.connect(self.click_seperate_Button)
        self.flip_buuton.clicked.connect(self.click_flip_Button)
        self.blend_button.clicked.connect(self.click_blend_Button)
        #filter
        self.median_Button.clicked.connect(self.click_median_Button)
        self.gaussian_Button.clicked.connect(self.click_gaussian_Button)
        self.bilateral_Button.clicked.connect(self.click_bilateral_Button)
        #edge detection
        self.guassian_gray_Button.clicked.connect(self.click_guassian_gray_Button)
        self.sobelx_Button.clicked.connect(self.click_sobelx_Button)
        self.sobely_Button.clicked.connect(self.click_sobely_Button)
        self.magnitude_Button.clicked.connect(self.click_sobel_Button)
        self.ok_Button.clicked.connect(self.click_ok_Button)
        self.cancel_Button.clicked.connect(self.click_cancel_Button)
        #transformation
        self.transformation_Button.clicked.connect(self.click_transformation_Button)
        #define default image
        self.array = np.zeros(10)
        #show image
        self.showimages_Button.clicked.connect(self.click_showimages_Button)
        self.showparameters_Button.clicked.connect(self.click_showparameters_Button)
        self.showmodel_Button.clicked.connect(self.click_showmodel_Button)
        self.showaccuracy_Button.clicked.connect(self.click_showaccuracy_Button)
        self.test_Button.clicked.connect(self.click_test_Button)
        self.inference_pushButton.clicked.connect(self.click_inference_Button)

    def unpickle(self, file):
        with open(file, 'rb') as fo:
            d = pickle.load(fo, encoding='bytes')
        return d

    def convert_image(self, raw_image):
        np.set_printoptions(threshold=sys.maxsize)
        raw = np.array(raw_image, dtype=float)/255.0
        images = raw.reshape([-1, 3, 32, 32])
        images = images.transpose([0, 2, 3, 1])

        return images

    def load_data(self):
        print("load data")
        transform = transforms.Compose(
        [transforms.ToTensor(),
        transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

        self.trainset = torchvision.datasets.CIFAR10(root='./data', train=True,
                                        download=True, transform=transform)

        self.testset = torchvision.datasets.CIFAR10(root='./data', train=False,
                                            download=True, transform=transform)

        self.classes = ('plane', 'car', 'bird', 'cat',
           'deer', 'dog', 'frog', 'horse', 'ship', 'truck')

    def click_showimages_Button(self):
        print("click_showimages_Button")
        self.load_data()
        trainloader = torch.utils.data.DataLoader(self.trainset, batch_size=10,
                                                shuffle=True, num_workers=2)

        def imshow(img, labels):
            img = img / 2 + 0.5     # unnormalize
            npimg = img.numpy()
            plt.imshow(np.transpose(npimg, (1, 2, 0)))
            # plt.text((0.0), labels)
            s = ""
            for i in labels:
                s += self.classes[i]+"     "
            plt.text(x=0, y=0, s=s)
            plt.show()
        # get some random training images
        dataiter = iter(trainloader)

        images, labels = dataiter.next()

        # show images
        imshow(torchvision.utils.make_grid(images, nrow=10), labels)

    def click_showparameters_Button(self):
        print("click_showparameters_Button")
        self.batch_size = 32
        self.lr = 0.0001
        self.optimizer = "Adam"
        self.epoch = 30
        print("Hyperparameters:")
        print("batch size:", self.batch_size)
        print("learngin rate", self.lr)
        print("optimizer", self.optimizer)
        print("epoch", self.epoch)

    def click_showmodel_Button(self):
        print("click_showmodel_Button")
        self.model = models.vgg16()
        self.model.classifier._modules['6'] = nn.Linear(in_features=4096, out_features=10, bias=True)

        print(self.model)

    def click_showaccuracy_Button(self):
        print("click_showaccuracy_Button")
        self.load_data()
        self.click_showparameters_Button()
        trainloader = torch.utils.data.DataLoader(self.trainset, batch_size=32,
                                          shuffle=True, num_workers=2)

        acc = include.train(trainloader, self.batch_size, self.lr, self.optimizer, self.epoch)
        self.Accuracy_Box.setValue(acc)

    def click_test_Button(self):
        print("click_test_Button")

    def click_inference_Button(self):
        print("click inference Button")
        choose_index = int(self.choose_index.toPlainText())
        print(choose_index)
        self.load_data()
        model = models.vgg16()
        model.classifier._modules['6'] = nn.Linear(in_features=4096, out_features=10, bias=True)

        model.load_state_dict(torch.load(os.path.join(os.path.dirname(os.path.abspath(__file__)),f'data/vgg16.pth')))
        model.eval()
        f = plt.figure()
        def imshow(img):
            img = img / 2 + 0.5     # unnormalize
            npimg = img.numpy()

            plt.imshow(np.transpose(npimg, (1, 2, 0)))
            f.show()

        # get some random training images
        images = self.testset[choose_index][0]

        # show images
        imshow(torchvision.utils.make_grid(images))
        output = model(self.testset[choose_index][0].unsqueeze(0))

        _, predict = torch.max(output.data, 1)

        # print(self.classes[predict])
        sm = torch.nn.Softmax()
        probabilities = sm(output)
        print(self.classes[predict])
        x = np.asarray(self.classes)
        n = plt.figure()
        plt.bar(x, probabilities.detach().numpy()[0])
        n.show()

    def click_transformation_Button(self):
        print("click_transformation_Button")
        self.img_parrot = cv2.imread('Dataset_opencvdl/Q4_Image/Parrot.png')
        # cv2.imshow("cool", self.img_parrot)
        width = self.img_parrot.shape[1]
        height = self.img_parrot.shape[0]
        print(self.img_parrot.shape)
        rotate = float(self.rotation_text.toPlainText())
        tx = float(self.tx_text.toPlainText())
        ty = float(self.ty_text.toPlainText())
        scale = float(self.scaling_text.toPlainText())
        square = np.float32([[1, 0, tx], [0, 1,  ty]])
        rot_mat = cv2.getRotationMatrix2D(tuple([width/2, height/2]), rotate, 1.0)
        move_parrot = cv2.warpAffine(self.img_parrot,square,(width,height))
        move_parrot = cv2.warpAffine(move_parrot,rot_mat,(width,height))
        move_parrot = cv2.resize(move_parrot,(int(scale*width),int(scale*height)),interpolation=cv2.INTER_CUBIC)
        cv2.imshow("Parrot image", move_parrot)

    def click_load_Button(self):
        print("click_load_Button")
        self.img_uncle = cv2.imread('Dataset_opencvdl/Q1_Image/Uncle_Roger.jpg')
        print("height", self.img_uncle.shape[0])
        print("width", self.img_uncle.shape[1])
        cv2.imshow("Uncle_Roger" , self.img_uncle)

    def click_seperate_Button(self):
        print("click_seperate_Button")
        self.img_flower = cv2.imread('Dataset_opencvdl/Q1_Image/Flower.jpg')
        print("height", self.img_flower.shape[0])
        print("width", self.img_flower.shape[1])
        print(self.img_flower.shape)
        cv2.imshow("original image", self.img_flower)
        b = self.img_flower.copy()
        # set green and red channels to 0
        b[:, :, 1] = 0
        b[:, :, 2] = 0
        cv2.imshow("blue image", b)
        g = self.img_flower.copy()
        # set blue and red channels to 0
        g[:, :, 0] = 0
        g[:, :, 2] = 0
        cv2.imshow("green image", g)

        r = self.img_flower.copy()
        # set blue and green channels to 0
        r[:, :, 0] = 0
        r[:, :, 1] = 0
        cv2.imshow("red image", r)

    def click_flip_Button(self):
        print("click_flip_Button")
        # img_uncle = cv2.imread('Dataset_opencvdl/Q1_Image/Uncle_Roger.jpg')
        # cv2.imshow("Uncle_Roger", self.img_uncle)
        self.img_uncle = cv2.imread('Dataset_opencvdl/Q1_Image/Uncle_Roger.jpg')
        self.img_uncle_flip = cv2.flip(self.img_uncle, 1)
        cv2.imshow("flipping image", self.img_uncle_flip)

    def Change_blend(self, x):
        # get current positions of four trackbars
        ra = x/255
        self.img_uncle_blend = cv2.addWeighted(self.img_uncle_flip, ra, self.img_uncle, 1-ra, 0.0)

        cv2.imshow('blending_image',self.img_uncle_blend)

    def click_blend_Button(self):
        print("click_blend_Button")
        self.img_uncle = cv2.imread('Dataset_opencvdl/Q1_Image/Uncle_Roger.jpg')
        self.img_uncle_flip = cv2.flip(self.img_uncle, 1)
        # self.img_uncle_blend = cv2.addWeighted(self.img_uncle_flip, 0.5, self.img_uncle, 0.5, 0.0)
        # cv2.imshow("blending image", self.img_uncle_blend)

        width = self.img_uncle.shape[0]
        height = self.img_uncle.shape[1]
        cv2.namedWindow("blending_image",  cv2.WINDOW_NORMAL)
        cv2.resizeWindow("blending_image", int(width+500), int(height+500));

        cv2.createTrackbar('trackbar_number','blending_image',0,255,self.Change_blend)

    def click_median_Button(self):
        print("click_median_Button")
        self.img_cat = cv2.imread('Dataset_opencvdl/Q2_Image/Cat.png')
        self.img_mblur_cat = cv2.medianBlur(self.img_cat, 7)
        cv2.imshow("median blur image", self.img_mblur_cat)

    def click_gaussian_Button(self):
        print("click_gaussian_Button")
        self.img_cat = cv2.imread('Dataset_opencvdl/Q2_Image/Cat.png')
        self.img_gblur_cat = cv2.GaussianBlur(self.img_cat,(3, 3), 1)
        cv2.imshow("gaussian blur image", self.img_gblur_cat)

    def click_bilateral_Button(self):
        print("click_bilateral_Button")
        self.img_cat = cv2.imread('Dataset_opencvdl/Q2_Image/Cat.png')
        self.img_bblur_cat = cv2.bilateralFilter(self.img_cat,9,90,90)
        cv2.imshow("bilateral blur image ", self.img_bblur_cat)

    def guassian_keranl(self):
        #3*3 Gassian filter
        x, y = np.mgrid[-1:2, -1:2]
        gk = np.exp(-(x**2+y**2))

        #Normalization
        gk = gk / gk.sum()

        return gk

    def click_guassian_gray_Button(self):
        print("click_guassian_gray_Button")
        self.img_chihiro = cv2.imread('Dataset_opencvdl/Q3_Image/Chihiro.jpg')
        self.img_chihiro = cv2.cvtColor(self.img_chihiro,cv2.COLOR_RGB2GRAY)
        gk = self.guassian_keranl()
        self.grad = self.convolution2d(self.img_chihiro, gk)
        self.array = self.grad

    def convolution2d(self, image, kernel):
        m, n = kernel.shape
        if (m == n):
            y, x = image.shape
            y = y - m + 1
            x = x - m + 1
            new_image = np.zeros((y,x))
            for i in range(y):
                for j in range(x):
                    new_image[i][j] = np.sum(image[i:i+m, j:j+m]*kernel)
        else:
            new_image = np.zeros((y, x))
        return new_image

    def click_sobelx_Button(self):
        self.click_guassian_gray_Button()
        self.fsx = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]])
        self.sobelx = self.convolution2d(self.grad, self.fsx)
        self.solidx = cv2.normalize(self.sobelx, 0, 255, cv2.NORM_MINMAX)
        self.array = np.array(self.solidx, np.uint8)

    def click_sobely_Button(self):
        self.click_guassian_gray_Button()
        self.fsy = np.array([[1, 2, 1], [0, 0, 0], [-1, -2, -1]])
        self.sobely = self.convolution2d(self.grad, self.fsy)
        self.solidy = cv2.normalize(self.sobely, 0, 255, cv2.NORM_MINMAX)
        self.array = np.array(self.solidy, np.uint8)

    def click_sobel_Button(self):
        print("click_sobel_Button")
        self.click_sobely_Button()
        self.click_sobelx_Button()
        self.sobel = np.sqrt(np.fabs(np.add(np.square(self.sobelx),np.square(self.sobely))))
        # self.sobel = cv2.normalize(self.sobel, 0, 255, cv2.NORM_MINMAX)
        self.array = np.array(self.sobel, np.uint8)

    def click_ok_Button(self):
        print("click_ok_Button")
        self.img = Image.fromarray(self.array)
        self.img.show()

    def click_cancel_Button(self):
        print("click_cancel_Button")
        self.img.close()

def main():
    app = QApplication(sys.argv)
    form = ExampleApp()

    form.show()
    app.exec_()

if __name__ == '__main__':
    main()


from django.shortcuts import render
from django.http.response import HttpResponse
from django.template.loader import get_template
from django.template import Context
from django.db.models import Q
from django.shortcuts import render_to_response
from educational_institution.models import Educational_institution, Type_of_payment_for_education, City,\
    Educational_direction, Student, Educational_method, Faculty, Educational_institution_type

# Create your views here.

def home(request):
    return render_to_response('home.html', {})

def cities(request):
    query = request.GET.get("q")
    if query:
        city_list = City.objects.filter(
            Q(city_name__icontains=query) |
            Q(population__icontains=query)
        )
    else:
        city_list = City.objects.all
    return render_to_response('cities.html', {'cities': city_list, 'request': request})

def city(request, city_id=1):
    return render_to_response('city.html', {'city': City.objects.get(id=city_id)})

def educational_institution_types(request):
    query = request.GET.get("q")
    if query:
        educational_institution_type_list = Educational_institution_type.objects.filter(
            Q(educational_institution_type__icontains=query)
        )
    else:
        educational_institution_type_list = Educational_institution_type.objects.all
    return render_to_response('educational_institution_types.html',
                              {'educational_institution_types': educational_institution_type_list, 'request': request})

def educational_institution_type(request, educational_institution_type_id=1):
    return render_to_response('educational_institution_type.html',
                              {'educational_institution_type': Educational_institution_type.objects.get(id=educational_institution_type_id)})

def educational_directions(request):
    query = request.GET.get("q")
    if query:
        educational_direction_list = Educational_direction.objects.filter(
            Q(educational_direction_name__icontains=query)
        )
    else:
        educational_direction_list = Educational_direction.objects.all
    return render_to_response('educational_directions.html',
                              {'educational_directions': educational_direction_list, 'request': request})

def educational_direction(request, educational_direction_id=1):
    return render_to_response('educational_direction.html',
                              {'educational_direction': Educational_direction.objects.get(id=educational_direction_id)})

def educational_methods(request):
    query = request.GET.get("q")
    if query:
        educational_method_list = Educational_method.objects.filter(
            Q(educational_method_name__icontains=query)
        )
    else:
        educational_method_list = Educational_method.objects.all
    return render_to_response('educational_methods.html',
                              {'educational_methods': educational_method_list, 'request': request})

def educational_method(request, educational_method_id=1):
    return render_to_response('educational_method.html',
                              {'educational_method': Educational_method.objects.get(id=educational_method_id)})

def faculties(request):
    query = request.GET.get("q")
    if query:
        faculty_list = Faculty.objects.filter(
            Q(faculty_name__icontains=query)
        )
    else:
        faculty_list = Faculty.objects.all
    return render_to_response('faculties.html', {'faculties': faculty_list, 'request': request})

def faculty(request, faculty_id=1):
    return render_to_response('faculty.html', {'faculty': Faculty.objects.get(id=faculty_id)})

def payment_types(request):
    query = request.GET.get("q")
    if query:
        type_of_payment_for_education_list = Type_of_payment_for_education.objects.filter(
            Q(type_of_payment_for_education__icontains=query)
        )
    else:
        type_of_payment_for_education_list = Type_of_payment_for_education.objects.all
    return render_to_response('payment_types.html', {'payment_types': type_of_payment_for_education_list, 'request': request})

def payment_type(request, payment_type_id=1):
    return render_to_response('payment_type.html',
                              {'payment_type': Type_of_payment_for_education.objects.get(id=payment_type_id)})

def students(request):
    query = request.GET.get("q")
    if query:
        student_list = Student.objects.filter(
            Q(student_name__icontains=query)
        )
    else:
        student_list = Student.objects.all
    return render_to_response('students.html', {'students': student_list, 'request': request})

def student(request, student_id=1):
    return render_to_response('student.html', {'student': Student.objects.get(id=student_id)})

def educational_institutions(request):
    query = request.GET.get("q")
    if query:
        educational_institution_list = Educational_institution.objects.filter(
            Q(educational_institution_name__icontains=query)|
            Q(city__city_name__icontains=query)
        )
    else:
        educational_institution_list = Educational_institution.objects.all
    return render_to_response('educational_institutions.html',
                              {'educational_institutions': educational_institution_list, 'request': request})

def educational_institution(request, educational_institution_id=1):
    return render_to_response('educational_institution.html',
                              {'educational_institution': Educational_institution.objects.get(id=educational_institution_id)})


import logging
import unittest

import dbldatagen as dg

spark = dg.SparkSingleton.getLocalInstance("unit tests")

class TestRanges(unittest.TestCase):
    testDataSpec = None
    dfTestData = None
    row_count = 100000
    column_count = 50

    def setUp(self):
        print("setting up")
        FORMAT = '%(asctime)-15s %(message)s'
        logging.basicConfig(format=FORMAT)

    @classmethod
    def setUpClass(cls):
        pass

    def test_numeric_range1(self):
        r1 = dg.NRange(1, 20, 1)

        self.assertEqual(r1.getDiscreteRange(), 19)
        print(r1.getDiscreteRange())

    def test_numeric_range2(self):
        r1 = dg.NRange(1.5, 2.5, 0.35)

        print(r1.getDiscreteRange())
        self.assertEqual(r1.getDiscreteRange(), 2.0)

        self.assertEqual(r1.getScale(), 2)

    def test_numeric_range3(self):
        r1 = dg.NRange(1.5, 2.5, 0.5)

        print(r1.getDiscreteRange())

    def test_numeric_range4(self):
        r1 = dg.NRange(0, 4, 0.5)
        self.assertEqual(r1.getDiscreteRange(), 8.0)

        print(r1.getDiscreteRange())

    def test_optional_min_max(self):

        r1 = dg.NRange(-1, 100)

        self.assertEqual(r1.minValue, -1)
        self.assertEqual(r1.maxValue, 100)

        r2 = dg.NRange(min=-1, max=100)

        self.assertEqual(r2.minValue, -1)
        self.assertEqual(r2.maxValue, 100)

        r3 = dg.NRange(minValue=-1, maxValue=100)

        self.assertEqual(r3.minValue, -1)
        self.assertEqual(r3.maxValue, 100)

# run the tests
# if __name__ == '__main__':
#  print("Trying to run tests")
#  unittest.main(argv=['first-arg-is-ignored'],verbosity=2,exit=False)

# def runTests(suites):
#    suite = unittest.TestSuite()
#    result = unittest.TestResult()
#    for testSuite in suites:
#        suite.addTest(unittest.makeSuite(testSuite))
#    runner = unittest.TextTestRunner()
#    print(runner.run(suite))

# runTests([TestBasicOperation])

if __name__ == '__main__':
    unittest.main()