'''
Chatty NPC example
'''

import sys
import pygame

pygame.init()

SCREEN_WIDTH = 500
SCREEN_HEIGHT = 500
FPS = 60

RED = [150, 0, 0]
LIGHT_GREY = [230, 230, 230]
BLACK = [0, 0, 0]
BLUE = [0, 0, 150]
ORANGE = [245, 180, 65]

screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])
pygame.display.set_caption("Chatty NPC")

clock = pygame.time.Clock()

font = pygame.font.SysFont('impact', 18)

NPC_WIDTH = 25
NPC_HEIGHT = 25
NPC_X = int(0.75 * SCREEN_WIDTH)
NPC_Y = int(0.5 * SCREEN_HEIGHT)
NPC_INTERACT_RANGE = 10 # How many pixels away from the NPC can you interact with it?
best_bud = {"rect":             pygame.Rect([NPC_X, NPC_Y], [NPC_WIDTH, NPC_HEIGHT]),
            "interaction_rect": pygame.Rect([NPC_X - NPC_INTERACT_RANGE, NPC_Y - NPC_INTERACT_RANGE], [NPC_WIDTH + (2*NPC_INTERACT_RANGE), NPC_HEIGHT + (2*NPC_INTERACT_RANGE)]),
            "can_interact":     False,
            "talkietalkie":     "Hi there my good friend!",
            "text_visible":      False}

CHAR_START_X = 0
CHAR_START_Y = 0
CHAR_WIDTH = 15
CHAR_HEIGHT = 15
CHAR_SPEED = 5
character = pygame.Rect([CHAR_START_X, CHAR_START_Y], [CHAR_WIDTH, CHAR_HEIGHT])

while True:
    screen.fill(LIGHT_GREY)

    # Update character
    pressed_keys = pygame.key.get_pressed()
    cur_char_vel = [0, 0]
    # - vertical movement
    if pressed_keys[pygame.K_w]:
        cur_char_vel[1] = -1*CHAR_SPEED
    elif pressed_keys[pygame.K_s]:
        cur_char_vel[1] = CHAR_SPEED
    # - horizontal movement
    if pressed_keys[pygame.K_d]:
        cur_char_vel[0] = CHAR_SPEED
    elif pressed_keys[pygame.K_a]:
        cur_char_vel[0] = -1*CHAR_SPEED
    character.left += cur_char_vel[0]
    character.top += cur_char_vel[1]

    # Is the character in range to interact with the NPC?
    if character.colliderect(best_bud["interaction_rect"]):
        best_bud["can_interact"] = True
    else:
        best_bud["can_interact"] = False
        best_bud["text_visible"] = False

    ############################################################################
    # DRAWING
    ############################################################################

    # Draw our best bud
    # pygame.draw.rect(screen, BLACK, best_bud["interaction_rect"])
    pygame.draw.rect(screen, RED, best_bud["rect"])

    pygame.draw.rect(screen, BLUE, character)

    if best_bud["text_visible"]:
        # Text should be visible!
        text_surf = font.render(best_bud["talkietalkie"], True, BLACK)
        text_box = text_surf.get_rect()
        text_box.centerx = best_bud["rect"].centerx
        text_box.y = best_bud["rect"].y - text_box.height - 5
        pygame.draw.rect(screen, ORANGE, text_box)
        pygame.draw.rect(screen, ORANGE, text_box, 3)
        screen.blit(text_surf, text_box)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_e:
                if best_bud["can_interact"]:
                    best_bud["text_visible"] = not best_bud["text_visible"]

    pygame.display.update()
    clock.tick(FPS)


from .ExcitationSystemDynamics import ExcitationSystemDynamics

class ExcAC6A(ExcitationSystemDynamics):
	'''
	Modified IEEE AC6A alternator-supplied rectifier excitation system with speed input.

	:ka: Voltage regulator gain (Ka).  Typical Value = 536. Default: 0.0
	:ks: Coefficient to allow different usage of the model-speed coefficient (Ks).  Typical Value = 0. Default: 0.0
	:ta: Voltage regulator time constant (Ta).  Typical Value = 0.086. Default: 0
	:tk: Voltage regulator time constant (Tk).  Typical Value = 0.18. Default: 0
	:tb: Voltage regulator time constant (Tb).  Typical Value = 9. Default: 0
	:tc: Voltage regulator time constant (Tc).  Typical Value = 3. Default: 0
	:vamax: Maximum voltage regulator output (Vamax).  Typical Value = 75. Default: 0.0
	:vamin: Minimum voltage regulator output (Vamin).  Typical Value = -75. Default: 0.0
	:vrmax: Maximum voltage regulator output (Vrmax).  Typical Value = 44. Default: 0.0
	:vrmin: Minimum voltage regulator output (Vrmin).  Typical Value = -36. Default: 0.0
	:te: Exciter time constant, integration rate associated with exciter control (Te).  Typical Value = 1. Default: 0
	:kh: Exciter field current limiter gain (Kh).  Typical Value = 92. Default: 0.0
	:tj: Exciter field current limiter time constant (Tj).  Typical Value = 0.02. Default: 0
	:th: Exciter field current limiter time constant (Th).  Typical Value = 0.08. Default: 0
	:vfelim: Exciter field current limit reference (Vfelim).  Typical Value = 19. Default: 0.0
	:vhmax: Maximum field current limiter signal reference (Vhmax).  Typical Value = 75. Default: 0.0
	:kc: Rectifier loading factor proportional to commutating reactance (Kc).  Typical Value = 0.173. Default: 0.0
	:kd: Demagnetizing factor, a function of exciter alternator reactances (Kd).  Typical Value = 1.91. Default: 0.0
	:ke: Exciter constant related to self-excited field (Ke).  Typical Value = 1.6. Default: 0.0
	:ve1: Exciter alternator output voltages back of commutating reactance at which saturation is defined (Ve).  Typical Value = 7.4. Default: 0.0
	:seve1: Exciter saturation function value at the corresponding exciter voltage, Ve1, back of commutating reactance (Se[Ve1]).  Typical Value = 0.214. Default: 0.0
	:ve2: Exciter alternator output voltages back of commutating reactance at which saturation is defined (Ve2).  Typical Value = 5.55. Default: 0.0
	:seve2: Exciter saturation function value at the corresponding exciter voltage, Ve2, back of commutating reactance (Se[Ve2]).  Typical Value = 0.044. Default: 0.0
		'''

	cgmesProfile = ExcitationSystemDynamics.cgmesProfile

	possibleProfileList = {'class': [cgmesProfile.DY.value, ],
						'ka': [cgmesProfile.DY.value, ],
						'ks': [cgmesProfile.DY.value, ],
						'ta': [cgmesProfile.DY.value, ],
						'tk': [cgmesProfile.DY.value, ],
						'tb': [cgmesProfile.DY.value, ],
						'tc': [cgmesProfile.DY.value, ],
						'vamax': [cgmesProfile.DY.value, ],
						'vamin': [cgmesProfile.DY.value, ],
						'vrmax': [cgmesProfile.DY.value, ],
						'vrmin': [cgmesProfile.DY.value, ],
						'te': [cgmesProfile.DY.value, ],
						'kh': [cgmesProfile.DY.value, ],
						'tj': [cgmesProfile.DY.value, ],
						'th': [cgmesProfile.DY.value, ],
						'vfelim': [cgmesProfile.DY.value, ],
						'vhmax': [cgmesProfile.DY.value, ],
						'kc': [cgmesProfile.DY.value, ],
						'kd': [cgmesProfile.DY.value, ],
						'ke': [cgmesProfile.DY.value, ],
						've1': [cgmesProfile.DY.value, ],
						'seve1': [cgmesProfile.DY.value, ],
						've2': [cgmesProfile.DY.value, ],
						'seve2': [cgmesProfile.DY.value, ],
						 }

	serializationProfile = {}

	__doc__ += '\n Documentation of parent class ExcitationSystemDynamics: \n' + ExcitationSystemDynamics.__doc__

	def __init__(self, ka = 0.0, ks = 0.0, ta = 0, tk = 0, tb = 0, tc = 0, vamax = 0.0, vamin = 0.0, vrmax = 0.0, vrmin = 0.0, te = 0, kh = 0.0, tj = 0, th = 0, vfelim = 0.0, vhmax = 0.0, kc = 0.0, kd = 0.0, ke = 0.0, ve1 = 0.0, seve1 = 0.0, ve2 = 0.0, seve2 = 0.0,  *args, **kw_args):
		super().__init__(*args, **kw_args)

		self.ka = ka
		self.ks = ks
		self.ta = ta
		self.tk = tk
		self.tb = tb
		self.tc = tc
		self.vamax = vamax
		self.vamin = vamin
		self.vrmax = vrmax
		self.vrmin = vrmin
		self.te = te
		self.kh = kh
		self.tj = tj
		self.th = th
		self.vfelim = vfelim
		self.vhmax = vhmax
		self.kc = kc
		self.kd = kd
		self.ke = ke
		self.ve1 = ve1
		self.seve1 = seve1
		self.ve2 = ve2
		self.seve2 = seve2

	def __str__(self):
		str = 'class=ExcAC6A\n'
		attributes = self.__dict__
		for key in attributes.keys():
			str = str + key + '={}\n'.format(attributes[key])
		return str


import sys

from bapred.utils import *

# This file is for searching occurance of specifiy words in dataset

def include_all_subs(string, subs):
    '''
    Parameters
    ----------
    strings: string

    subs: List(str)

    Returns: bool
    -------

    '''
    return sum([sub.lower() in string.lower() for sub in subs]) == len(subs)

def filter_with_substring(strings, subs):
    '''
    Parameters
    ----------
    strings: List(str)
        to be filtered

    subs: List(str)
        substring which has to be in filtered string

    Returns: List(Tuple(idx, str))
        filtered strings with original index
    -------

    '''

    out = [(i, s) for i, s in enumerate(strings) if include_all_subs(s, subs)]

    return out

def main(data_dir, n_ans, words):
    questions, answers, scores = get_raw_data_score(data_dir, n_ans, n_files=100)
    reg_scores = reguralize_score(scores, n_ans)

    filtered_ans = filter_with_substring(answers, words)

    with open('retrieved_{}.html'.format(str(words)), 'w') as f:
        f.write('
include words:' + str(words))
        f.write('
n_all_ans' + str(len(answers)))
        f.write('
n_filtered_answers' + str(len(filtered_ans)))
        for i, ans in filtered_ans:
            # if reg_scores[i] != 1:
            #     continue
            q = questions[i // n_ans]
            f.write('
score{}
Question:
{}
Answer:
{}

'.format(reg_scores[i], q, ans))

if __name__ == '__main__':
    if len(sys.argv) != 2:
        raise Exception('Usage: python retrieve_doc.py <data_dir>')
    data_dir = sys.argv[1]
    n_ans = 5
    # words = ['answers']
    words = ['edit']
    main(data_dir, n_ans, words)


# coding: utf-8

class Disciplina:
    """Classe que armazena as informações referente a uma disciplina.

        Armazena os dados que serão inseridos nas posições da grade
    """

    def __init__(self, nome, codigo, turma, horarios, creditos, professor, preferencial, tipo, pode_cursar, trava_credito):
        """Construtor

        Args:
            nome: Nome da disciplina
            codigo: Código da disciplina
            turma: Turma
            horarios: Lista de tuplas com os horarios armazenados em pares (dia, tempo). Exemplo: ("seg", "m1")
            creditos: Quantidade de créditos da disciplina
            professor: Nome do professor que lecionará a disciplina
            preferencial: Bool que indica se a disciplina é preferencial para o aluno
            tipo: Obrigatória, eletiva definida ou eletiva restrita
            pode_cursar: Bool que indica se o aluno pode cursar a disciplina, ou seja, não há pré-requisitos pendentes
            trava_credito: credito minimo necessario para cusar a disciplina
        """
        self._nome = nome
        self._codigo = codigo
        self._turma = turma
        self._horarios = horarios
        self._creditos = creditos
        self._professor = professor
        self._preferencial = preferencial
        self._tipo = tipo
        self._pode_cursar = pode_cursar
        self._trava_credito = trava_credito

    def __str__(self):
        _str = "{} - {}\nHorários: {}".format(self._nome, self._codigo, self._horarios)
        return _str


# -*- coding: utf-8 -*-
"""
Created on Sun Mar  1 21:34:35 2020

@author: KAVITA
"""

from moviepy.editor import *
import sys
import matplotlib.pyplot as plt
import scipy
from scipy import signal
from scipy.io import wavfile
import librosa as lib
scipy.signal.spectrogram
import numpy as np
import librosa.display
import pickle as pkl

def get_audio_features(source_filepath,destination_filepath,i,label):

    feature_files = ".\Data\enterface_features_encoded"
    video = VideoFileClip(source_filepath)
    audio_part = video.audio
    audio_part.write_audiofile(destination_filepath)

    sample_rate, samples = wavfile.read(destination_filepath)
    frequencies, times, spectrogram = signal.spectrogram(samples, sample_rate)

    ##### read audio as vector

    audio_input,sr=lib.load(destination_filepath)

    ##### Hamming Window and stft
    audio_stft = librosa.stft(audio_input,window='hamm',n_fft=1024)
    audio_mfcc=librosa.feature.mfcc(abs(audio_input),n_mfcc=32)

    output_filename = os.path.join(feature_files, str(i) + '.pkl')
    out = {'class_label': label,
       'audio': audio_mfcc,
       'sr': sr}
    with open(output_filename, 'wb') as w:
        pkl.dump(out, w)

def get_einterface_files():
    count_unknown, i = 0,0
    av_file_directory = ".\Data\eInterface/enterface database"
    aud_folder='.\Data\Audio_clips\enterface'
    emotions = ['anger', 'disgust','fear', 'happiness', 'sadness', 'surprise']
    for (root,dirs,files) in os.walk(".\Data\eInterface/enterface database", topdown=True):
        for file in files:
            if str(file) != "Thumbs.db": #I put this condition because on my Mac I had a bunch of thumbnail files which we want to skip
                if not str(file).startswith('.'):
                    source_path = os.path.join(root,file)
                    print(source_path)
                    if str(source_path).find("fear") > 0:
                        aud_file_name='f{}'.format(i)+'.wav'
                        label="2"

                    elif str(source_path).find("happiness") > 0 :
                        aud_file_name='h{}'.format(i)+'.wav'
                        label="3"

                    elif str(source_path).find("sadness") > 0:
                        #print(str(root).find("sadness"))
                        aud_file_name='sa{}'.format(i)+'.wav'
                        label="4"

                    elif str(str(source_path)).find("surprise") > 0:
                        aud_file_name='su{}'.format(i)+'.wav'
                        label="5"

                    elif str(str(source_path)).find("anger") > 0 :
                        aud_file_name='a{}'.format(i)+'.wav'
                        label="0"

                    elif str(source_path).find("disgust") > 0 :
                        aud_file_name='d{}'.format(i)+'.wav'
                        label="1"

                    else :
                        #print(str(source_path))
                        aud_file_name = "unknown"
                        count_unknown +=1

                    if aud_file_name != "unknown":
                        #print(vid_file_name)
                        #pass
                        get_audio_features(source_path,os.path.join(aud_folder,aud_file_name),i,label)
                        i+=1

if __name__ == "__main__":

    #get_savee_files()
    get_einterface_files()
    #python open_enterface_folders.py


from threading import Timer as TTimer

class Timer(object):
    PERIODIC = 'PERIODIC'

    ENABLED = 'ENABLED'
    DISABLED = 'DISABLED'

    def __init__(self, id):
        self.id = id
        self.period = 0
        self.mode = Timer.PERIODIC
        self.callback = None
        self.status = Timer.DISABLED

    def init(self, period, mode, callback):
        self.period = period / 1000
        self.mode = mode
        self.callback = callback
        self.status = Timer.ENABLED
        TTimer(self.period, self.run, ()).start()

    def deinit(self):
        self.status = Timer.DISABLED

    def run(self):
        if self.status == Timer.ENABLED:
            self.callback('dummy')
            if self.mode == Timer.PERIODIC:
                TTimer(self.period, self.run, ()).start()

class Pin(object):
    def __init__(self, pin):
        self.pin = pin


# -*- coding: utf-8 -*-
"""
Created on Thu Nov 26 09:56:33 2020

@author: Administrator
"""

import torch
import torchvision as tv
import torchvision.transforms as transforms
import torch.nn as nn
import torch.optim as optim
from PIL import Image, ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
from torch.utils.data import Dataset, DataLoader
import argparse
import torchvision.models as models
import cv2
import time
import numpy as np
import matplotlib.pyplot as plt

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# device = torch.device("cuda")
parser = argparse.ArgumentParser()
parser.add_argument('--outf', default='F:/yzh/DeepLearningDataSet/model_16/', help='folder to output images and model checkpoints')
parser.add_argument('--net', default='/model/net.pth', help="path to netG (to continue training)")
opt = parser.parse_args()

# EPOCH = 30
BATCH_SIZE = 32     #(batch_size)
LR = 0.001        #learning rate
# root = 'D:/neck_tissue_datasets/'
dataset = 'F:/yzh/DeepLearningDataSet/'
# dataset = 'D:/NeckTissue/dataset1103/'
savepath = '/model_16/'
modelname = '1'

def default_loader(path):
    bgr = cv2.imread(path, cv2.IMREAD_LOAD_GDAL)
    rgb = bgr[:, :, ::-1]
    img = Image.fromarray(rgb).convert('L')

    # return Image.open(path).convert('L')
    return img
class MyDataset(Dataset):
    def __init__(self, txt, transform=None, target_transform=None, loader=default_loader):
        fh = open(txt, 'r')                 #Open the specified folder
        imgs = []
        for line in fh:
            line = line.strip('\n')
            line = line.rstrip()
            words = line.split()
            imgs.append((words[0],int(words[1])))
        self.imgs = imgs
        self.transform = transform
        self.target_transform = target_transform
        self.loader = loader

    def __getitem__(self, index):
        fn, label = self.imgs[index]
        img = self.loader(fn)
        if self.transform is not None:
            img = self.transform(img)
#        print(img.size())
        return img,label

    def __len__(self):
        return len(self.imgs)

#Reading data
transform1 = transforms.Compose([
                                 transforms.ToTensor(),

                                 # transforms.Grayscale(1)
                                 # transforms.Normalize((0.5,),(0.5,))
                                 ]
                                )
transform2 = transforms.ToTensor()
train_data1=MyDataset(txt=dataset+'train1.txt', transform=transform1)
train_data2=MyDataset(txt=dataset+'train2.txt', transform=transform1)
train_data3=MyDataset(txt=dataset+'train3.txt', transform=transform1)
train_data4=MyDataset(txt=dataset+'train4.txt', transform=transform1)
test_data1=MyDataset(txt=dataset+'test1.txt', transform=transform1)
test_data2=MyDataset(txt=dataset+'test2.txt', transform=transform1)
test_data3=MyDataset(txt=dataset+'test3.txt', transform=transform1)
test_data4=MyDataset(txt=dataset+'test4.txt', transform=transform1)

train_data=train_data2+test_data2+train_data3+test_data3+train_data4+test_data4
test_data=train_data1+test_data1

trainloader = DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)
#testloader = DataLoader(dataset=test_data, batch_size=8)
testloader = DataLoader(dataset=test_data)

train_data_size = 40500  #Total training set (including all classes)
valid_data_size = 13500  #Total test set (including all classes)

class LeNet(nn.Module):
    def __init__(self):
        super(LeNet, self).__init__()
        self.conv1 = nn.Sequential(     #input_size=(1*28*28)
            nn.Conv2d(1, 6, 5, 1, 2),
            nn.ReLU(),      #input_size=(6*28*28)
            nn.MaxPool2d(kernel_size=2, stride=2),#output_size=(6*14*14)
        )
        self.conv2 = nn.Sequential(
            nn.Conv2d(6, 16, 5),
            nn.ReLU(),      #input_size=(16*10*10)
            nn.MaxPool2d(2, 2)  #output_size=(16*5*5)
        )
        self.conv3 = nn.Sequential(
            nn.Conv2d(16, 16, 5),
            nn.ReLU(),      #input_size=(16*10*10)
            nn.MaxPool2d(2, 2)  #output_size=(16*5*5)
        )
        self.fc1 = nn.Sequential(
            nn.Linear(16 * 29 * 29, 120),
            nn.ReLU()
        )
        self.fc2 = nn.Sequential(
            nn.Linear(120, 84),
            nn.ReLU()
        )
        self.fc3 = nn.Linear(84, 3)

    def forward(self, x):
        x = self.conv1(x)
        x = self.conv2(x)
        x = self.conv3(x)
        # nn.Linear()
        # print(x.size())
        x = x.view(x.size()[0], -1)
        x = self.fc1(x)
        x = self.fc2(x)
        x = self.fc3(x)
        return x

class LeNet12(nn.Module):
    def __init__(self):
        super(LeNet12, self).__init__()
        self.conv1 = nn.Sequential(     #input_size=(1*28*28)
            nn.Conv2d(1, 6, 5, 1, 2),
            nn.ReLU(),      #input_size=(6*28*28)
            nn.MaxPool2d(kernel_size=2, stride=2),#output_size=(6*14*14)
        )
        self.conv2 = nn.Sequential(
            nn.Conv2d(6, 16, 5, 1, 2),
            nn.ReLU(),      #input_size=(16*10*10)
            nn.MaxPool2d(2, 2)  #output_size=(16*5*5)
        )
        self.conv3 = nn.Sequential(
            nn.Conv2d(16, 32, 5, 1, 2),
            nn.ReLU(),      #input_size=(16*10*10)
            nn.MaxPool2d(2, 2)  #output_size=(16*5*5)
        )
        self.conv4 = nn.Sequential(
            nn.Conv2d(32, 64, 5, 1, 2),
            nn.ReLU(),      #input_size=(16*10*10)
            nn.MaxPool2d(2, 2)  #output_size=(16*5*5)
        )
        self.conv5 = nn.Sequential(
            nn.Conv2d(64, 128, 5, 1, 2),
            nn.ReLU(),      #input_size=(16*10*10)
            nn.MaxPool2d(2, 2)  #output_size=(16*5*5)
        )
        self.conv6 = nn.Sequential(
            nn.Conv2d(128, 256, 5, 1, 2),
            nn.ReLU(),      #input_size=(16*10*10)
            # nn.MaxPool2d(2, 2)  #output_size=(16*5*5)
        )
        self.fc1 = nn.Sequential(
            nn.Linear(256 * 8 * 8, 120),
            nn.ReLU()
        )
        self.fc2 = nn.Sequential(
            nn.Linear(120, 84),
            nn.ReLU()
        )
        self.fc3 = nn.Linear(84, 3)

    def forward(self, x):
        # print(x.size())
        x = self.conv1(x)
        # print(x.size())
        x = self.conv2(x)
        # print(x.size())
        x = self.conv3(x)
        # print(x.size())
        x = self.conv4(x)
        # print(x.size())
        x = self.conv5(x)
        # print(x.size())
        x = self.conv6(x)
        # print(x.size())
        # nn.Linear()
        # print(x.size())
        x = x.view(x.size()[0], -1)
        x = self.fc1(x)
        x = self.fc2(x)
        x = self.fc3(x)
        return x
# net = LeNet12().to(device)
# net = LeNet()
# net = torch.load('F:/yzh/data_process_results/DL/PreprocessDataset/model/Lenet_240.pt') #Load the trained model
# resnet50 = models.resnet18(pretrained=True)
# net = models.squeezenet1_0(num_classes = 5)
# print(net)

#resnet18
# net = models.resnet18(pretrained=False)
# net = models.resnet18(num_classes = 3)
# net.conv1 = nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3, bias=False)  #Change layer 1 of resnet18 to single channel input
# net.features[0] = nn.Conv2d(1, 96, kernel_size=7, stride=2, padding=3, bias=False)
# for param in resnet50.parameters():

# VGG16

net = models.vgg16(pretrained=False)
# net = net.vgg16(num_classes=3)
net.features[0]=nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3, bias=False) #Change layer 1 of vgg16 to single channel input
net.classifier[6]=nn.Linear(in_features=4096,out_features=3,bias=True) #Modify the output of the final full connection layer
#     param.requires_grad = False

# fc_inputs = net.fc.in_features

# net.fc = nn.Sequential(

#     nn.Linear(fc_inputs, 256),

#     nn.ReLU(),

#     nn.Dropout(0.4),

#     nn.Linear(256, 5),

#     nn.LogSoftmax(dim=1)

# )

# net.classifier = nn.Sequential(
#     nn.Dropout(p=0.5, inplace=False),

#     nn.Conv2d(512, 5, kernel_size=(1, 1), stride=(1, 1)),

#     nn.ReLU(),

#     nn.LogSoftmax(dim=1)

# )
print(net)
net = net.to(device)

loss_func = nn.CrossEntropyLoss()
# loss_func = nn.NLLLoss()
# optimizer = optim.SGD(net.parameters(), lr=LR, momentum=0.9)
optimizer = optim.Adam(net.parameters(),lr = LR)

def train_and_valid(model, loss_function, optimizer, epochs):

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

    history = []

    best_acc = 0.0

    best_epoch = 0

    for epoch in range(epochs):

        epoch_start = time.time()

        print("Epoch: {}/{}".format(epoch+1, epochs))

        model.train()

        train_loss = 0.0

        train_acc = 0.0

        valid_loss = 0.0

        valid_acc = 0.0

        for i, (inputs, labels) in enumerate(trainloader):

            inputs = inputs.to(device)

            labels = labels.to(device)

            optimizer.zero_grad()

            outputs = model(inputs)

            loss = loss_function(outputs, labels)

            loss.backward()

            optimizer.step()

            train_loss += loss.item() * inputs.size(0)

            ret, predictions = torch.max(outputs.data, 1)

            correct_counts = predictions.eq(labels.data.view_as(predictions))

            acc = torch.mean(correct_counts.type(torch.FloatTensor))

            train_acc += acc.item() * inputs.size(0)

        with torch.no_grad():

            model.eval()

            for j, (inputs, labels) in enumerate(testloader):

                inputs = inputs.to(device)

                labels = labels.to(device)

                outputs = model(inputs)

                loss = loss_function(outputs, labels)

                valid_loss += loss.item() * inputs.size(0)

                ret, predictions = torch.max(outputs.data, 1)

                correct_counts = predictions.eq(labels.data.view_as(predictions))

                acc = torch.mean(correct_counts.type(torch.FloatTensor))

                valid_acc += acc.item() * inputs.size(0)

        avg_train_loss = train_loss/train_data_size

        avg_train_acc = train_acc/train_data_size

        avg_valid_loss = valid_loss/valid_data_size

        avg_valid_acc = valid_acc/valid_data_size

        history.append([avg_train_loss, avg_valid_loss, avg_train_acc, avg_valid_acc])

        if best_acc < avg_valid_acc:

            best_acc = avg_valid_acc

            best_epoch = epoch + 1

        epoch_end = time.time()

        print("Epoch: {:03d}, Training: Loss: {:.4f}, Accuracy: {:.4f}%, \n\t\tValidation: Loss: {:.4f}, Accuracy: {:.4f}%, Time: {:.4f}s".format(

            epoch+1, avg_train_loss, avg_train_acc*100, avg_valid_loss, avg_valid_acc*100, epoch_end-epoch_start

        ))

        print("Best Accuracy for validation : {:.4f} at epoch {:03d}".format(best_acc, best_epoch))

        torch.save(model, dataset + savepath + modelname+str(epoch+1)+'.pt')

    return model, history

num_epochs = 40

trained_model, history = train_and_valid(net, loss_func, optimizer, num_epochs)

# torch.save(history, dataset + savepath + modelname+'_history.pt')

history = np.array(history)

plt.plot(history[:, 0:2])

plt.legend(['Tr Loss', 'Val Loss'])

plt.xlabel('Epoch Number')

plt.ylabel('Loss')

plt.ylim(0, 1)

# plt.savefig(dataset + savepath + modelname+'_loss_curve.png')

plt.show()

plt.plot(history[:, 2:4])

plt.legend(['Tr Accuracy', 'Val Accuracy'])

plt.xlabel('Epoch Number')

plt.ylabel('Accuracy')

plt.ylim(0, 1)

# plt.savefig(dataset + savepath + modelname+'_accuracy_curve.png')

plt.show()


from fc_topo_all_route import Fc_topo_all_route

class Fc_topo_disjoin_route(Fc_topo_all_route):

    def __init__(self, switches, hosts, ports, vir_layer_degree, is_random, random_seed):
        Fc_topo_all_route.__init__(self, switches, hosts, ports, vir_layer_degree, is_random, random_seed)

if __name__ == "__main__":
    switches = 5
    hosts = 24
    ports = 36
    vir_layer_degree = [2,4,4,2]
    is_random = 1
    random_seed = 3
    fc_demo = Fc_topo_disjoin_route(switches, hosts, ports, vir_layer_degree, is_random, random_seed)
    fc_demo.fc_topo_gene()
    fc_demo.route_infor_generate()
    thread_num = 2
    if_report = 1
    report_num = 2
    if_save = 1
    # fc_demo.route_gene(thread_num, if_report, report_num, if_save)
    fc_demo.route_read()


import streamlit
import pandas
import snowflake.connector

streamlit.title('My First Hotel Menu by Streamlit')
#streamlit.header('Breakfast Menu')
streamlit.header("Fruityvice Fruit Advice!")
streamlit.text('Omega 3 & Blueberry Oatmeal')
streamlit.text('Kale, Spinach & Rocket Smoothie')
streamlit.text('Hard-Boiled Free-Range Egg')

my_fruit_list = pandas.read_csv("https://uni-lab-files.s3.us-west-2.amazonaws.com/dabw/fruit_macros.txt")
my_fruit_list = my_fruit_list.set_index('Fruit')

fruits_selected =streamlit.multiselect("Pick some fruits:", list(my_fruit_list.index),['Avocado','Strawberries'])
streamlit.dataframe(my_fruit_list)

fruits_to_show = my_fruit_list.loc[fruits_selected]

import requests
fruityvice_response = requests.get("https://fruityvice.com/api/fruit/" + "watermelon")
streamlit.text(fruityvice_response)
# write your own comment -what does the next line do?
fruityvice_normalized = pandas.json_normalize(fruityvice_response.json())
# write your own comment - what does this do?
streamlit.dataframe(fruityvice_normalized)

my_cnx = snowflake.connector.connect(**streamlit.secrets["snowflake"])
my_cur = my_cnx.cursor()
my_cur.execute("SELECT * from pc_rivery_db.public.fruit_load_list")
my_data_row = my_cur.fetchone()
streamlit.text("The fruit list contains:")
streamlit.text(my_data_row)


#Exercise 4.1
#Create Python code to convert temperature between Farenheit and Centigrade:
def celsiusToFahrenheit(celsiusParam):
    result = (celsiusParam * 1.8) + 32
    return print(result)

def fahrenheitToCelsius(fahrenheitParam):
    result = (fahrenheitParam - 32) / 1.8
    return print(result)

celsiusToFahrenheit(25)
fahrenheitToCelsius(77)

#Exercise 4.2
#Create a program to average any number of numbers. You will need to use a loop like:
numberArray = [1,2,3,12,15,26,30,50]
arrayLength = len(numberArray)
cumulative = 0;

for index in numberArray:
    cumulative += index

average = cumulative / arrayLength
print(average)

#Exercise 4.3a
#Use lists, dictionaries etc. to create Python data structures:
#Instantiating a dictionary
personInfoDict = {}
personInfoDict[0] = {"Name": "Sue", "Age" : 21, "Height" : 160, "Gender" : 'F'}
print(personInfoDict[0])

#Zipping two arrays to make a dictionary
personInfoHeadings = ["Name", "Age", "Height", "Gender"]
personInfoValues = ["Sue", 21, 160, 'F']
personInfo = zip(personInfoHeadings, personInfoValues)
print(dict(personInfo))

#Exercise 4.3b:
#David - boss of Ken and Nick, has staff
#Nick - has a department
#Ken - has a department
#Department - has staff

#Plurals Exercise
#Try to write general rules for pluralisation in Python. Main rules: vowel change: man -> men, -f +ves: shelf -> shelves, consonant -y + ies: lady -> ladies, o/ss/ch/x + es: box -> boxes
def pluralise(word):
    endsWithMan = word.endswith("man")
    endsWithF = word.endswith("f")
    endsWithY = word.endswith("y")
    endsWithO = word.endswith("o")
    endsWithSs = word.endswith("ss")
    endsWithCh = word.endswith("ch")
    endsWithX = word.endswith("x")

    if (endsWithMan):
        split = word.rsplit('man', 1) #Last occurrence of 'man' in case the word contains more than one
        firstHalfSplit = split[0]
        pluralised = firstHalfSplit + "men"
        return pluralised

    elif (endsWithF):
        print("ends with f")
        split = word.rsplit('f', 1) #Last occurrence of 'f' in case the word contains more than one
        print(split)
        firstHalfSplit = split[0]
        print(firstHalfSplit)
        pluralised = firstHalfSplit + "ves"
        return pluralised

    elif (endsWithY):
        split = word.rsplit('y', 1) #Last occurrence of 'y' in case the word contains more than one
        firstHalfSplit = split[0]
        pluralised = firstHalfSplit + "ies"
        return pluralised

    elif (endsWithO or endsWithSs or endsWithCh or endsWithX):
        pluralised = word + "es"
        return pluralised

toPluralise = "church"
print(pluralise(toPluralise))


import pytest
from flask import Flask

from useraccounts.app import flask_app

@pytest.fixture(autouse=True)
def fake_bootstrap(monkeypatch):
    monkeypatch.setattr('useraccounts.app.bootstrap', lambda: None)
    monkeypatch.setattr('useraccounts.app.register_blueprints', lambda *args, **kwargs: None)

def test_create_app_should_return_instance_of_flask_app():
    app = flask_app()
    assert isinstance(app, Flask)

# def test_create_app_should_abort_on_missing_config(monkeypatch):
#     def mock_abort(x):
#         raise Exception('Start up aborted!')

#     monkeypatch.setitem('useraccounts.bootstrap.abort', mock_abort)
#     monkeypatch.setitem('useraccounts.config.config', 'DB_CONNECTION_STRING', None)

#     with pytest.raises(Exception) as excinfo:
#         flask_app()

#     assert excinfo.value.args[0] == 'Start up aborted!'


from techs.armor import Armor
from techs.domination import Domination
from techs.weapon import Laser, FleetAttack, Gauss
from units.cruiser import Cruiser
from units.heavy_fighter import HFighter
from units.light_fighter import LFighter

TECH_LIST = [
    Laser(14),
    Laser(6, tech_lvl=2),
    Gauss(1),
    Gauss(5, tech_lvl=2),
    Armor(25),
    Domination(1),
    FleetAttack(17),

]

def get_my_fleet():
    lf = LFighter()
    hf = HFighter()
    for tech in TECH_LIST:
        tech.process_ship(lf)
        tech.process_ship(hf)
    fleet = {
        lf: 100,
        hf: 100
    }
    return fleet

def get_other_fleet():
    hf = HFighter()
    cr = Cruiser()
    for tech in TECH_LIST:
        tech.process_ship(hf)
        tech.process_ship(cr)
    fleet = {
        hf: 100,
        cr: 40
    }
    return fleet

if __name__ == '__main__':
    fleet = get_my_fleet()
    fleet2 = get_other_fleet()


import pandas as pd
import numpy as np
from sklearn.model_selection import KFold
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.ensemble import RandomForestClassifier

train_data_file = pd.read_csv('data/traindata.csv')
train_labels_file = pd.read_csv('data/trainlabel.csv')
test_data_file = pd.read_csv('data/testdata.csv')

for i in train_data_file:
    train_data_file[i] = train_data_file[i] - np.mean(train_data_file[i])

attributes = train_data_file.values
labels = train_labels_file.values.ravel()
X_test = test_data_file.values

accuracy_mean = []
accuracy_ = []

log_cls = LogisticRegression()
dtree_clf = DecisionTreeClassifier(random_state=0)
gnb_clf = GaussianNB()
rf_clf = RandomForestClassifier(max_depth=2, random_state=0)

kf = KFold(n_splits=5, shuffle=False, random_state=None)
kf.get_n_splits(attributes)
for train_index, test_index in kf.split(attributes):
    X_train, X_test = attributes[train_index], attributes[test_index]
    y_train, y_test = labels[train_index], labels[test_index]

    # print(type(X_train))
    # print(X_train.shape)

    accuracy = []

    # using svm
    # svm_cls = svm.SVC(kernel='linear')
    # svm_cls.fit(X_train, y_train)
    # svm_predict = svm_cls.score(X_test, y_test)
    # accuracy.append(svm_predict)

    # using logistic regression
    log_cls.fit(X_train, y_train)
    log_accuracy = log_cls.score(X_test, y_test)
    accuracy.append(log_accuracy)

    # using decision tree
    dtree_clf.fit(X_train, y_train)
    dtree_accuracy = dtree_clf.score(X_test, y_test)
    accuracy.append(dtree_accuracy)

    # using gaussian naive bayes
    gnb_clf.fit(X_train, y_train)
    gnb_accuracy = gnb_clf.score(X_test, y_test)
    accuracy.append(gnb_accuracy)

    # using random forest
    rf_clf.fit(X_train, y_train)
    rf_accuracy = rf_clf.score(X_test, y_test)
    accuracy.append(rf_accuracy)

    accuracy_.append(accuracy)

for i in range(4):
    accuracy_mean.append((accuracy_[0][i] + accuracy_[1][i] + accuracy_[2][i] + accuracy_[3][i])/4)

print(accuracy_mean)

# as the first classifier gives the best performance in cross validation,
# therefore, it is chosen.

result = log_cls.predict(test_data_file)
result = pd.Series(result)
result.to_csv('project1_20446377.csv',index=False)


from aquilon.exceptions_ import ArgumentError
from aquilon.aqdb.model import (Personality, PersonalityStage, Cluster, Host,
                                HostEnvironment, PersonalityESXClusterInfo)
from aquilon.worker.broker import BrokerCommand
from aquilon.worker.dbwrappers.change_management import ChangeManagement
from aquilon.worker.dbwrappers.grn import lookup_grn
from aquilon.worker.templates import PlenaryHost

# List of functions allowed to be used in vmhost_capacity_function
restricted_builtins = {'None': None,
                       'dict': dict,
                       'divmod': divmod,
                       'float': float,
                       'int': int,
                       'len': len,
                       'max': max,
                       'min': min,
                       'pow': pow,
                       'round': round}

def _check_stage_unused(session, dbstage):
    if dbstage.personality.is_cluster:
        q = session.query(Cluster.id)
        msg = "clusters"
    else:
        q = session.query(Host.hardware_entity_id)
        msg = "hosts"

    q = q.filter_by(personality_stage=dbstage)
    if q.count():
        raise ArgumentError("{0} still has {1!s}.".format(dbstage, msg))

class CommandUpdatePersonality(BrokerCommand):
    requires_plenaries = True

    required_parameters = ["personality", "archetype"]

    def render(self, session, logger, plenaries, personality, personality_stage, archetype,
               vmhost_capacity_function, cluster_required, config_override,
               host_environment, grn, eon_id, leave_existing, staged,
               justification, reason, comments, user, **arguments):
        dbpersona = Personality.get_unique(session, name=personality,
                                           archetype=archetype, compel=True)

        if staged is not None:
            if staged is False:
                if "current" not in dbpersona.stages:
                    raise ArgumentError("{0} does not have stage current, "
                                        "you need to promote it before "
                                        "staging can be turned off."
                                        .format(dbpersona))
                for stage in ("previous", "next"):
                    try:
                        dbstage = dbpersona.stages[stage]
                    except KeyError:
                        continue

                    _check_stage_unused(session, dbstage)
                    plenaries.add(dbstage)
                    del dbpersona.stages[stage]

            dbpersona.staged = staged

        dbstage = dbpersona.active_stage(personality_stage)

        cm = ChangeManagement(session, user, justification, reason, logger, self.command, **arguments)
        # It's a bit ugly. If any of the non-staged attributes are touched,
        # then we need to check for prod hosts for all stages
        if (cluster_required is not None or config_override is not None or
                host_environment or grn or eon_id or
                leave_existing is not None or comments is not None):
            for ver in dbpersona.stages.values():
                cm.consider(ver)
        else:
            cm.consider(dbstage)
        cm.validate()

        if cluster_required is not None and \
           dbpersona.cluster_required != cluster_required:
            if dbpersona.is_cluster:
                q = session.query(Cluster.id)
            else:
                q = session.query(Host.hardware_entity_id)
            q = q.join(PersonalityStage)
            q = q.filter_by(personality=dbpersona)
            # XXX: Ideally, filter based on hosts/clusters that are/arenot in
            # cluster/metacluster
            if q.count():
                raise ArgumentError("{0} is in use, the cluster requirement "
                                    "cannot be modified.".format(dbpersona))
            dbpersona.cluster_required = cluster_required

        if host_environment is not None:
            if dbpersona.host_environment.name == 'legacy':
                dbhost_env = HostEnvironment.get_instance(session, host_environment)
                Personality.validate_env_in_name(personality, dbhost_env.name)
                dbpersona.host_environment = dbhost_env
            else:
                raise ArgumentError("{0} already has its environment set to "
                                    "{1!s}, and cannot be updated."
                                    .format(dbpersona, dbpersona.host_environment))

        if grn or eon_id:
            dbgrn = lookup_grn(session, grn, eon_id, logger=logger,
                               config=self.config)
            old_grn = dbpersona.owner_grn
            dbpersona.owner_grn = dbgrn

            # Hosts which inherit the ownership from the personality need to be
            # updated
            q = session.query(Host)
            q = q.filter_by(owner_grn=None)
            q = q.join(PersonalityStage)
            q = q.filter_by(personality=dbpersona)
            q = q.options(PlenaryHost.query_options())
            plenaries.add(q)

            if not leave_existing:
                # If this is a public personality, then there may be hosts with
                # various GRNs inside the personality, so make sure we preserve
                # those GRNs by filtering on the original GRN of the personality
                q = session.query(Host)
                q = q.filter_by(owner_grn=old_grn)
                q = q.join(PersonalityStage)
                q = q.filter_by(personality=dbpersona)
                q = q.options(PlenaryHost.query_options())
                for dbhost in q:
                    dbhost.owner_grn = dbgrn
                    plenaries.add(dbhost)

        if config_override is not None and \
           dbpersona.config_override != config_override:
            dbpersona.config_override = config_override

        if comments is not None:
            dbpersona.comments = comments

        if vmhost_capacity_function is not None:
            if "esx" not in dbstage.cluster_infos:
                dbstage.cluster_infos["esx"] = PersonalityESXClusterInfo()

            # Basic sanity tests to see if the function works
            try:
                global_vars = {'__builtins__': restricted_builtins}
                local_vars = {'memory': 10}
                capacity = eval(vmhost_capacity_function, global_vars,
                                local_vars)
            except Exception as err:
                raise ArgumentError("Failed to evaluate the function: %s" % err)
            if not isinstance(capacity, dict):
                raise ArgumentError("The function should return a dictonary.")
            for name, value in capacity.items():
                if not isinstance(name, str) or (not isinstance(value, int) and
                                                 not isinstance(value, float)):
                    raise ArgumentError("The function should return a dictionary "
                                        "with all keys being strings, and all "
                                        "values being numbers.")

            # TODO: Should this be mandatory? It is for now.
            if "memory" not in capacity:
                raise ArgumentError("The memory constraint is missing from "
                                    "the returned dictionary.")

            dbstage.cluster_infos["esx"].vmhost_capacity_function = vmhost_capacity_function
        elif vmhost_capacity_function == "":
            dbstage.cluster_infos["esx"].vmhost_capacity_function = None

        plenaries.add(dbpersona.stages.values())

        session.flush()

        plenaries.write()

        return


import math
n = int(input())
array = []
def get_num(num):
    global n
    mid = int(math.sqrt(num))
    for i in range(mid, 1, -1):
        if num % i == 0:
            n = num // i
            return get_num(n), get_num(i)
    array.append(num)

get_num(n)
array.sort()
for i in array:
    if i == 1:
        break
    print(i)


# regiester=[0 for i in range(16)]
# memory=[0 for i in range(256)]
# ir=32
# print(f'{ir:032b}')
# a=(0xC50000000)
# b=(0x7ffff)
# print((a&b)/2**23+1)
def g(n):
    sum=0
    while n!=0:
        sum=sum+n%10
        n=n//10
    if sum>9:
        g(sum)
    else:
        return sum
print(g(1234))


import numpy as np
import cv2
import torch
import torch.nn.functional as F

def smooth_mask(mask, size, sigma) -> np.ndarray:
    mask = mask.astype(np.uint8)
    mask = cv2.GaussianBlur(mask, (size, size), sigma)
    return mask

def dilate_mask(mask, kernel_size=3, iterations=1):
    kernel = np.ones((kernel_size, kernel_size), np.uint8)
    mask = cv2.dilate(mask, kernel, iterations=iterations)

    return mask

def erode_mask(mask, kernel_size=3, iterations=1):
    kernel = np.ones((kernel_size, kernel_size), np.uint8)
    mask = cv2.erode(mask, kernel, iterations=iterations)

    return mask

def close_small_holes(mask, min_size=10):
    contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    for contour in contours:
        if cv2.contourArea(contour) < min_size:
            cv2.drawContours(mask, [contour], -1, 0, -1)

    return mask

def maxpool2d_closing(image: np.ndarray, mask: np.ndarray):

    im_floodfill = mask.copy()

    h, w = image.shape[:2]
    flood_mask = np.zeros((h+2, w+2), np.uint8)

    ret, imf, maskf, rect = cv2.floodFill(im_floodfill, flood_mask, (0,0), 255)
    maskf = maskf[1:-1, 1:-1]

    img_conv = torch.tensor(image, dtype=torch.float32)
    img_conv = torch.permute(img_conv, (2, 0, 1)).unsqueeze(0)

    img_max = F.max_pool2d(img_conv, 3, 1, 1)
    img_max_numpy = img_max.permute(0, 2, 3, 1).numpy()[0]
    img_max_numpy = img_max_numpy.astype(np.uint8)

    mask_conv = 255 - mask
    mask_conv = mask_conv.reshape(1, 1, h, w)

    mask_max = F.max_pool2d(torch.tensor(mask_conv.astype(np.float32)), 3, 1, 1)
    mask_max_numpy = mask_max.numpy().astype(np.uint8)[0][0]
    mask_max_numpy = 255 - mask_max_numpy

    img_max_numpy[maskf == 1] = 0
    mask_max_numpy[maskf == 1] = 255


from machine import Pin
from neopixel import NeoPixel
from time import sleep_ms
npPin = 4
NumOfLeds = 128
maxCol = 16
maxRow = 8
pin = Pin(npPin, Pin.OUT)
neoMatrix = NeoPixel(pin, NumOfLeds)
# Converts one demintion NeoPixel to two demintion matrix
#
def setNeoMatrix(col, row, color):
    neoMatrix[row * maxCol + col] = color
    neoMatrix.write()

def clearNeoMatrix(col, row):
    clear = (0, 0, 0)
    neoMatrix[row * maxCol + col] = clear
    neoMatrix.write()

red = (100, 0, 0)
green = (0, 100, 0)
blue = (0, 0, 100)
while(1):
    for row in range(maxRow):
        col = row
        setNeoMatrix(col + 3 , row, red)
        setNeoMatrix(col + 4, row, green)
        setNeoMatrix(col + 5, row, blue)
        sleep_ms(100)
        clearNeoMatrix(col + 3, row)
        clearNeoMatrix(col + 4, row)
        clearNeoMatrix(col + 5, row)
        sleep_ms(100)


from django.shortcuts import render

# Create your views here.
import os
import time
from mysite import settings

def show_static(request):
    print(request.META['REMOTE_ADDR'])  # 客户端ｉｐ
    return render(request, 'index.html')

def show_qr(request):
    remote_addr = request.META['REMOTE_ADDR']
    print(remote_addr)

    img_path = 'static//%s.png' % remote_addr
    if os.path.exists(img_path):
        os.remove(img_path)
    app_dir = 'wechat//wechatHelper'
    img_path = '..//..//' + img_path  # 这个是要传入的参数，因为在WeChatHelper.py文件中要切换目录，所以这里要向上跳两个目录级别
    cmd = 'python3 wechat/wechatHelper/WeChatHelper.py --base_dir %s --pro_dir %s --img_path %s &' \
          % (settings.BASE_DIR, app_dir, img_path)
    os.system(cmd)
    time.sleep(3)  # 这里必须要给时间去下载二维码
    context = {}
    context['url'] = '/static/%s.png' % remote_addr
    return render(request, 'showqr.html', context)


import torch
import torch.nn as nn
import torch.utils.model_zoo as model_zoo
import math

class VGG(nn.Module):

	def __init__(self, attn='0', num_classes=10):
		super(VGG, self).__init__()

		self.attn_type = attn

		self.cfgs = {
				'part1': [64,'D',64,128,'D',128,256,'D',256,'D',256],
				'part2': ['M',512,'D',512,'D',512],
				'part3': ['M',512,'D',512,'D',512],
				'part4': ['M',512,'D','M',512,'M']
			}

		self._make_layers(batch_norm=True)
		self._make_classifier(num_classes)
		self._make_compat_pc()
		self._initialize_weights()

		self.softmaxattn = nn.Softmax(dim=1)

	def forward(self, x):
		loc7 = self.part1(x)
		loc10 = self.part2(loc7)
		loc13 = self.part3(loc10)

		glob = self.part4(loc13).view(loc13.size(0), -1)
		glob = self.part5(glob)

		# #without att
		# out = self.classifier(glob)
		# return out
		if self.attn_type == 'no-att':
			out = self.classifier(glob)
			return out

		if self.attn_type == '1dp':
			out = self.forward_attdp(glob, loc13)
			out = self.classifier(out)
			return out

		if self.attn_type == '1pc':
			out = self.forward_attpc(glob, loc13, self.pcConv13)
			out = self.classifier(out)
			return out

		if self.attn_type == '2dp':
			at1 = self.forward_attdp(glob, loc13)
			at2 = self.forward_attdp(glob, loc10)
			out = torch.cat([at1,at2],dim=1)
			out = self.classifier(out)
			return out

		if self.attn_type == '2pc':
			at1 = self.forward_attpc(glob, loc13, self.pcConv13)
			at2 = self.forward_attpc(glob, loc10, self.pcConv10)
			out = torch.cat([at1,at2],dim=1)
			out = self.classifier(out)
			return out

		if self.attn_type == '2dp-ind':
			at13 = self.forward_attdp(glob, loc13)
			at10 = self.forward_attdp(glob, loc10)

			out1 = self.classifier13(at13)
			out2 = self.classifier13(at10)
			out = out1.add(out2)
			return out

		if self.attn_type == '2pc-ind':
			at13 = self.forward_attpc(glob, loc13, self.pcConv13)
			at10 = self.forward_attpc(glob, loc10, self.pcConv10)

			out1 = self.classifier13(at13)
			out2 = self.classifier13(at10)
			out = out1.add(out2)
			return out

		return

	def forward_attdp(self, glob, loc):
		f = loc.size(-1)

		glob_ = glob.repeat(f,1,1).repeat(f,1,1,1).transpose(0,2).transpose(1,3)

		c = glob_.mul(loc).sum(dim=1).view(-1,f*f)
		c = self.softmaxattn(c)
		c = c.repeat(512,1,1).transpose(0,1)

		loc_attn = c.mul(loc.view(-1,512,f*f)).sum(dim=2)

		return loc_attn

	def forward_attpc(self, glob, loc, cnv):
		f = loc.size(-1)

		glob_ = glob.repeat(f,1,1).repeat(f,1,1,1).transpose(0,2).transpose(1,3)

		c = cnv(glob_.add(loc)).view(-1,f*f)
		c = self.softmaxattn(c)
		c = c.repeat(512,1,1).transpose(0,1)

		loc_attn = c.mul(loc.view(-1,512,f*f)).sum(dim=2)

		return loc_attn

	# def forward_att1dp(self, glob, loc):

	# 	glob = glob.repeat(8,1,1).repeat(8,1,1,1).transpose(0,2).transpose(1,3)

	# 	c = glob.mul(loc).sum(dim=1).view(-1,64)
	# 	c = self.softmax(c)
	# 	c = c.repeat(512,1,1).transpose(0,1)

	# 	loc_attn = c.mul(loc.view(-1,512,64)).sum(dim=2)

	# 	return loc_attn

	# def forward_att2dp(self, glob, loc):

	# 	glob = glob.repeat(16,1,1).repeat(16,1,1,1).transpose(0,2).transpose(1,3)

	# 	c = glob.mul(loc).sum(dim=1).view(-1,256)
	# 	c = self.softmax(c)
	# 	c = c.repeat(512,1,1).transpose(0,1)

	# 	loc_attn = c.mul(loc.view(-1,512,256)).sum(dim=2)

	# 	return loc_attn

	# def forward_att1pc(self, glob, loc):
	# 	glob = glob.repeat(8,1,1).repeat(8,1,1,1).transpose(0,2).transpose(1,3)

	# 	c = glob.add(loc).sum(dim=1).view(-1,64)
	# 	c = self.softmax(c)
	# 	c = c.repeat(512,1,1).transpose(0,1)

	# 	loc_attn = c.mul(loc.view(-1,512,64)).sum(dim=2)

	# 	return loc_attn

	def _initialize_weights(self):
		for m in self.modules():
			if isinstance(m, nn.Conv2d):
				n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
				m.weight.data.normal_(0, math.sqrt(2. / n))
				if m.bias is not None:
					m.bias.data.zero_()
			elif isinstance(m, nn.BatchNorm2d):
				m.weight.data.fill_(1)
				m.bias.data.zero_()
			elif isinstance(m, nn.Linear):
				n = m.weight.size(1)
				m.weight.data.normal_(0, 0.01)
				m.bias.data.zero_()

	def _make_classifier(self, num_classes):
		num_feat = 512
		if 'ind' not in self.attn_type:
			if '2' in self.attn_type:
				num_feat = 1024
			layers = []
			layers += [nn.BatchNorm1d(num_feat)]
			layers += [nn.ReLU(inplace=True)]
			layers += [nn.Dropout(0.5)]
			layers += [nn.Linear(num_feat, num_classes)]
			self.classifier = nn.Sequential(*layers)

		elif 'ind' in self.attn_type:
			layers = []
			layers += [nn.BatchNorm1d(num_feat)]
			layers += [nn.ReLU(inplace=True)]
			layers += [nn.Dropout(0.5)]
			layers += [nn.Linear(num_feat, num_classes)]
			layers += [nn.Softmax(dim=1)]
			self.classifier13 = nn.Sequential(*layers)

			layers = []
			layers += [nn.BatchNorm1d(num_feat)]
			layers += [nn.ReLU(inplace=True)]
			layers += [nn.Dropout(0.5)]
			layers += [nn.Linear(num_feat, num_classes)]
			layers += [nn.Softmax(dim=1)]
			self.classifier10 = nn.Sequential(*layers)

	def _make_compat_pc(self):
		if 'pc' in self.attn_type:
			self.pcConv13 = nn.Conv2d(512, 1, kernel_size=1, padding=0)
			self.pcConv10 = nn.Conv2d(512, 1, kernel_size=1, padding=0)
			self.pcConv7 = nn.Conv2d(512, 1, kernel_size=1, padding=0)

	def _make_layers(self, batch_norm = True):
		firstDP = True
		layers = []
		in_channels = 3
		for v in self.cfgs['part1']:
			if v == 'M':
				layers += [nn.MaxPool2d(kernel_size=2, stride=2)]
			elif v == 'D':
				if firstDP:
					layers += [nn.Dropout(0.3)]
					firstDP = False
				else:
					layers += [nn.Dropout(0.4)]
			else:
				conv2d = nn.Conv2d(in_channels, v, kernel_size=3, padding=1)
				if batch_norm:
					layers += [conv2d, nn.BatchNorm2d(v), nn.ReLU(inplace=True)]
				else:
					layers += [conv2d, nn.ReLU(inplace=True)]
				in_channels = v

		self.part1 = nn.Sequential(*layers)
		layers = []
		for v in self.cfgs['part2']:
			if v == 'M':
				layers += [nn.MaxPool2d(kernel_size=2, stride=2)]
			elif v == 'D':
				layers += [nn.Dropout(0.4)]
			else:
				conv2d = nn.Conv2d(in_channels, v, kernel_size=3, padding=1)
				if batch_norm:
					layers += [conv2d, nn.BatchNorm2d(v), nn.ReLU(inplace=True)]
				else:
					layers += [conv2d, nn.ReLU(inplace=True)]
				in_channels = v

		self.part2 = nn.Sequential(*layers)

		layers = []
		for v in self.cfgs['part3']:
			if v == 'M':
				layers += [nn.MaxPool2d(kernel_size=2, stride=2)]
			elif v == 'D':
				layers += [nn.Dropout(0.4)]
			else:
				conv2d = nn.Conv2d(in_channels, v, kernel_size=3, padding=1)
				if batch_norm:
					layers += [conv2d, nn.BatchNorm2d(v), nn.ReLU(inplace=True)]
				else:
					layers += [conv2d, nn.ReLU(inplace=True)]
				in_channels = v

		self.part3 = nn.Sequential(*layers)

		layers = []
		for v in self.cfgs['part4']:
			if v == 'M':
				layers += [nn.MaxPool2d(kernel_size=2, stride=2)]
			elif v == 'D':
				layers += [nn.Dropout(0.4)]
			else:
				conv2d = nn.Conv2d(in_channels, v, kernel_size=3, padding=1)
				if batch_norm:
					layers += [conv2d, nn.BatchNorm2d(v), nn.ReLU(inplace=True)]
				else:
					layers += [conv2d, nn.ReLU(inplace=True)]
				in_channels = v

		self.part4 = nn.Sequential(*layers)

		layers = [nn.Linear(512, 512)]
		self.part5 = nn.Sequential(*layers)


from flask import Blueprint, render_template, request, redirect, session, jsonify, flash, url_for, abort
from functools import wraps
import hashlib
import json
from datetime import datetime

#custom imports
from .models import Users, Shortlist
from .models import Jobs
shorlist_obj=Shortlist()
user_object = Users()
jobs=Jobs()
admin = Blueprint("admin", __name__, template_folder='templates', static_folder='static/admin',
                   static_url_path='static/admin')

@admin.errorhandler(404)
def page_not_found(error):
    return render_template('admin/404.html'), 404

@admin.route('/add_job',methods=['POST','GET'])
def add_job():
    try:
        if request.method == 'POST':
            job={}
            job['category']=request.form.get('category')
            job['title']=request.form.get('description')
            job['description']=request.form.get('description')
            job['skills']= request.form.get('skills').split(',')
            job['aptitude']=[]
            job['personality']=[]
            job['created_on']= datetime.now()
            result=jobs.put_job(job)
            return redirect(url_for('admin.add_aptitude',job_id=result))
        else:
            return render_template('admin/index.html')
    except Exception as error:
        print(error)
        return render_template('admin/index.html')

@admin.route('/add_aptitude/<job_id>',methods=['POST','GET'])
def add_aptitude(job_id):
    print(job_id)
    try:
        job={}
        job['job_id']=job_id
        job['is_apti']=True
        if request.method == 'POST':
            apti=[]
            for i in range(10):
                tmp={}
                tmp['question']=request.form.get('question'+str(i+1))
                tmp['options']=request.form.get('options'+str(i+1)).split(',')
                tmp['answer']=request.form.get('answer'+str(i+1))
                apti.append(tmp)
            print(apti)
            jobs.put_aptitude(job_id,apti)
            return redirect(url_for('admin.add_personality',job_id=job_id))
        else:
            return render_template('admin/test.html',job=job)

    except Exception as error:
        job={}
        job['job_id']=job_id
        job['is_apti']=False
        print('In exception: ',error)
        return render_template('admin/test.html',job=job)

@admin.route('/dashboard')
def dashboard():
    alljobs=jobs.get_all_jobs()
    print('\n\nall jobs: ',alljobs)
    return render_template('admin/dashboard.html',alljobs=alljobs)

@admin.route('/shortlist')
def shortlist():
    print(request.args.get('job_id'))
    profiles=shorlist_obj.get_profiles(request.args.get('job_id'))
    print('\n\nall jobs: ',profiles)
    return render_template('admin/shortlist.html',profiles=profiles)

@admin.route('/delete/<job_id>',methods=['POST','GET'])
def delete(job_id):
    try:
        print("Im here"*100,job_id)
        jobs.delete_job(job_id)

        return redirect(url_for('admin.dashboard'))
    except Exception as error:

        return redirect(url_for('admin.dashboard'))

@admin.route('/add_personality/<job_id>',methods=['POST','GET'])
def add_personality(job_id):
    print(job_id)
    try:
        job={}
        job['job_id']=job_id
        job['is_apti']=False
        if request.method == 'POST':
            apti=[]
            for i in range(10):
                tmp={}
                tmp['question']=request.form.get('question'+str(i+1))
                tmp['options']=request.form.get('options'+str(i+1)).split(',')
                tmp['answer']=request.form.get('answer'+str(i+1))
                apti.append(tmp)
            print(apti)
            jobs.put_personality(job_id,apti)
            return redirect(url_for('admin.dashboard'))
        else:
            return render_template('admin/test.html',job_id=job_id)

    except Exception as error:
        print('In exception: ',error)

        job={}
        job['job_id']=job_id
        job['is_apti']=False

        return render_template('admin/test.html',job=job)


#!/usr/bin/env python
"""
coding=utf-8

Main entry point into Moby-Dick project.

There aren't great batteries included examples for modeling text with deep learning, so I've built out this repo to
contain starter code for:

 - Text processing: Processing text to be utilized with keras (text pre-processing, converting to indices,
 padding) - Pre-trained embedding: Using a pre-trained text embedding (GoogleNews 300) with keras (translating words
 to a point in \mathbb{R}^{300}) - Convolutional architecture: Modeling text with a convolutional architecture (
 functionally similar to Ngrams) - RNN architecture: Modeling text with a Recurrent Neural Net (RNN) architecture (
 functionally similar to a rolling window)

"""
import glob
import logging
import ntpath
import os

from collections import defaultdict

import numpy
import pandas

from gensim.utils import simple_preprocess

import lib
import resources
import models

def main():
    """
    Main function documentation template
    :return: None
    :rtype: None
    """
    logging.getLogger().setLevel(level=logging.DEBUG)

    # Extract data from upstream
    articles, embedding_matrix, word_to_index = extract()

    # Transform data for modeling
    articles, embedding_matrix, word_to_index = transform(articles, embedding_matrix, word_to_index)

    # Model data / predict on data
    model(articles, embedding_matrix, word_to_index)

    # TODO Load. What is using this down stream?
    load()
    pass

def extract():
    """
    Extract necessary data / resources from upstream. This method will:

     - Validate that newsgroup data set is available, and read in
     - Validate that text embeddings are available, and read in
     - Validate that text to embedding index lookup is available, and read in

    :return: observations, embedding_matrix, word_to_index
    :rtype: (pandas.DataFrame, numpy.array, dict)
    """

    logging.info('Begin extract')
    logging.info('Performing extract for batch: {}, from newgroup_path: {}'
                 .format(lib.get_batch_name(), lib.get_conf('newsgroup_path')))

    # Download resources

    # Confirm newsgroup data set is downloaded
    resources.download_newsgroup()

    # Confirm that embedding is downloaded
    resources.download_embedding()

    # Extract resources from file system

    # Newsgroup20: Get list of all candidate documents
    glob_pattern = os.path.join(lib.get_conf('newsgroup_path'), '*', '*')
    logging.info('Searching for glob_pattern: {}'.format(glob_pattern))
    document_candidates = glob.glob(glob_pattern)

    # Newsgroup20: Create observations data set
    observations = pandas.DataFrame(document_candidates, columns=['document_path'])
    logging.info('Shape of observations data frame created from glob matches: {}'.format(observations.shape))

    # Newsgroup20: Re-order rows
    observations = observations.sample(frac=1)

    # Newsgroup20: Subset number of observations, if it's a test run
    if lib.get_conf('test_run'):
        logging.info('Reducing file size for test run')
        observations = observations.head(100)
        logging.info('Test run number of records: {}'.format(len(observations.index)))

    # Embedding: Load embedding
    embedding_matrix, word_to_index = resources.create_embedding_matrix()
    logging.info('word_to_index max index: {}'.format(max(word_to_index.values())))

    # Archive schema and return
    lib.archive_dataset_schemas('extract', locals(), globals())
    logging.info('End extract')
    return observations, embedding_matrix, word_to_index

def transform(observations, embedding_matrix, word_to_index):
    """
    Transform data and resources to be ready for model consumption. This includes:

     - Pulling document category
     - Pulling raw text (stripped of headers)
     - Normalizing text, converting text to an array of tokens, and converting array of tokens to array of embedding
     indices
     - Padding array of indices, so that all arrays of indices are the same length

    :param observations: A Pandas DataFrame containing the field padded_indices
    :type observations: pandas.DataFrame
    :param embedding_matrix: An embedding matrix, with shape (n,m), where n is the number of words, and m is the
    dimensionality of the embedding
    :type embedding_matrix: numpy.array
    :param word_to_index: A mapping from words (strings), to their index in the embedding matrix. For example
    embedding_matrix[word_to_index['pineapple']] would give the embedding vector for the word 'pineapple'
    :type: {str:int}
    :return: articles, embedding_matrix, word_to_index
    :rtype: (pandas.DataFrame, numpy.array, dict)
    """

    logging.info('Begin transform')

    # Transform embedding resources
    # Embedding: Update embedding to map any unknown words (words not in training vocabulary) to the unknown value
    default_dict_instance = defaultdict(lambda: word_to_index['UNK'])
    default_dict_instance.update(word_to_index)
    word_to_index = default_dict_instance

    # Transform newsgroup20 data set
    # Newsgroup20: Extract article filename from document path
    observations['filename'] = observations['document_path'].apply(lambda x: ntpath.basename(x))

    # Newsgroup20: Extract article category from document path
    observations['category'] = observations['document_path'].apply(lambda x: ntpath.basename(os.path.dirname(x)))

    # Newsgroup20: Extract article text (and strip article headers), from document path
    observations['text'] = observations['document_path'].apply(lambda x: lib.strip_header(open(x).readlines()))

    # Newsgroup20: Convert text to normalized tokens. Unknown tokens will map to 'UNK'.
    observations['tokens'] = observations['text'].apply(simple_preprocess)

    # Newsgroup20: Convert tokens to indices
    observations['indices'] = observations['tokens'].apply(lambda token_list: map(lambda token: word_to_index[token],
                                                                                token_list))
    observations['indices'] = observations['indices'].apply(lambda x: numpy.array(x))

    # Newsgroup20: Pad indices list with zeros, so that every article's list of indices is the same length
    observations['padded_indices'] = observations['indices'].apply(lib.pad_sequence)

    # Newsgroup20: Create label one hot encoder, and encode labels
    label_encoder = lib.create_label_encoder(set(observations['category']))
    observations['category_encoded'] = observations['category'].apply(lambda x: label_encoder[x])

    # Set up modeling input
    observations['modeling_input'] = observations['padded_indices']

    # Archive schema and return
    lib.archive_dataset_schemas('transform', locals(), globals())
    logging.info('End transform')
    return observations, embedding_matrix, word_to_index

def model(observations, embedding_matrix, word_to_index):
    """
    Train models, as appropriate.

    The Pandas DataFrame observations should contain the fields `modeling_input` (where each member is an iterable of
    the same length), and `category_encoded` (where each member is an iterable of the same length)

    :param observations: A Pandas DataFrame containing the field padded_indices
    :type observations: pandas.DataFrame
    :param embedding_matrix: An embedding matrix, with shape (n,m), where n is the number of words, and m is the
    dimensionality of the embedding
    :type embedding_matrix: numpy.array
    :param word_to_index: A mapping from words (strings), to their index in the embedding matrix. For example
    embedding_matrix[word_to_index['pineapple']] would give the embedding vector for the word 'pineapple'
    :type: {str:int}
    :return: None
    :rtype: None
    """

    logging.info('Begin model')

    # Reference variables

    # Create train and test data sets

    train_test_mask = numpy.random.random(size=len(observations.index))
    num_train = sum(train_test_mask < .8)
    num_validate = sum(train_test_mask >= .8)
    logging.info('Proceeding w/ {} train observations, and {} test observations'.format(num_train, num_validate))

    x_train = observations['modeling_input'][train_test_mask < .8].tolist()
    y_train = observations['category_encoded'][train_test_mask < .8].tolist()
    x_test = observations['modeling_input'][train_test_mask >= .8].tolist()
    y_test = observations['category_encoded'][train_test_mask >= .8].tolist()

    # Convert x and y vectors to numpy objects
    x_train = numpy.array(x_train, dtype=object)
    y_train = numpy.array(y_train)
    x_test = numpy.array(x_test, dtype=object)
    y_test = numpy.array(y_test)

    logging.info('x_train shape: {}, y_train shape: {}, '
                 'x_test shape: {}, y_test shape: {}'.format(x_train.shape, y_train.shape, x_test.shape, y_test.shape))

    # If required, train model
    if lib.get_conf('train_model'):
        logging.info('Creating and training model')

        classification_model = models.gen_conv_model(observations, embedding_matrix, word_to_index)

        # Train model
        classification_model.fit(x_train, y_train, batch_size=128, epochs=20, validation_data=(x_test, y_test))

        logging.info('Finished creating and training model')

    # Validate model

    # Archive schema and return
    lib.archive_dataset_schemas('transform', locals(), globals())
    logging.info('End model')
    pass

def load():
    pass

# Main section
if __name__ == '__main__':
    main()


import argparse
import json
import logging
import time
from notion_client import Client
import requests
from requests.utils import cookiejar_from_dict
from http.cookies import SimpleCookie
from datetime import datetime

WEREAD_URL = "https://weread.qq.com/"
WEREAD_NOTEBOOKS_URL = "https://i.weread.qq.com/user/notebooks"
WEREAD_BOOKMARKLIST_URL = "https://i.weread.qq.com/book/bookmarklist"
WEREAD_CHAPTER_INFO = "https://i.weread.qq.com/book/chapterInfos"
WEREAD_READ_INFO_URL = "https://i.weread.qq.com/book/readinfo"
WEREAD_REVIEW_LIST_URL = "https://i.weread.qq.com/review/list"
WEREAD_REVIEW_BOOK_INFO = "https://i.weread.qq.com/book/info"

def parse_cookie_string(cookie_string):
    cookie = SimpleCookie()
    cookie.load(cookie_string)
    cookies_dict = {}
    cookiejar = None
    for key, morsel in cookie.items():
        cookies_dict[key] = morsel.value
        cookiejar = cookiejar_from_dict(
            cookies_dict, cookiejar=None, overwrite=True
        )
    return cookiejar

def get_bookmark_list(bookId):
    """获取我的划线"""
    params = dict(bookId=bookId)
    r = session.get(WEREAD_BOOKMARKLIST_URL, params=params)
    if r.ok:
        updated = r.json().get("updated")
        updated = sorted(updated, key=lambda x: (
            x.get("chapterUid", 1), int(x.get("range").split("-")[0])))
        return r.json()["updated"]
    return None

def get_read_info(bookId):
    params = dict(bookId=bookId, readingDetail=1,
                  readingBookIndex=1, finishedDate=1)
    r = session.get(WEREAD_READ_INFO_URL, params=params)
    if r.ok:
        return r.json()
    return None

def get_bookinfo(bookId):
    """获取书的详情"""
    url = ""
    params = dict(bookId=bookId)
    r = session.get(url, params=params)
    isbn = ""
    if r.ok:
        data = r.json()
        isbn = data["isbn"]
        title = data["title"]
    return isbn

def get_review_list(bookId):
    """获取笔记"""
    params = dict(bookId=bookId, listType=11, mine=1, syncKey=0)
    r = session.get(WEREAD_REVIEW_LIST_URL, params=params)
    reviews = r.json().get("reviews")
    summary = list(filter(lambda x: x.get("review").get("type") == 4, reviews))
    reviews = list(filter(lambda x: x.get("review").get("type") == 1, reviews))
    reviews = list(map(lambda x: x.get("review"), reviews))
    reviews = list(map(lambda x: {**x, "markText": x.pop("content")}, reviews))
    return summary, reviews

def get_table_of_contents():
    """获取目录"""
    return {
        "type": "table_of_contents",
        "table_of_contents": {
            "color": "default"
        }
    }

def get_heading(level, content):
    if level == 1:
        heading = "heading_1"
    elif level == 2:
        heading = "heading_2"
    else:
        heading = "heading_3"
    return {
        "type": heading,
        heading: {
            "rich_text": [{
                "type": "text",
                "text": {
                    "content": content,
                }
            }],
            "color": "default",
            "is_toggleable": False
        }
    }

def get_quote(content):
    return {
        "type": "quote",
        "quote": {
            "rich_text": [{
                "type": "text",
                "text": {
                    "content": content
                },
            }],
            "color": "default"
        }
    }

def get_callout(content, style, colorStyle, reviewId):
    # 根据不同的划线样式设置不同的emoji 直线type=0 背景颜色是1 波浪线是2
    emoji = "🌟"
    if style == 0:
        emoji = "💡"
    elif style == 1:
        emoji = "⭐"
    # 如果reviewId不是空说明是笔记
    if reviewId != None:
        emoji = "✍"
    color = "default"
    # 根据划线颜色设置文字的颜色
    if colorStyle == 1:
        color = "red"
    elif colorStyle == 2:
        color = "purple"
    elif colorStyle == 3:
        color = "blue"
    elif colorStyle == 4:
        color = "green"
    elif colorStyle == 5:
        color = "yellow"
    return {
        "type": "callout",
        "callout": {
            "rich_text": [{
                "type": "text",
                "text": {
                    "content": content,
                }
            }],
            "icon": {
                "emoji": emoji
            },
            "color": color
        }
    }

def check(bookId):
    """检查是否已经插入过 如果已经插入了就删除"""
    time.sleep(0.3)
    filter = {
        "property": "BookId",
        "rich_text": {
            "equals": bookId
        }
    }
    response = client.databases.query(database_id=database_id, filter=filter)
    for result in response["results"]:
        time.sleep(0.3)
        client.blocks.delete(block_id=result["id"])

def get_chapter_info(bookId):
    """获取章节信息"""
    body = {
        'bookIds': [bookId],
        'synckeys': [0],
        'teenmode': 0
    }
    url = 'https://i.weread.qq.com/book/chapterInfos'
    r = session.post(url, json=body)
    if r.ok and "data" in r.json() and len(r.json()["data"]) == 1 and "updated" in r.json()["data"][0]:
        update = r.json()["data"][0]["updated"]
        return {item["chapterUid"]: item for item in update}
    return None

def insert_to_notion(bookName, bookId, cover, sort, author):
    """插入到notion"""
    time.sleep(0.3)
    parent = {
        "database_id": database_id,
        "type": "database_id"
    }
    properties = {
        "BookName": {"title": [{"type": "text", "text": {"content": bookName}}]},
        "BookId": {"rich_text": [{"type": "text", "text": {"content": bookId}}]},
        "Author": {"rich_text": [{"type": "text", "text": {"content": author}}]},
        "Sort": {"number": sort},
        "Cover": {"files": [{"type": "external", "name": "Cover", "external": {"url": cover}}]},
    }
    read_info = get_read_info(bookId=bookId)
    if read_info != None:
        markedStatus = read_info.get("markedStatus", 0)
        readingTime = read_info.get("readingTime", 0)
        format_time = ""
        hour = readingTime // 3600
        if hour > 0:
            format_time += f"{hour}时"
        minutes = readingTime % 3600 // 60
        if minutes > 0:
            format_time += f"{minutes}分"
        properties["Status"] = {"select": {
            "name": "读完" if markedStatus == 4 else "在读"}}
        properties["ReadingTime"] = {"rich_text": [
            {"type": "text", "text": {"content": format_time}}]}
        if "finishedDate" in read_info:
            properties["Date"] = {"date": {"start": datetime.utcfromtimestamp(read_info.get(
                "finishedDate")).strftime("%Y-%m-%d %H:%M:%S"), "time_zone": "Asia/Shanghai"}}

    icon = {
        "type": "external",
        "external": {
            "url": cover
        }
    }
    # notion api 限制100个block
    response = client.pages.create(
        parent=parent, icon=icon, properties=properties)
    id = response["id"]
    return id

def add_children(id, children):
    results = []
    for i in range(0, len(children)//100+1):
        time.sleep(0.3)
        response = client.blocks.children.append(
            block_id=id, children=children[i*100:(i+1)*100])
        results.extend(response.get("results"))
    return results if len(results) == len(children) else None

def add_grandchild(grandchild, results):
    for key, value in grandchild.items():
        time.sleep(0.3)
        id = results[key].get("id")
        client.blocks.children.append(block_id=id, children=[value])

def get_notebooklist():
    """获取笔记本列表"""
    r = session.get(WEREAD_NOTEBOOKS_URL)
    if r.ok:
        data = r.json()
        books = data.get("books")
        books.sort(key=lambda x: x["sort"])
        return books
    return None

def get_sort():
    """获取database中的最新时间"""
    filter = {
        "property": "Sort",
        "number": {
            "is_not_empty": True
        }
    }
    sorts = [
        {
            "property": "Sort",
            "direction": "descending",
        }
    ]
    response = client.databases.query(
        database_id=database_id, filter=filter, sorts=sorts, page_size=1)
    if (len(response.get("results")) == 1):
        return response.get("results")[0].get("properties").get("Sort").get("number")
    return 0

def get_children(chapter, summary, bookmark_list):
    children = []
    grandchild = {}
    if chapter != None:
        # 添加目录
        children.append(get_table_of_contents())
        d = {}
        for data in bookmark_list:
            chapterUid = data.get("chapterUid", 1)
            if (chapterUid not in d):
                d[chapterUid] = []
            d[chapterUid].append(data)
        for key, value in d .items():
            if key in chapter:
                # 添加章节
                children.append(get_heading(
                    chapter.get(key).get("level"), chapter.get(key).get("title")))
            for i in value:
                callout = get_callout(
                    i.get("markText"), data.get("style"), i.get("colorStyle"), i.get("reviewId"))
                children.append(callout)
                if i.get("abstract") != None and i.get("abstract") != "":
                    quote = get_quote(i.get("abstract"))
                    grandchild[len(children)-1] = quote

    else:
        # 如果没有章节信息
        for data in bookmark_list:
            children.append(get_callout(data.get("markText"),
                            data.get("style"), data.get("colorStyle"), data.get("reviewId")))
    if summary != None and len(summary) > 0:
        children.append(get_heading(1, "点评"))
        for i in summary:
            children.append(get_callout(i.get("review").get("content"), i.get(
                "style"), i.get("colorStyle"), i.get("review").get("reviewId")))
    return children, grandchild

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("weread_cookie")
    parser.add_argument("notion_token")
    parser.add_argument("database_id")
    options = parser.parse_args()
    weread_cookie = options.weread_cookie
    database_id = options.database_id
    notion_token = options.notion_token
    session = requests.Session()
    session.cookies = parse_cookie_string(weread_cookie)
    client = Client(
        auth=notion_token,
        log_level=logging.ERROR
    )
    session.get(WEREAD_URL)
    latest_sort = get_sort()
    books = get_notebooklist()
    if (books != None):
        for book in books:
            sort = book["sort"]
            if sort <= latest_sort:
                continue
            book = book.get("book")
            title = book.get("title")
            cover = book.get("cover")
            bookId = book.get("bookId")
            author = book.get("author")
            check(bookId)
            chapter = get_chapter_info(bookId)
            bookmark_list = get_bookmark_list(bookId)
            summary, reviews = get_review_list(bookId)
            bookmark_list.extend(reviews)
            bookmark_list = sorted(bookmark_list, key=lambda x: (
                x.get("chapterUid", 1), 0 if x.get("range", "") == "" else int(x.get("range").split("-")[0])))
            children, grandchild = get_children(
                chapter, summary, bookmark_list)
            id = insert_to_notion(title, bookId, cover, sort, author)
            results = add_children(id, children)
            if(len(grandchild)>0 and results!=None):
                add_grandchild(grandchild, results)


# A simple pre-computed KRR example.
# NOTE this does not appear to be a good choice of kernel

# %%
import json
import pandas as pd
import itertools
import numpy as np

from EleMD import EleMD
from tqdm import tqdm
from sklearn.kernel_ridge import KernelRidge

# %%
# Load the data

filename = "data/matbench_expt_gap.json"

with open(filename, 'rb') as f:
    dataframe_data = json.load(f)

df = pd.DataFrame(**dataframe_data)
df = df.sample(frac=1).reset_index(drop=True)

# %%
# Eval train distances

n = 1000

x = df["composition"][:n].values
y = df["gap expt"][:n].values

D = np.zeros((n, n))

mod_petti = EleMD()

iterator = itertools.combinations(range(n), 2)
for i, j in tqdm(iterator):
    D[i, j] = mod_petti.elemd(x[i], x[j])

D = D + D.T

# %%
# Eval test distances

m = 200

x_test = df["composition"][n:n+m].values
y_test = df["gap expt"][n:n+m].values

D_test = np.zeros((m, n))

iterator = itertools.product(range(m), range(n))
for i, j in tqdm(iterator):
    D_test[i, j] = mod_petti.elemd(x[i], x[j])

# %%
# fit KRR
krr = KernelRidge(kernel="precomputed")
lam = 2e-4

def K(D, lam=lam):
    # return np.exp(-D**2/l)
    return lam/(D**2+lam)

krr.fit(K(D), y)

tr_y = krr.predict(K(D))
te_y = krr.predict(K(D_test))

print(f"Train MAE: {np.mean(np.abs(tr_y - y)):.3f}")
print(f"Test MAE: {np.mean(np.abs(te_y - y_test)):.3f}")

print(f"Train RMSE: {np.sqrt(np.mean((tr_y - y)**2)):.3f}")
print(f"Test RMSE: {np.sqrt(np.mean((te_y - y_test)**2)):.3f}")

# %%


import requests
from common.classes.hugging_face_classes import HuggingFaceResponse

# retrieve tokens from .env file
from dotenv import load_dotenv
import os
load_dotenv()
HUGGING_FACE_TOKEN = os.getenv('HUGGING_FACE_TOKEN')

huggin_face_url = 'https://api-inference.huggingface.co/models/google/bigbird-pegasus-large-pubmed'

def summarizeWithML(abstracts_text: str):
  '''summarize a text using an ml model from Hugging Face'''
  hugging_face_response = requests.post(
    huggin_face_url,
    headers={
      "Authorization": f"Bearer {HUGGING_FACE_TOKEN}"
    },
    json=abstracts_text
  )
  hugging_face_obj: HuggingFaceResponse = hugging_face_response.json()
  return hugging_face_obj


from bs4 import BeautifulSoup
import requests
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
import os
import json

def remove_spaces(spaces):
    spaces = spaces.strip().replace(" +","")
    spaces = " ".join(spaces.split())
    return spaces

PATH = os.getcwd()
JSON_FILEPATH = os.path.join(PATH,'linkedin_job_finder.json')
if os.path.exists(JSON_FILEPATH) :
    flag = 0
    with open(JSON_FILEPATH, 'r') as f:
        data_master = json.load(f)
else:
    flag = 1
    with open(JSON_FILEPATH, 'w') as fp:
        pass

options = webdriver.ChromeOptions()
options.add_argument('--disable-gpu')
options.add_argument('--no-sandbox')
options.add_argument('--headless')
driver = webdriver.Chrome(options = options)

data = []

url ="https://www.linkedin.com/jobs/search/?currentJobId=2599978326&jobPostingId=2599472731&pivotType=similarJobs"
driver.get(url)
content = driver.page_source
soup = BeautifulSoup(content, "html.parser")

st_divs1 = soup.find_all('div',{"class" : "base-card base-card--link base-search-card base-search-card--link job-search-card"})
print(len(st_divs1))

for divs in st_divs1 :

    print("*"*20)

    JOBID = ""
    TITLE = ""
    COMPANY = ""
    PLACE = ""
    DATE = ""
    LINK = ""
    DESCRIPTION = ""
    JOB_FUNCTION = ""
    EMPLOYMENT_TYPE = ""
    INDUSTRIES = ""

    job_id = divs['data-entity-urn'].split(':')[-1]
    job_id = remove_spaces(job_id)
    print(job_id)
    JOBID = job_id

    links = divs.find('a',{"class" :"base-card__full-link"})['href']
    links = remove_spaces(links)
    print(links)
    LINK = links

    title = divs.find('h3',{"class" : "base-search-card__title"}).text
    title = remove_spaces(title)
    print(title)
    TITLE = title

    company = divs.find('h4',{"class" : "base-search-card__subtitle"}).text
    company = remove_spaces(company)
    print(company)
    COMPANY = company

    location = divs.find('span',{"class" : "job-search-card__location"}).text
    location = remove_spaces(location)
    print(location)
    PLACE = location

    try :
        date_time = divs.find('time',{"class" : "job-search-card__listdate--new"})['datetime']
        date_time = remove_spaces(date_time)
        print(date_time)
        DATE = date_time

    except Exception as e :
        print(e)
        pass

    driver.get(links)
    content = driver.page_source
    soup_1 = BeautifulSoup(content, "html.parser")
    time.sleep(3)

    try :
        description = soup_1.find('div',{"class" : "show-more-less-html__markup"}).text
        description = remove_spaces(description)
        print(description)
        DESCRIPTION = description

    except Exception as e :
        print(e)
        pass

    try :
        info_div = soup_1.find_all('li',{"class" : "description__job-criteria-item"})
        for info in info_div :
            employment_type = remove_spaces(info.find('h3').text)
            employment_desc = remove_spaces(info.find('span').text)
            print(employment_type,employment_desc)
            if 'employment' in employment_type.lower() :
                EMPLOYMENT_TYPE = employment_desc
            elif 'job' in employment_type.lower() :
                JOB_FUNCTION = employment_desc
            elif 'industries' in employment_type.lower() :
                INDUSTRIES = employment_desc

    except Exception as e:
        print(e)
        pass

    scraper_data = {}
    scraper_data['job_id'] = JOBID
    scraper_data['title'] = TITLE
    scraper_data['company'] = COMPANY
    scraper_data['place'] = PLACE
    scraper_data['date'] = DATE
    scraper_data['link'] = LINK
    scraper_data['description'] = DESCRIPTION
    scraper_data['job_function'] = JOB_FUNCTION
    scraper_data['employment_type'] = EMPLOYMENT_TYPE
    scraper_data['industries'] = INDUSTRIES
    data.append(scraper_data)

if data == [] :
    raise Exception('The data object is empty . Please run the Python File once again ')

if flag == 0 :
    for x in data :
        if x not in data_master:
            data_master.append(x)

    seen = []
    for x in data_master:
        if x not in seen:
            seen.append(x)

    with open(JSON_FILEPATH,'w') as file :
        json.dump(seen,file,ensure_ascii=False, indent=1)

elif flag == 1 :
    with open(JSON_FILEPATH,'w') as file :
        json.dump(data,file,ensure_ascii=False, indent=1)

driver.quit()


import string

alfabet = ['a', 'ą', 'b', 'c', 'ć', 'd', 'e', 'ę', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'ł', 'm',
           'n', 'ń', 'o', 'ó', 'p', 'q', 'r', 's', 'ś', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'ź', 'ż']

# funkcja szyfrująca i deszyfrująca szyfr Cezara
def Cezar(text, key):
    is_upper = False
    final = ''

    for character in text:
        # sprawdzenie czy czytany znak nie jest kropką, przecinkiem, liczbą lub spacją
        if character in string.punctuation or character in string.whitespace or character in string.digits:
            final += character
            continue
        # jeśli znak jest dużą literą, zmienna is_upper jest ustawiana na True
        elif character.isupper():
            character = character.lower()
            is_upper = True

        if character in alfabet:
            position = alfabet.index(character)

            # pobierany jest znak z pozycji odpowiadającej sumie pozycji czytanego znaku i klucza
            if position + key >= len(alfabet):
                temp = alfabet[abs(len(alfabet) - (position + key))]
            else:
                temp = alfabet[position + key]

            # jeśli czytany znak był dużą literą, w outpucie zapisywany jest równiez dużą literą
            if is_upper:
                final += temp.upper()
                is_upper = False
            else:
                final += temp

    return final

if __name__ == '__main__':
    print(Cezar('Ala ma kota.', 3) == 'Cnc oc mqwc.')
    print(Cezar('Ala ma kota.', 20) == 'Óżó ąó źćió.')
    print(Cezar('Ala ma 2 koty.', 5) == 'Dod pd 2 ńsyą.')
    print(Cezar(
        'Daremne żale, próżny trud,\nBezsilne złorzeczenia!\nPrzeżytych kształtów żaden cud\nNie wróci do istnienia.',
        7)
          == 'Jęxkrsk eępk, vxuesc źxżj,\nGkćyńpsk ćqtxćkhćksńę!\nVxćkecźchn óyćźęqźuą eęjks hżj\nSńk ąxuhń jt ńyźsńksńę.')
    print(Cezar('Cnc oc mqwc.', -3) == 'Ala ma kota.')
    print(Cezar('Óżó ąó źćió.', -20) == 'Ala ma kota.')
    print(Cezar('Dod pd 2 ńsyą.', -5) == 'Ala ma 2 koty.')
    print(Cezar(
        'Jęxkrsk eępk, vxuesc źxżj,\nGkćyńpsk ćqtxćkhćksńę!\nVxćkecźchn óyćźęqźuą eęjks hżj\nSńk ąxuhń jt ńyźsńksńę.',
        -7)
          == 'Daremne żale, próżny trud,\nBezsilne złorzeczenia!\nPrzeżytych kształtów żaden cud\nNie wróci do istnienia.')


from datetime import datetime
import re

from sqlalchemy import (Column, Integer, Boolean, DateTime, Sequence, String,
                        ForeignKey, UniqueConstraint, PrimaryKeyConstraint)
from sqlalchemy.inspection import inspect
from sqlalchemy.orm import (relation, backref, deferred, object_session,
                            reconstructor)
from sqlalchemy.orm.collections import column_mapped_collection
from sqlalchemy.util import memoized_property

from aquilon.exceptions_ import ArgumentError, NotFoundException
from aquilon.aqdb.column_types import AqStr, Enum
from aquilon.aqdb.model import (
    Archetype,
    Base,
    Grn,
    HostEnvironment,
    Location,
    NetGroupWhiteList,
    Parameterized,
    User,
)

_TN = 'personality'
_PGN = 'personality_grn_map'
_PRU = 'personality_rootuser'
_PRNG = 'personality_rootnetgroup'
_PS = 'personality_stage'
_ALLOWED_STAGES = ('previous', 'current', 'next')

class Personality(Base):
    """ Personality names """
    __tablename__ = _TN

    id = Column(Integer, Sequence('%s_id_seq' % _TN), primary_key=True)
    name = Column(AqStr(64), nullable=False)
    archetype_id = Column(ForeignKey(Archetype.id), nullable=False)

    cluster_required = Column(Boolean, default=False, nullable=False)

    config_override = Column(Boolean, default=False, nullable=False)

    owner_eon_id = Column(ForeignKey(Grn.eon_id, name='%s_owner_grn_fk' % _TN),
                          nullable=False)

    host_environment_id = Column(ForeignKey(HostEnvironment.id), nullable=False)

    staged = Column(Boolean, default=False, nullable=False)

    creation_date = deferred(Column(DateTime, default=datetime.now,
                                    nullable=False))
    comments = Column(String(255), nullable=True)

    archetype = relation(Archetype, innerjoin=True)
    owner_grn = relation(Grn, innerjoin=True)

    host_environment = relation(HostEnvironment, innerjoin=True)

    __table_args__ = (UniqueConstraint(archetype_id, name),
                      {'info': {'unique_fields': ['name', 'archetype']}},)

    def __init__(self, name=None, **kwargs):
        name = AqStr.normalize(name)
        super(Personality, self).__init__(name=name, **kwargs)

    @property
    def is_cluster(self):
        return self.archetype.cluster_type is not None

    @property
    def qualified_name(self):
        return self.archetype.name + "/" + self.name

    @classmethod
    def validate_env_in_name(cls, name, host_environment):
        env_mapper = inspect(HostEnvironment)
        persona_env = re.search("[-/](" +
                                "|".join(env_mapper.polymorphic_map) +
                                ")$", name, re.IGNORECASE)
        if persona_env and (persona_env.group(1) != host_environment):
            raise ArgumentError("Environment value in personality name '{0}' "
                                "does not match the host environment '{1}'"
                                .format(name, host_environment))

    @staticmethod
    def force_valid_stage(stage):
        if stage not in _ALLOWED_STAGES:
            raise ArgumentError("'%s' is not a valid personality stage." %
                                stage)

    def force_existing_stage(self, stage):
        self.force_valid_stage(stage)
        if stage not in self.stages:
            raise NotFoundException("{0} does not have stage {1!s}."
                                    .format(self, stage))

    def default_stage(self, stage=None):
        """
        Return the default stage to be used for non-update operations
        """
        if stage:
            if not self.staged:
                raise ArgumentError("{0} is not staged.".format(self))
        else:
            stage = "current"

        self.force_existing_stage(stage)
        return self.stages[stage]

    def active_stage(self, stage=None):
        """
        Return the default stage to be used for updates
        """
        if stage:
            if not self.staged:
                raise ArgumentError("{0} is not staged.".format(self))
            self.force_existing_stage(stage)
            return self.stages[stage]
        else:
            if not self.staged:
                return self.stages["current"]

            if "next" not in self.stages:
                session = object_session(self)
                with session.no_autoflush:
                    dbstage = self.stages["current"].copy(name="next")
                    dbstage.created_implicitly = True
                    self.stages["next"] = dbstage

            return self.stages["next"]

class PersonalityStage(Base):
    __tablename__ = _PS
    _class_label = "Personality"

    id = Column(Integer, Sequence('%s_id_seq' % _PS), primary_key=True)

    personality_id = Column(ForeignKey(Personality.id, ondelete='CASCADE'),
                            nullable=False)
    name = Column(Enum(8, _ALLOWED_STAGES), nullable=False)

    # The plenary classes need the ORM to be aware if the object is deleted, so
    # we're using a ORM cascading instead of passive_deletes=True here.
    personality = relation(Personality, innerjoin=True,
                           backref=backref('stages',
                                           cascade='all, delete-orphan',
                                           collection_class=column_mapped_collection(name)))

    __table_args__ = (UniqueConstraint(personality_id, name,
                                       name='%s_uk' % _PS),)

    @property
    def qualified_name(self):
        if self.staged:
            return self.personality.qualified_name + "@" + self.name
        else:
            return self.personality.qualified_name

    @property
    def cluster_required(self):
        return self.personality.cluster_required

    @property
    def staged(self):
        return self.personality.staged

    @property
    def owner_eon_id(self):
        return self.personality.owner_eon_id

    @property
    def archetype(self):
        return self.personality.archetype

    @property
    def owner_grn(self):
        return self.personality.owner_grn

    @property
    def host_environment(self):
        return self.personality.host_environment

    @property
    def root_users(self):
        return self.personality.root_users

    @property
    def root_netgroups(self):
        return self.personality.root_netgroups

    def copy(self, name="current"):
        from aquilon.aqdb.model import StaticRoute
        session = object_session(self)

        new = self.__class__(name=name)

        with session.no_autoflush:
            for defholder, param in self.parameters.items():
                new.parameters[defholder] = param.copy()
            new.features.extend(link.copy() for link in self.features)
            for dbsrv, info in self.required_services.items():
                new.required_services[dbsrv] = info.copy()

            new.grns.extend(grn_link.copy() for grn_link in self.grns)

            for cluster_type, info in self.cluster_infos.items():
                new.cluster_infos[cluster_type] = info.copy()

            q = session.query(StaticRoute)
            q = q.filter_by(personality_stage=self)
            for src_route in q:
                dst_route = src_route.copy(personality_stage=new)
                session.add(dst_route)

        return new

    def __init__(self, *args, **kwargs):
        # This flag is used to track if plenaries need to be created for a newly
        # created 'next' stage, even if existing plenaries would not have to be
        # updated.
        # TODO: can we just ask this information from SQLAlchemy?
        self.created_implicitly = False

        super(PersonalityStage, self).__init__(*args, **kwargs)

    @reconstructor
    def setup(self):
        # Loading an object from the DB does not call __init__
        self.created_implicitly = False

    @memoized_property
    def param_features(self):
        """
        Return the features which can have parameters set

        The feature should be bound directly to the personality rather than
        indirectly to the whole archetype, and the feature should at least
        have a parameter definition holder.
        """
        return frozenset(link.feature for link in self.features
                         if link.feature.param_def_holder)

class PersonalityGrnMap(Base):
    __tablename__ = _PGN

    personality_stage_id = Column(ForeignKey(PersonalityStage.id,
                                             ondelete='CASCADE'),
                                  nullable=False)

    eon_id = Column(ForeignKey(Grn.eon_id), nullable=False)

    target = Column(AqStr(32), nullable=False)

    grn = relation(Grn, lazy=False, innerjoin=True)

    __table_args__ = (PrimaryKeyConstraint(personality_stage_id, eon_id,
                                           target),)

    def copy(self):
        return type(self)(eon_id=self.eon_id, target=self.target)

PersonalityStage.grns = relation(PersonalityGrnMap,
                                 cascade='all, delete-orphan',
                                 passive_deletes=True)

class __PersonalityRootUser(Base):
    __tablename__ = _PRU

    personality_id = Column(ForeignKey(Personality.id, ondelete='CASCADE'),
                            nullable=False)

    user_id = Column(ForeignKey(User.id, ondelete='CASCADE'),
                     nullable=False, index=True)

    creation_date = deferred(Column(DateTime, default=datetime.now,
                                    nullable=False))

    __table_args__ = (PrimaryKeyConstraint(personality_id, user_id),)

Personality.root_users = relation(User,
                                  secondary=__PersonalityRootUser.__table__,
                                  passive_deletes=True)

class __PersonalityRootNetGroup(Base):
    __tablename__ = _PRNG

    personality_id = Column(ForeignKey(Personality.id, ondelete='CASCADE'),
                            nullable=False)

    netgroup_id = Column(ForeignKey(NetGroupWhiteList.id, ondelete='CASCADE'),
                         nullable=False, index=True)

    creation_date = deferred(Column(DateTime, default=datetime.now,
                                    nullable=False))

    __table_args__ = (PrimaryKeyConstraint(personality_id, netgroup_id),)

Personality.root_netgroups = relation(NetGroupWhiteList,
                                      secondary=__PersonalityRootNetGroup.__table__,
                                      passive_deletes=True)

class ParameterizedPersonality(Parameterized):
    _objects = {
        'main': Personality,
        'location': Location,
    }

    @property
    def resholder(self):
        for resholder in self._main.resholders:
            if resholder.location == self.location:
                return resholder
        return None


'''
[program description]

Author: Laith Adi

ID: 170265190

Email: Adix5190@mylaurier.ca

__updated__ = "2018-11-02"

'''
penny_weight = 1.5552

print("Pennyweight to grams Conversion")
start = int(input("Start: "))
limit = int(input("Limit: "))
increment = int(input("Increment: "))

pennys = 0
grams = 0
counter = 0

pen = ("Pennyweight")
gram = ("Grams")
line = ("-----------")
line2 = ("---------")
print("")
print("{:>11}{:>10}".format(pen, gram))
print("{:>11}{:>10}".format(line, line2))
for i in range(start, limit + 1, increment):
    pennys = start + (increment * counter)
    counter += 1
    grams = pennys * penny_weight
    print("{:>11d}{:>10.4f}".format(pennys, grams))