import numpy as np
import torch
import librosa
from PIL import Image
import wav2clip
import os
import os.path as osp

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

BASE_DIR = './extracted_audio'
FEATURE_DIR = './features_audio'
if not os.path.exists(FEATURE_DIR):
    os.mkdir(FEATURE_DIR)

audio_dict = {}

def extract_audio_features(src: str, dst: str):
    audio, sr = librosa.load(src)
    audio_features = wav2clip.embed_audio(audio, audio_model)
    np.save(dst, audio_features)
    return audio_features

for class_name in os.listdir(BASE_DIR):
    print("Extracting class {}".format(class_name))
    base_class_dir = osp.join(BASE_DIR, class_name)
    if not os.path.isdir(base_class_dir):
        continue

    feature_class_dir = osp.join(FEATURE_DIR, class_name)
    if not os.path.exists(feature_class_dir):
        os.mkdir(feature_class_dir)

    for video_name in os.listdir(base_class_dir):
        base_audio_path = osp.join(base_class_dir, video_name)
        feature_audio_path = osp.join(feature_class_dir, video_name)
        features = extract_audio_features(base_audio_path, feature_audio_path)
        audio_dict["{}/{}".format(class_name, video_name)] = features

np.save('feature_dict.npy', features)


"""
utility functions to process composite database

"""

from rdkit import Chem
from rdkit.Chem import Descriptors
import pandas as pd
import numpy as np
import re

def flatten_list(nested_list):
    return [e for inner_list in nested_list for e in inner_list]

def change_dict_key(d, old_key, new_key, default_value=None):
    d[new_key] = d.pop(old_key, default_value)

def is_nan(v):
    return v != v

def list_to_slash(ratio_list, punct="/"):
    ratio_list = [str(i) for i in ratio_list]
    return punct.join(ratio_list)

def slash_to_list(ratio_list, mode="float"):
    ratio_list = str(ratio_list).split("/")

    if mode == "float":
        return [float(i) for i in ratio_list]
    else:
        return [i for i in ratio_list]

def normalize_ratio(s):

    ratio_list = slash_to_list(s)
    tot = sum(ratio_list)
    ratio_list = [str(i/tot) for i in ratio_list]

    return list_to_slash(ratio_list)

def calc_wt_ratio_from_mol_wt(single_record, mol_wt_list, key="SMILES", punct="."):

    # if molar ratio is recorded, calculate weight ratio
    if not is_nan(single_record["mol_ratio"]):

        mol_list = str(single_record["mol_ratio"]).split("/")
        mol_list = [float(i) for i in mol_list]
        wt_list = [str(i*j) for i, j in zip(mol_list, mol_wt_list)]
        single_record["wt_ratio"] = "/".join(wt_list)

    # single component
    if single_record[key].find(punct) < 0:
        single_record["wt_ratio"] = "1"

    # multiple component
    else:
        # if no information is given about watio, just put 1/1/1..
        if is_nan(single_record["wt_ratio"]):
            semiles_count = single_record[key].count(punct)+1
            array_of_one = ["1"]*semiles_count
            single_record["wt_ratio"] = "/".join(array_of_one)

        # normalize weight ratio
        single_record["wt_ratio"] = normalize_ratio(single_record["wt_ratio"])

    return single_record

# calculate molar weight of compounds excluding Mg and Ca
def calc_mol_weight(smiles):
    mol = Chem.MolFromSmiles(smiles)
    try:
        wt = Descriptors.MolWt(mol)
        f_charge = Chem.rdmolops.GetFormalCharge(mol)
    except:
        wt = 100
        f_charge = 0
    # lithium is often omitted in the compound database. add the weight of lithium
    if f_charge < 0:
        wt = wt-6.941*f_charge

    # Ca and Mg is often used just to reperesent the repeating units
    wt = wt-40.078*smiles.count("Ca")
    wt = wt-24.305*smiles.count("Mg")

    return wt

def sort_compounds_by_weight_ratio(comp_list, wt_list):

    ordering_list = [[k, v] for k, v in zip(wt_list, comp_list)]
    ordering_list.sort(reverse=True)
    a, b = list(zip(*ordering_list))
    return b, a

def unnest_dataframe(df, explode, axis):
    if axis == 1:
        idx = df.index.repeat(df[explode[0]].str.len())
        df1 = pd.concat([
            pd.DataFrame({x: np.concatenate(df[x].values)}) for x in explode], axis=1)
        df1.index = idx

        return df1.join(df.drop(explode, 1), how='left')
    else:
        df1 = pd.concat([
            pd.DataFrame(df[x].tolist(), index=df.index).add_prefix(x) for x in explode], axis=1)
        return df1.join(df.drop(explode, 1), how='left')

def get_column_names(df, name):
    return list(df.columns[[True if re.match(name, i) else False for i in df.columns]])


class person:
    TITLE = ("Mr.",'Ms.','Mrs.','Dr.')
    def __init__(self,title,name,surname):
        if title not in self.TITLE:
            raise ValueError("%s is not a valid title." % title)
        self.title = title
        self.name = name
        self.surname = surname

# we can access a class attribute from an instance
person.TITLES

# but we can also access it from the class
Person.TITLES

# This will give us an error
person = person
Person.name
Person.surname


# -*- coding: utf-8 -*-
"""
Created on Thu Sep 20 17:27:43 2018

@author: simadec
"""
from numpy.random import seed
import tensorflow
import glob
import os
import sys
import numpy as np
from tqdm import tqdm
from skimage.transform import resize
from skimage.io import imread
from sklearn.model_selection import train_test_split
import tensorflow as tf
import gc
#from tensorflow.compat.v1.keras import backend as K
#K.set_session()
from tensorflow.python.keras import backend as K
from pathlib import Path
import shutil
import random
from tensorflow.keras.models import model_from_json
# from keras.backend.tensorflow_backend import set_session
# from keras.backend.tensorflow_backend import clear_session
# from keras.backend.tensorflow_backend import get_session

def reset_keras():
    sess = K.get_session()
    K.clear_session()
    sess.close()
    sess = K.get_session()
    seed(123)
    tensorflow.random.set_seed(1)
    np.random.seed(123)
    SEED = 123
    os.environ['PYTHONHASHSEED']= str(SEED)
    os.environ['TF_DETERMINISTIC_OPS'] = '1'
    try:
        del model # this is from global space - change this as you need
    except:
        pass
    try:
        del history # this is from global space - change this as you need
    except:
        pass
    print('gc.collect() : ')
    print(gc.collect()) # if it's done something you should see a number being outputted
    # use the same config as you used to create the session
    # config = tf.compat.v1.ConfigProto()
    # config.gpu_options.per_process_gpu_memory_fraction = 1
    # config.gpu_options.visible_device_list = "0"
    # config.gpu_options.allow_growth = True
    # K.set_session(tf.Session(config=config))
    tf.keras.backend.clear_session()
    print("reset keras")

def make_train_valid_temp(study_PATH,valid =0.1):
    img_list = []
    train_ids = next(os.walk(study_PATH))[1]
    for n, id_ in tqdm(enumerate(train_ids), total=len(train_ids)):
        images_add = [image for image in Path(study_PATH + id_ + '/').glob("images/*") if image.name.endswith((".png", ".jpg", ".JPG"))]
        img_list = img_list+images_add
    random.shuffle(img_list)
    train_list = img_list[:int(len(img_list)*(1-valid))]
    valid_list = img_list[int(len(img_list)*(1-valid)):]

    processed_train_img = Path('temp_training/Training/images/img')
    processed_train_img.mkdir(parents=True, exist_ok=True)
    processed_train_mask = Path('temp_training/Training/masks/img')
    processed_train_mask.mkdir(parents=True, exist_ok=True)

    for n,imageName in tqdm(enumerate(train_list)):
        shutil.copy(imageName,processed_train_img/imageName.name)
        os.rename(processed_train_img/imageName.name, Path(str(processed_train_img/imageName.name).replace('/img/', '/img/{}_'.format(n))))

        new_mask = Path(str(processed_train_img/imageName.name).replace('/images/', '/masks/'))
        shutil.copy2(Path(str(imageName).replace('/images/', '/masks/')),new_mask)
        os.rename(new_mask, Path(str(new_mask).replace('/img/', '/img/{}_'.format(n))))

    processed_val_img = Path('temp_training/Validation/images/img')
    processed_val_img.mkdir(parents=True, exist_ok=True)
    processed_val_mask = Path('temp_training/Validation/masks/img')
    processed_val_mask.mkdir(parents=True, exist_ok=True)

    for n,imageName in tqdm(enumerate(valid_list)):
        shutil.copy(imageName,processed_val_img/imageName.name)
        os.rename(processed_val_img/imageName.name, Path(str(processed_val_img/imageName.name).replace('/img/', '/img/{}_'.format(n))))

        new_mask = Path(str(processed_val_img/imageName.name).replace('/images/', '/masks/'))
        shutil.copy(Path(str(imageName).replace('/images/', '/masks/')),Path(str(processed_val_img/imageName.name).replace('/images/', '/masks/')))
        os.rename(new_mask, Path(str(new_mask).replace('/img/', '/img/{}_'.format(n))))

    return int(len(img_list)*(1-valid)), len(img_list)-int(len(img_list)*(1-valid))

def save_model(model, model_id):
    model_json = model.to_json()
    with open("{0}.json".format(model_id),"w") as json_file:
      json_file.write(model_json)
    model.save_weights("{0}.h5".format(model_id))
    print("saved model..! ready to go.")

def load_saved_model(model_id):
    json_file = open('{0}.json'.format(model_id), 'r')
    loaded_model_json = json_file.read()
    json_file.close()
    loaded_model = model_from_json(loaded_model_json)
    loaded_model.load_weights("{0}.h5".format(model_id))
    print("Loaded model from disk")
    return loaded_model


# 1880ms
from collections import deque
import sys
input = sys.stdin.readline

def bfs(start):
    visited = [0] * (N+1)
    q = deque()

    visited[start] = 1
    q.append(start)

    while q:
        v = q.popleft()
        if len(adjLst[v]) == 1 and v != 1:
            leaves.append(visited[v])
        for w in adjLst[v]:
            if not visited[w]:
                q.append(w)
                if v == 1:
                    visited[w] = visited[v] / (len(adjLst[v]))
                else:
                    visited[w] = visited[v] / (len(adjLst[v])-1)

N, W = map(int, input().split())
adjLst = [[] for _ in range(N + 1)]
for _ in range(N-1):
    a, b = map(int, input().split())
    adjLst[a].append(b)
    adjLst[b].append(a)

leaves = []

bfs(1)
result = sum([W*x for x in leaves])/len(leaves)
print(result)


from pwn import *
from sys import *
import time

host = argv[1]
port = int(argv[2])
timeout = 30

context.log_level = 'critical'

def getIO():
    return remote(host, port, timeout=timeout)

#normal I/O check
def check1():
	try:
		p = getIO()
		info = p.recvuntil(b"choice>", drop=True, timeout=0.5)
		if info[-1] != 10:
			raise Exception("Service is nothing")
		p.close()
	except Exception as e:
		p.close()
		raise Exception("check1 error, "+str(e))
	return True

def checker():
	try:
		# add your check function name
		if check1():
			pass
		else:
			print("team" + str(port)[1:3])
	except Exception as e:
		print("team" + str(port)[1:3])

if __name__ == '__main__':
    checker()


import requests
from bs4 import BeautifulSoup as bs

URL = "https://remoteok.io"

headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36'}

def extract_ro(term):
  url = ''.join([URL, "/remote-dev+{}-jobs".format(term)])
  print(f'searching for {term} jobs at {url}... ')
  response = requests.get(url, allow_redirects=False, headers=headers)

  bs_ = bs(response.text, 'html.parser')
  work_infos = bs_.find_all('td',{'class':'company_and_position_mobile'})

  ro_list = []

  for work_info in work_infos:
    title = work_info.find('h2')
    company = work_info.find('h3')
    if title is None or company is None:
      continue
    else:
      href = title.parent['href']
      href = ''.join([URL, href])
      title = title.text
      company = company.text

    ro_list.append({'title':title, 'company':company, 'href':href})

  return ro_list


import random
import math
import pygame

import globalVars as g

class Entity():
    def __init__(self, x, y, r, c):
        self.x = x
        self.y = y
        self.r = r
        self.c = c
        self.m = 1

    @staticmethod
    def randVec():
        angle = random.random()*math.pi*2
        return {
            'x': math.sin(angle),
            'y': math.cos(angle)}

    def movement(self):
        if random.random() < .005:
            self.vel = self.randVec()

        self.normalizeSpeed()

        self.x += self.vel['x']
        self.y += self.vel['y']

    def wallCollision(self): # if stuck in walls
        if self.x + self.r + self.vel['x'] >= g.gameWidth or self.x - self.r + self.vel['x'] <= 0:
            self.vel['x'] *= -1

        if self.y + self.r + self.vel['y'] >= g.gameHeight or self.y - self.r + self.vel['y'] <= 0:
            self.vel['y'] *= -1

    def normalizeSpeed(self):
        mag = math.sqrt(self.vel['x']**2 + self.vel['y']**2)
        if mag != 0:
            self.vel['x'] /= mag
            self.vel['y'] /= mag
            self.vel['x'] *= self.speed
            self.vel['y'] *= self.speed

    def entityCollision(self, e): # performs elastic collision of 2 circles
        # implementing this equation: https://wikimedia.org/api/rest_v1/media/math/render/svg/f8c2fdb8539aeda1e02fbf46de0f0c35229e76e1
        v1 = math.sqrt(self.vel['x']**2 + self.vel['y']**2)
        v2 = math.sqrt(e.vel['x']**2 + e.vel['y']**2)

        theta1 = math.atan2(self.vel['y'], self.vel['x'])
        theta2 = math.atan2(e.vel['y'], e.vel['x'])

        m1 = self.m
        m2 = e.m

        phi = math.atan2(e.y-self.y,e.x-self.x)

        num1x = v1*math.cos(theta1-phi)*(m1-m2) + 2*m2*v2*math.cos(theta2 - phi)
        num1y = num1x

        self.vel['x'] = (num1x/(m1+m2))*math.cos(phi) + v1*math.sin(theta1-phi)*math.cos(phi + math.pi*0.5)
        self.vel['y'] = (num1y/(m1+m2))*math.sin(phi) + v1*math.sin(theta1-phi)*math.sin(phi + math.pi*0.5)

        num2x = v2*math.cos(theta2-phi)*(m2-m1) + 2*m1*v1*math.cos(theta1 - phi)
        num2y = num2x

        e.vel['x'] = (num2x/(m1+m2))*math.cos(phi) + v2*math.sin(theta2-phi)*math.cos(phi + math.pi*0.5)
        e.vel['y'] = (num2y/(m1+m2))*math.sin(phi) + v2*math.sin(theta2-phi)*math.sin(phi + math.pi*0.5)

    def draw(self, render):
        if render:
            # draws circle on the screen
            pygame.draw.circle(g.screen,self.c,(round(self.x - g.cameraX), round(self.y - g.cameraY)), self.r)


from socket import *
import timeit
import os
import avro.schema
from avro.datafile import DataFileReader, DataFileWriter
from avro.io import DatumReader, DatumWriter

Data = dict(root=dict(int_1=2 ** 9, float_1=3.14, str_1="short string",
                      str_2="I AM LONG STRING, VERY VERY LONG!!!!!!!!!!!!!!!!!!!!",
                      lst_int=[i ** 2 for i in range(1000)],
                      lst_str=[str(i) * 10 for i in range(100)]))

def avro_serialization():
    writer = DataFileWriter(open("test.avro", "wb"), DatumWriter(), schema)
    writer.append(Data)
    writer.close()

def avro_deserialization():
    DataFileReader(open("test.avro", "rb"), DatumReader())

# Press the green button in the gutter to run the script.

if __name__ == '__main__':
    serverSocket = socket(AF_INET, SOCK_DGRAM)
    serverSocket.bind(('', 2005))
    schema = avro.schema.parse(open("m.avsc", "rb").read())
    while True:
        message, address = serverSocket.recvfrom(1024)
        if message == b"get_result":
            time1 = int(timeit.timeit(avro_serialization, timeit.default_timer, number=1000) * 1000)
            time2 = int(timeit.timeit(avro_deserialization, timeit.default_timer, number=1000) * 1000)
            sz = os.path.getsize('test.avro')
            res = f"Apache Avro - {sz} - {time1}ms - {time2}ms\n"
            serverSocket.sendto(str.encode(res), address)
        else:
            serverSocket.sendto(b"bad request\n", address)


import torch
import numpy
import torch.distributed.deprecated as dist
#import torch.distributed as dist
from datasource import Mnist, Mnist_noniid, Cifar10, Cifar10_noniid
from model import CNNMnist, CNNCifar, ResNet18
import copy
from torch.multiprocessing import Process
import argparse
import time
from datetime import datetime
import sys
import os
sys.stdout.flush()

#LR = 1
LR = 0.01
MAX_ROUND = 20000
ROUND_NUMBER_FOR_SAVE = 50
ROUND_NUMBER_FOR_REDUCE = 5
IID = True
#DATA_SET = 'Mnist'
DATA_SET = 'Cifar10'
MODEL = 'CNN'
#MODEL = 'ResNet18'
SAVE = True
CUDA = torch.cuda.is_available()
WINDOW_SIZE = 10
INITIAL_FREQ = 16 * 500
INITIAL_FREQ = 128
RATIO = 0.8

def logging(string):
    print(str(datetime.now())+' '+str(string))
    sys.stdout.flush()

def get_train_loader(world_size, rank, batch_size):
    if IID == True:
        if DATASET == 'Mnist':
            train_loader = Mnist(rank, batch_size).get_train_data()
        if DATASET == 'Cifar10':
            train_loader = Cifar10(rank, batch_size).get_train_data()
    else:
        if DATASET == 'Mnist':
            train_loader = Mnist_noniid(batch_size, world_size).get_train_data(rank)
        if DATASET == 'Cifar10':
            train_loader = Cifar10_noniid(batch_size, world_size).get_train_data(rank)
    return train_loader

def get_test_loader(rank):
    if DATASET == 'Mnist':
        test_loader = Mnist(rank).get_test_data()
    if DATASET == 'Cifar10':
        test_loader = Cifar10(rank).get_test_data()
    return test_loader

def init_param(model, src, group):
    for param in model.parameters():
        dist.broadcast(param.data, src=src, group=group)

def save_model(model, round, rank):
#    logging('===> Saving models...')
    state = {
        'state': model.state_dict(),
        'round': round,
        }
    torch.save(state, 'autoencoder-' + DATASET + '-' + MODEL + '-' + str(rank) + '.t7')

def load_model(group, rank):
    if MODEL == 'CNN' and DATASET == 'Mnist':
        model = CNNMnist()
    if MODEL == 'CNN' and DATASET == 'Cifar10':
        model = CNNCifar()
    if MODEL == 'ResNet18' and DATASET == 'Cifar10':
        model = ResNet18()
    if CUDA:
        model.cuda()
    if SAVE and os.path.exists('autoencoder'+str(rank)+'.t7'):
        logging('===> Try resume from checkpoint')
        checkpoint = torch.load('autoencoder'+str(rank)+'.t7')
        model.load_state_dict(checkpoint['state'])
        round = checkpoint['round']
        logging('model loaded')
    else:
        round = 0
        init_param(model, 0, group)
        logging('model created')
    return model, round

def all_reduce(model, world_size, group):
    for param in model.parameters():
        dist.all_reduce(param.data, op=dist.reduce_op.SUM, group=group)
        param.data /= world_size
    return model

def test(test_loader, model):
    accuracy = 0
    positive_test_number = 0
    total_test_number = 0
    for step, (test_x, test_y) in enumerate(test_loader):
        if CUDA:
            test_x = test_x.cuda()
            test_y = test_y.cuda()
        test_output = model(test_x)
        pred_y = torch.max(test_output, 1)[1].data.cpu().numpy()
        positive_test_number += (pred_y == test_y.data.cpu().numpy()).astype(int).sum()
        total_test_number += float(test_y.size(0))
    accuracy = positive_test_number / total_test_number
    return accuracy

def run(world_size, rank, group, epoch_per_round, batch_size):

    train_loader = get_train_loader(world_size, rank, batch_size)
    test_loader = get_test_loader(rank)

    model, round = load_model(group, rank)
    optimizer = torch.optim.SGD(model.parameters(), lr=LR, weight_decay=1e-2)
    loss_func = torch.nn.CrossEntropyLoss()

    print('initial model parameters: ')
    print(list(model.parameters())[0][0][0])
    print('\n\n ----- start training -----')
    sys.stdout.flush()

    iter_id = 0
    epoch_id = 0
    while epoch_id < MAX_ROUND:
        last_model = copy.deepcopy(model)
        if SAVE and epoch_id == 0 and not os.path.exists('autoencoder'+str(rank)+'.t7'):
            save_model(model, epoch_id, rank)
            logging('\t## Model Saved')

        for step, (b_x, b_y) in enumerate(train_loader):
#            print('--- start batch '+ str(batch_id) + ' ---')
            if CUDA:
                b_x = b_x.cuda()
                b_y = b_y.cuda()
            optimizer.zero_grad()
            output = model(b_x)
            loss = loss_func(output, b_y)
            loss.backward()
            optimizer.step()

            if iter_id % INITIAL_FREQ == 0:
                gradients = []
                for param1, param2 in zip(last_model.parameters(), model.parameters()):
                    gradients.append((param2 - param1).detach().numpy())
                numpy.save(str(epoch_id)+'-gradient', numpy.asarray(gradients))
                model = all_reduce(model, world_size, group)
                numpy.save(str(epoch_id), numpy.asarray([i.detach().numpy() for i in list(model.parameters())]))
                last_model = copy.deepcopy(model)
                accuracy = test(test_loader, model)
                logging(' -- Finish epoch: '+str(iter_id/INITIAL_FREQ) + ' -- | test accuracy: '+str(accuracy))
                epoch_id += 1
            iter_id += 1

def init_processes(master_address, world_size, rank, epoch_per_round, batch_size, run):
    # change 'tcp' to 'nccl' if running on GPU worker
    # master_address = "tcp://" + master_address + ":22222"
    if CUDA:
        dist.init_process_group(backend='nccl', init_method=master_address, world_size=world_size, rank=rank)
    else:
        dist.init_process_group(backend='tcp', init_method=master_address, world_size=world_size, rank=rank)
    group = dist.new_group([i for i in range(world_size)])
    run(world_size, rank, group, epoch_per_round, batch_size)

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('--master_address', '-m', type=str, default='127.0.0.1')
    parser.add_argument('--world_size', '-w', type=int, default=5)
    parser.add_argument('--rank', '-r', type=int, default=0)
    parser.add_argument('--epoch_per_round', '-e', type=int, default=1)
    parser.add_argument('--batch_size', '-b', type=int, default=100)
    parser.add_argument('--model', '-M', type=str, default='CNN')
    parser.add_argument('--dataset', '-D', type=str, default='Cifar10')
    parser.add_argument('--iid', '-I', type=int, default=1)
    args = parser.parse_args()

    master_address = args.master_address
    world_size = args.world_size
    rank = args.rank
    epoch_per_round = args.epoch_per_round
    batch_size = args.batch_size
    # batch_size = 60000
    # batch_size = 128

    # global MODEL, DATASET, IID
    MODEL = args.model
    DATASET = args.dataset
    if args.iid == 1:
        IID = True
    else:
        IID = False

    logging('Initialization:\n\t model: ' + MODEL + '; dataset: ' + DATASET + '; iid: ' + str(IID)
            + '\n\t master_address: ' + str(master_address) + '; world_size: '+str(world_size)
            + ';\n\t rank: '+ str(rank) + '; epoch: '+str(epoch_per_round) + '; batch size: '+str(batch_size))
    init_processes(master_address, world_size, rank, epoch_per_round, batch_size, run)


class TreeNode:
    def __init__(self,key):
        self.key=key
        self.left=None
        self.right=None

node0=TreeNode(3)
node1=TreeNode(4)
node2=TreeNode(5)

node0.left=node1
node0.right=node2

tree=node0
print(tree.key)
print(tree.left.key)
print(tree.right.key)

# constructing a tree
node0=TreeNode(2)
node1=TreeNode(3)
node2=TreeNode(5)
node3=TreeNode(1)
node4=TreeNode(3)
node5=TreeNode(7)
node6=TreeNode(4)
node7=TreeNode(6)
node8=TreeNode(8)

node0.left=node1
node0.right=node2
node1.left=node3
node2.left=node4
node2.right=node5
node4.right=node6
node5.left=node7
node5.right=node8

print(node5.key)
print(node5.left.key)
print(node5.right.key)

# function to create a tree
def parse_tuple(data):
    if isinstance(data,tuple) and len(data)==3:
        node=TreeNode(data[1])
        node.left=parse_tuple(data[0])
        node.right=parse_tuple(data[2])
    elif data is None:
        node=None
    else:
        node=TreeNode(data)
    return node

tree1=parse_tuple(((1,3,None), 2, ((None, 3, 4), 5, (6, 7, 8))))
print(tree1)
print(tree1.key)
print(tree1.left.key,tree1.right.key)

# displaying a tree
def display_keys(node,space='\t',level=0):
    if node is None:
        print(space*level+'∅')
        return

    if node.left is None and node.right is None:
        print(space*level+str(node.key))
        return

    display_keys(node.right,space,level+1)
    print(space*level+str(node.key))
    display_keys(node.left,space,level+1)

display_keys(node0)

# Inorder traversal
def inorder_traversal(node):
    if node is None:
        return []
    return inorder_traversal(node.left)+[node.key]+inorder_traversal(node.right)

print(inorder_traversal(node0))

# Preorder traversal
def preorder_traversal(node):
    if node is None:
        return []
    return [node.key]+preorder_traversal(node.left)+preorder_traversal(node.right)

print(preorder_traversal(node0))

# Postorder traversal
def postorder_traversal(node):
    if node is None:
        return []
    return postorder_traversal(node.left)+postorder_traversal(node.right)+[node.key]

print(postorder_traversal(node0))

# height of tree
def tree_height(node):
    if node is None:
        return 0
    return 1+max(tree_height(node.left),tree_height(node.right))

print(tree_height(node0))

# number of nodes in tree
def nodesintree(node):
    if node is None:
        return 0
    return 1+nodesintree(node.left)+nodesintree(node.right)

print(nodesintree(node0))


from rest_framework import serializers
from images.models import Image

class ImageUploadSerializer(serializers.ModelSerializer):
    image_field = serializers.ImageField(
        label = "",
        style = {'template': 'images/html/includes/file_input.html'}
    )
    class Meta:
        model = Image
        fields = ["image_field"]

class ImageURLSerializer(serializers.Serializer):
    url = serializers.URLField(
        label = "",
        style = {'template': 'images/html/includes/url_input.html'}
    )

class ImageAltSerializer(serializers.Serializer):
    alt = serializers.CharField(
        max_length = 250,
        allow_blank = True,
        trim_whitespace = True,
    )


a = int(input("Enter a number to calculate the factorial:"))

# factorial(5) = 5 * 4 * 3 * 2 * 1 = 120
fact = 1
while a > 1:
    fact *= a
    a -= 1
print(fact)

print("---------")

# Recursive function and Tail Recursion
# function call is keep happening until an exit condition is met.
# whenever a function call happens stack frame will be created and has to exist in memory, and it will be de-allocated once value has been given back.
# all the execution happens within the stack-frame.Traditional recursion uses multiple stack-frames but tail recursion uses only one stack frame.
def fact(a):
    if a == 1:
        return a
    return a * fact(a - 1)

print(fact(5))
print(fact(998))

# tail recursion-> Here there is no dependency that expression needs to be evaluated in the return statement, instead
# everything is done in the fact call itself using accumulator variable, so it uses only one stackframe.
"""
n = 3, acc = 1
fact(3,1)
fact(2,3)
fact(1,6)
return 6
"""

def fact(n, acc):
    if n == 1:
        return acc
    else:
        return fact(n - 1, n * acc)

print(fact(3, 1))


import dash
import dash_labs as dl
import numpy as np
import plotly.express as px

app = dash.Dash(__name__, plugins=[dl.plugins.FlexibleCallbacks()])

# tpl = dl.templates.FlatDiv()
# tpl = dl.templates.HtmlCard(title="Dash Labs App", width="500px")
# tpl = dl.templates.DbcCard(title="Dash Labs App", columns=6)
# tpl = dl.templates.DbcRow(title="Dash Labs App")
# tpl = dl.templates.DbcSidebar(title="Dash Labs App")
# tpl = dl.templates.DdkCard(title="Dash Labs App", width=50)
# tpl = dl.templates.DdkRow(title="Dash Labs App")
# tpl = dl.templates.DdkSidebar(title="Dash Labs App")
#
# tpl = dl.templates.DbcSidebar(
#     title="Dash Labs App",
#     theme="https://stackpath.bootstrapcdn.com/bootswatch/4.5.2/superhero/bootstrap.min.css",
#     figure_template=True
# )

# import dash_bootstrap_components as dbc
#
# tpl = dl.templates.DbcSidebar(
#     title="Dash Labs App",
#     theme=dbc.themes.CYBORG,
# )

from my_theme import theme

tpl = dl.templates.DdkSidebar(title="Dash Labs App", theme=theme)

@app.callback(
    args=dict(
        fun=tpl.dropdown_input(["sin", "cos", "exp"], label="Function"),
        figure_title=tpl.textbox_input("Initial Title", label="Figure Title"),
        phase=tpl.slider_input(1, 10, label="Phase"),
        amplitude=tpl.slider_input(1, 10, value=3, label="Amplitude"),
    ),
    output=tpl.graph_output(),
    template=tpl,
)
def callback(fun, figure_title, phase, amplitude):
    xs = np.linspace(-10, 10, 100)
    np_fn = getattr(np, fun)

    # Let parameterize infer output component
    x = xs
    y = np_fn(xs + phase) * amplitude
    return px.line(x=x, y=y).update_layout(title_text=figure_title)

app.layout = tpl.layout(app)

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


class Solution:
    def minAddToMakeValid(self, s: str) -> int:
        if len(s) == 0: return 0
        stack: list[str] = []
        ans: int = 0

        for c in s:
            if c == '(':
                stack.append(c)
            elif not len(stack): ans += 1
            else: stack.pop()
        ans += len(stack)
        return ans


import os
import unittest
from pyats.topology import loader
from genie.libs.sdk.apis.iosxe.rommon.configure import configure_rommon_tftp

class TestConfigureRommonTftp(unittest.TestCase):

    @classmethod
    def setUpClass(self):
        testbed = f"""
        devices:
          ott-c9300-63:
            connections:
              defaults:
                class: unicon.Unicon
              a:
                command: mock_device_cli --os iosxe --mock_data_dir {os.path.dirname(__file__)}/mock_data --state connect
                protocol: unknown
            os: iosxe
            platform: cat9k
            type: cat9k
            management:
              address:
                ipv4: 5.5.5.5/16
              gateway:
                ipv4: 1.1.1.1
              interface: GigabitEthernet0/0
        testbed:
          servers:
            tftp:
              address: 2.2.2.2
              credentials:
                default:
                  password: ''
                  username: ''
                enable:
                  password: ''
              protocol: tftp
        """
        self.testbed = loader.load(testbed)
        self.device = self.testbed.devices['ott-c9300-63']
        self.device.connect(
            learn_hostname=True,
            init_config_commands=[],
            init_exec_commands=[]
        )

    def test_configure_rommon_tftp(self):
        result = configure_rommon_tftp(self.device)
        expected_output = None
        self.assertEqual(result, expected_output)


from __future__ import absolute_import

import six

from vdsm.common import cmdutils
from vdsm.common import commands
from vdsm import constants

_curl = cmdutils.CommandPath("curl",
                             "/usr/bin/curl", )  # Fedora, EL6

CURL_OPTIONS = ["-q", "--silent", "--fail", "--show-error"]

class CurlError(Exception):
    def __init__(self, ecode, stdout, stderr, message=None):
        self.ecode = ecode
        self.stdout = stdout
        self.stderr = stderr
        self.msg = message

    def __str__(self):
        return "ecode=%s, stdout=%s, stderr=%s, message=%s" % (
            self.ecode, self.stdout, self.stderr, self.msg)

def _headersToOptions(headers):
    options = []
    for k, v in six.iteritems(headers):
        options.extend(("--header", "%s: %s" % (k, v)))
    return options

def _run_curl(cmd, headers=None):
    if headers:
        cmd.extend(_headersToOptions(headers))

    try:
        return commands.run(cmd)
    except cmdutils.Error as e:
        raise CurlError(e.rc, e.out, e.err)

def parse_headers(out):
    lines = out.decode("iso-8859-1").splitlines(False)
    # Besides headers curl returns also HTTP status as the first line and the
    # last line is empty. Therefore we skip first and last line.
    headers = lines[1:-1]
    return dict([x.split(": ", 1) for x in headers])

def head(url, headers=None):
    # Cannot be moved out because _curl.cmd is lazy-evaluated
    cmd = [_curl.cmd] + CURL_OPTIONS + ["--head", url]
    out = _run_curl(cmd, headers)
    # Parse and return headers
    return parse_headers(out)

def get(url, headers=None):
    # Cannot be moved out because _curl.cmd is lazy-evaluated
    cmd = [_curl.cmd] + CURL_OPTIONS + [url]
    return _run_curl(cmd, headers)

def download(url, path, headers=None):
    cmd = [constants.EXT_CURL_IMG_WRAP, "--download"]
    if headers:
        cmd.extend(_headersToOptions(headers))
    cmd.extend([path, url])

    rc, out, err = commands.execCmd(cmd)

    if rc != 0:
        raise CurlError(rc, out, err)

def upload(url, path, headers=None):
    cmd = [constants.EXT_CURL_IMG_WRAP, "--upload"]
    if headers:
        cmd.extend(_headersToOptions(headers))
    cmd.extend([path, url])

    rc, out, err = commands.execCmd(cmd)

    if rc != 0:
        raise CurlError(rc, out, err)


from turtle import Screen, Turtle
import time

# Screen setup
screen = Screen()
screen.setup(width=600, height=600)
screen.bgcolor("black")
screen.title("My Snake Game")
screen.tracer(0)

# creating a Snake body
starting_positions = [(0,0), (-20,0), (-40,0)]  # Starting positions for the snake segments

segments = []  # List to store the turtle segments

# Create turtle segments for each starting position
for position in starting_positions:
    new_segment = Turtle("square")  # Create a new turtle segment with a square shape
    new_segment.color("white")  # Set the color of the segment to white
    new_segment.penup()  # Lift the pen up, so it doesn't draw while moving
    new_segment.goto(position)  # Move the turtle segment to the specified position
    segments.append(new_segment)  # Add the turtle segment to the segments list

game_is_on = True  # Variable to control the game loop

while game_is_on:
    screen.update()  # Update the screen to show any changes
    time.sleep(0.1)  # Introduce a 0.1-second delay between each iteration of the game loop

    for seg_num in range(len(segments) - 1, 0, -1):
        new_x = segments[seg_num - 1].xcor()  # Get the x-coordinate of the previous segment
        new_y = segments[seg_num - 1].ycor()  # Get the y-coordinate of the previous segment
        segments[seg_num].goto(new_x, new_y)  # Move the current segment to the new position

    # Move the first segment forward by 20 units
    segments[0].forward(20)

screen.exitonclick()  # Exit the program when the user clicks on the screen


import collections
import os
import xml.etree.ElementTree as ET
from PIL import Image

def convert_to_voc_format(annotations_path, image_sets_path, origin_images_path, origin_annotations_path,
                          class_names_path):
    category_id_to_name_dict = category_id_to_name(class_names_path)
    # 获取原始标注路径
    filenames_list = os.listdir(origin_annotations_path)
    image_sets_list = [filename.split('.')[0] + '\n' for filename in filenames_list]
    with open(image_sets_path, 'w') as f:
        f.writelines(image_sets_list)
    filenames_list = [os.path.join(origin_annotations_path, filename) for filename in filenames_list]
    for filename in filenames_list:
        # 获取原始标注信息
        xml_folder = 'name of dataset'
        xml_filename = filename.split(os.sep)[-1].split('.')[0] + '.jpg'
        xml_segmented = '0'
        image_path = os.path.join(origin_images_path, xml_filename)
        image = Image.open(image_path)
        xml_width, xml_height = image.size
        xml_width = str(xml_width)
        xml_height = str(xml_height)
        xml_depth = '3'
        xml_objects = []
        xml_pose = 'Unspecified'
        xml_truncated = '0'
        xml_difficult = '0'
        with open(filename, 'r') as f:
            bboxes_cats = f.readlines()
        for bbox_cat in bboxes_cats:
            # 15 0.980000 0.445266 0.500000 0.399408
            if len(bbox_cat.strip()) > 0:
                xml_objects.append(bbox_cat.strip())
        # 创建voc format xml 文件
        annotation = ET.Element('annotation')
        tree = ET.ElementTree(annotation)
        folder = ET.Element('folder')
        folder.text = xml_folder
        et_filename = ET.Element('filename')
        et_filename.text = xml_filename
        size = ET.Element('size')
        width = ET.Element('width')
        height = ET.Element('height')
        depth = ET.Element('depth')
        width.text = xml_width
        height.text = xml_height
        depth.text = xml_depth
        size.append(width), size.append(height), size.append(depth)
        segmented = ET.Element('segmented')
        segmented.text = xml_segmented
        annotation.append(folder), annotation.append(et_filename)
        annotation.append(size), annotation.append(segmented)
        for xml_object in xml_objects:
            et_object = ET.Element('object')
            name = ET.Element('name')
            name.text = category_id_to_name_dict[xml_object.split(' ')[0]]
            pose = ET.Element('pose')
            pose.text = xml_pose
            truncated = ET.Element('truncated')
            truncated.text = xml_truncated
            difficult = ET.Element('difficult')
            difficult.text = xml_difficult
            bndbox = ET.Element('bndbox')
            xmin = ET.Element('xmin')
            x_center = float(xml_object.split(' ')[1]) * float(xml_width)
            y_center = float(xml_object.split(' ')[2]) * float(xml_height)
            image_width = float(xml_object.split(' ')[3]) * float(xml_width)
            image_height = float(xml_object.split(' ')[4]) * float(xml_height)
            xmin.text = '{:.6f}'.format(x_center - image_width / 2)
            ymin = ET.Element('ymin')
            ymin.text = '{:.6f}'.format(y_center - image_height / 2)
            xmax = ET.Element('xmax')
            xmax.text = '{:.6f}'.format(x_center + image_width / 2)
            ymax = ET.Element('ymax')
            ymax.text = '{:.6f}'.format(y_center + image_height / 2)
            bndbox.append(xmin), bndbox.append(ymin)
            bndbox.append(xmax), bndbox.append(ymax)
            et_object.append(name), et_object.append(pose), et_object.append(truncated)
            et_object.append(difficult), et_object.append(bndbox)
            annotation.append(et_object)
        __indent(annotation)
        xml_path = os.path.join(annotations_path, filename.split(os.sep)[-1].split('.')[0] + '.xml')
        tree.write(xml_path, encoding='utf-8', xml_declaration=True)

# 创建xml缩进
def __indent(elem, level=0):
    """
    Confirm the right format of xml file.
    Args:
        elem: root.
        level: level of current node.

    Returns: right format of xml file.

    """
    i = "\n" + level * "\t"
    if len(elem):
        if not elem.text or not elem.text.strip():
            elem.text = i + "\t"
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
        for elem in elem:
            __indent(elem, level + 1)
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
    else:
        if level and (not elem.tail or not elem.tail.strip()):
            elem.tail = i

def category_id_to_name(class_names_path):
    with open(class_names_path, 'r') as f:
        classes_names = f.readlines()
    category_id_to_name_dict = collections.OrderedDict()
    for i, class_name in enumerate(classes_names):
        category_id_to_name_dict[str(i)] = class_name.strip()

    return category_id_to_name_dict

if __name__ == '__main__':
    mode = 'train'
    annotations_path = '../bbox_detection/data_dataset_voc/Annotations'
    image_sets_path = f'../bbox_detection/data_dataset_voc/ImageSets/Main/{mode}.txt'
    origin_images_path = f'../bbox_detection/data_dataset_yolo/{mode}'
    origin_annotations_path = f'../bbox_detection/data_dataset_yolo/{mode}_annotations'
    class_name_path = '../bbox_detection/data_dataset_yolo/class_names.txt'
    convert_to_voc_format(annotations_path, image_sets_path, origin_images_path, origin_annotations_path,
                          class_name_path)


"""
Experiment 4

Check wether diff needs decimals
"""

import options
import os, sqlite3, sys,  time, random
import math
from decimal import *
from quantizer import *
import essentials
from random import shuffle

print(getcontext())

config = options.Get()
config.read()

genesis_conf = config.genesis_conf
ledger_path_conf = config.ledger_path_conf

def db_h_define():
    hdd = sqlite3.connect(ledger_path_conf, timeout=1)
    hdd.text_factory = str
    h = hdd.cursor()
    hdd.execute("PRAGMA page_size = 4096;")
    return hdd, h

def execute(cursor, query):
    """Secure execute for slow nodes"""
    while True:
        try:
            cursor.execute(query)
            break
        except Exception as e:
            print("Database query: {} {}".format(cursor, query))
            print("Database retry reason: {}".format(e))
    return cursor

def execute_param(cursor, query, param):
    """Secure execute w/ param for slow nodes"""
    while True:
        try:
            cursor.execute(query, param)
            break
        except Exception as e:
            print("Database query: {} {} {}".format(cursor, query, param))
            print("Database retry reason: {}".format(e))
            time.sleep(random.random())
    return cursor

def difficulty(c, block_height):
    """ Node diff function for a given blockheight"""
    global timestamp_last
    global timestamp_before_last
    global timestamp_1441
    global timestamp_1440
    global diff_block_previous

    try:

        execute_param(c, "SELECT * FROM transactions WHERE reward != 0 AND block_height <= ? ORDER BY block_height DESC LIMIT 2", (block_height,))
        result = c.fetchone()
        timestamp_last = Decimal(result[1])
        block_height = int(result[0])
        previous = c.fetchone()
        # Failsafe for regtest starting at block 1}
        timestamp_before_last = timestamp_last if previous is None else Decimal(previous[1])

        execute_param(c, ("SELECT timestamp FROM transactions WHERE CAST(block_height AS INTEGER) > ? AND reward != 0 ORDER BY timestamp ASC LIMIT 2"), (block_height - 1441,))
        timestamp_1441 = Decimal(c.fetchone()[0])
        block_time_prev = (timestamp_before_last - timestamp_1441) / 1440
        temp = c.fetchone()
        timestamp_1440 = timestamp_1441 if temp is None else Decimal(temp[0])
        block_time = Decimal(timestamp_last - timestamp_1440) / 1440
        execute_param(c, "SELECT difficulty FROM misc WHERE block_height = ?", (block_height,))
        diff_block_previous = Decimal(c.fetchone()[0])

        time_to_generate = timestamp_last - timestamp_before_last

        hashrate = pow(2, diff_block_previous / Decimal(2.0)) / (
            block_time * math.ceil(28 - diff_block_previous / Decimal(16.0)))
        # Calculate new difficulty for desired blocktime of 60 seconds
        target = Decimal(60.00)
        ##D0 = diff_block_previous
        difficulty_new = Decimal((2 / math.log(2)) * math.log(hashrate * target * math.ceil(28 - diff_block_previous / Decimal(16.0))))
        # Feedback controller
        Kd = 10
        difficulty_new = difficulty_new - Kd * (block_time - block_time_prev)
        diff_adjustment = (difficulty_new - diff_block_previous) / 720  # reduce by factor of 720

        if diff_adjustment > Decimal(1.0):
            diff_adjustment = Decimal(1.0)

        difficulty_new_adjusted = quantize_ten(diff_block_previous + diff_adjustment)
        difficulty = difficulty_new_adjusted

        diff_drop_time = Decimal(180)

        diff_dropped = difficulty
        """
        if Decimal(time.time()) > Decimal(timestamp_last) + Decimal(2*diff_drop_time):
            # Emergency diff drop
            time_difference = quantize_two(time.time()) - quantize_two(timestamp_last)
            diff_dropped = quantize_ten(difficulty) - quantize_ten(1) \
                           - quantize_ten(10 * (time_difference-2 * diff_drop_time) / diff_drop_time)
        elif Decimal(time.time()) > Decimal(timestamp_last) + Decimal(diff_drop_time):
            time_difference = quantize_two(time.time()) - quantize_two(timestamp_last)
            diff_dropped = quantize_ten(difficulty) + quantize_ten(1) - quantize_ten(time_difference / diff_drop_time)
        """

        if difficulty < 50:
            difficulty = 50
        if diff_dropped < 50:
            diff_dropped = 50

        return (
            float('%.10f' % difficulty), float('%.10f' % diff_dropped), float(time_to_generate), float(diff_block_previous),
            float(block_time), float(hashrate), float(diff_adjustment),
            block_height)  # need to keep float here for database inserts support

    except Exception as e:
        print("error: {}".format(e))
        exc_type, exc_obj, exc_tb = sys.exc_info()
        fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
        print(exc_type, fname, exc_tb.tb_lineno)

def difficulty2(c, block_height):
    """ Node diff function for a given blockheight"""
    global timestamp_last
    global timestamp_before_last
    global timestamp_1441
    global timestamp_1440
    global diff_block_previous

    try:

        block_time_prev = (timestamp_before_last - timestamp_1441) / 1440
        block_time = (timestamp_last - timestamp_1440) / 1440

        time_to_generate = timestamp_last - timestamp_before_last

        hashrate = pow(2, diff_block_previous / 2) / (
            block_time * math.ceil(28 - diff_block_previous / 16.0))
        # Calculate new difficulty for desired blocktime of 60 seconds
        target = 60
        ##D0 = diff_block_previous
        difficulty_new = (2 / math.log(2)) * math.log(hashrate * target * math.ceil(28 - diff_block_previous / 16))
        # Feedback controller
        Kd = 10
        difficulty_new = difficulty_new - Kd * (block_time - block_time_prev)
        diff_adjustment = (difficulty_new - diff_block_previous) / 720  # reduce by factor of 720

        if diff_adjustment > 1:
            diff_adjustment = 1.0

        difficulty_new_adjusted = diff_block_previous + diff_adjustment
        difficulty = difficulty_new_adjusted

        diff_drop_time = 180

        diff_dropped = difficulty
        """
        if Decimal(time.time()) > Decimal(timestamp_last) + Decimal(2*diff_drop_time):
            # Emergency diff drop
            time_difference = quantize_two(time.time()) - quantize_two(timestamp_last)
            diff_dropped = quantize_ten(difficulty) - quantize_ten(1) \
                           - quantize_ten(10 * (time_difference-2 * diff_drop_time) / diff_drop_time)
        elif Decimal(time.time()) > Decimal(timestamp_last) + Decimal(diff_drop_time):
            time_difference = quantize_two(time.time()) - quantize_two(timestamp_last)
            diff_dropped = quantize_ten(difficulty) + quantize_ten(1) - quantize_ten(time_difference / diff_drop_time)
        """

        if difficulty < 50:
            difficulty = 50
        if diff_dropped < 50:
            diff_dropped = 50

        return (
            float('%.10f' % difficulty), float('%.10f' % diff_dropped), float(time_to_generate), float(diff_block_previous),
            float(block_time), float(hashrate), float(diff_adjustment),
            block_height)  # need to keep float here for database inserts support

    except Exception as e:
        print("error: {}".format(e))
        exc_type, exc_obj, exc_tb = sys.exc_info()
        fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
        print(exc_type, fname, exc_tb.tb_lineno)

def check():
    global timestamp_last
    global timestamp_before_last
    global timestamp_1441
    global timestamp_1440
    global diff_block_previous
    for block in range(231560, 231560+100000):
        diff1 = difficulty(h, block)
        timestamp_last = float(timestamp_last)
        timestamp_before_last = float(timestamp_before_last)
        timestamp_1441 = float(timestamp_1441)
        timestamp_1440 = float(timestamp_1440)
        diff_block_previous = float(diff_block_previous)
        diff2 = difficulty2(h, block)
        if diff1[0] != diff2[0]:
            print("{}: {} {}".format(block, diff1[0], diff2[0]))

if __name__ == "__main__":
    # Ledger
    hdd, h = db_h_define()
    ERRORS = 0

    VERBOSE = False

    print("Selecting blocks from 231560")
    # execute(h, ("SELECT distinct(recipient) FROM transactions2 group by recipient;"))
    # result = h.fetchall()
    check()


# Write a program to implement job assignment problem using branch and bound
import sys
import heapq

class JobAssignmentProblem:
    def __init__(self, cost_matrix):
        # Initialize the problem with the given cost matrix
        self.cost_matrix = cost_matrix
        self.num_rows = len(cost_matrix)  # Number of workers (rows)
        self.num_cols = len(cost_matrix[0])  # Number of jobs (columns)
        self.best_solution = None  # Best assignment found so far
        self.best_cost = sys.maxsize  # Cost of the best assignment

    def calculate_lower_bound(self, start_row):
        # Calculate a lower bound for the remaining unassigned rows
        lower_bound = 0
        for i in range(start_row, self.num_rows):
            # Find the minimum cost in each row and add it to the lower bound
            min_cost = min(self.cost_matrix[i])
            lower_bound += min_cost
        return lower_bound

    def branch_and_bound(self):
        priority_queue = [
            (0, [], 0)
        ]  # Priority queue to store nodes (cost, assignment, row_index)

        while priority_queue:
            current_cost, current_assignment, row_index = heapq.heappop(priority_queue)

            # If the assignment is complete for all rows, check if it's better than the best solution
            if row_index == self.num_rows:
                if current_cost < self.best_cost:
                    self.best_solution = current_assignment
                    self.best_cost = current_cost
                continue

            # Calculate a lower bound for the current node
            lower_bound = current_cost + self.calculate_lower_bound(row_index)

            # If the lower bound is greater than or equal to the best cost, prune this node
            if lower_bound >= self.best_cost:
                continue

            # Branch into each column for the current row
            for col_index in range(self.num_cols):
                if col_index not in current_assignment:
                    new_cost = current_cost + self.cost_matrix[row_index][col_index]
                    new_assignment = current_assignment + [col_index]
                    heapq.heappush(
                        priority_queue, (new_cost, new_assignment, row_index + 1)
                    )

    def find_optimal_assignment(self):
        # Start the branch and bound process
        self.branch_and_bound()
        return self.best_solution, self.best_cost

if __name__ == "__main__":
    # Example cost matrix representing the cost of assigning each worker to each job
    cost_matrix = [[9, 2, 7, 8], [6, 4, 3, 7], [5, 8, 1, 8], [7, 6, 9, 4]]

    # Create an instance of the JobAssignmentProblem class
    job_assignment_problem = JobAssignmentProblem(cost_matrix)

    # Find the optimal assignment and its cost
    solution, cost = job_assignment_problem.find_optimal_assignment()

    # Print the results
    print("Optimal Assignment:", solution)
    print("Total Cost:", cost)


# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]:
        ans = node = ListNode(0)
        ans.next = head
        while head and head.next:
            if head.val == head.next.val:
                while head and head.next and head.val == head.next.val:
                    head = head.next
                head = head.next
                node.next = head
            else:
                node = node.next
                head = head.next
        return ans.next


from django.urls import path
from . import views

urlpatterns = [
    path('', views.home_view, name=''),
    path('login', views.login, name='login'),
    path("signup/", views.signup, name="signup"),
    path('home', views.home_view, name='home'),
    path('user', views.user_homepage_view, name='user'),
    path('artisan', views.artisan_homepage_view, name='artisan'),
    path('submit_request/', views.submit_request, name='submit_request'),
    path('submit_feedback/', views.submit_feedback, name='submit_feedback'),
    path('logout/', views.logout_view, name='logout'),
    path('get-artisans/', views.get_artisans, name='get_artisans'),
    path('get_requests_and_feedback/', views.get_requests_and_feedback, name='get_requests_and_feedback'),
]


from fuzzyfinder import fuzzyfinder
from prompt_toolkit import prompt
from prompt_toolkit.history import FileHistory
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
from prompt_toolkit.completion import Completer, Completion
from scistash.database.sqlitedb import SQLiteHandler
from scistash.database.memorydb import MemoryDBHandler
from scistash.entities.author import Author
from scistash.entities.article import Article
from scistash.entities.annotation import Annotation
import click
import uuid

class StashCompleter(Completer):
    def __init__(self):
        self.__vocabulary = ''

    def setvocab(self, vocabulary):
        self.__vocabulary = vocabulary

    def get_completions(self, document, complete_event):
        word_before_cursor = document.get_word_before_cursor(WORD=True)
        matches = fuzzyfinder(word_before_cursor, self.__vocabulary)
        for m in matches:
            yield Completion(m, start_position=-len(word_before_cursor))

class ReplHandler:
    levels = {
        'stash': {
            'current': {
                'id': 'curr_id',                        # DONE
                'fetch': 'curr_fetch',                  # DONE
                'show': 'curr_show',                    # DONE
                'save': 'curr_save',                    # DONE
                'scratch': 'curr_scratch',              # DONE
                'edit': 'curr_edit',
                'annotate': 'curr_annot',
                'tag': {
                    'add': 'curr_tag_add',
                    'rem': 'curr_tag_rem',
                    'show': 'curr_tag_show'
                },
                'file': {
                    'add': 'curr_file_add',
                    'rem': 'curr_file_rem',
                    'show': 'curr_file_show',
                },
                'ref': {
                    'add': 'curr_att_rky_add',
                    'rem': 'curr_att_rky_rem',
                    'show': 'curr_att_rky_show'
                }
            },
            'pending': {
                'show': 'pend_show',                    # DONE
                'scratch' : 'pend_scratch',             # DONE
                'scratchall': 'pend_scratch_all',       # DONE
                'save': 'pend_save',                    # DONE
                'checkout': {
                    'author': 'pend_chko_auth',         # DONE
                    'article': 'pend_chko_art',         # DONE
                    'annotation': 'pend_chko_annot',    # DONE
                }
            },
            'authors': {
                'new': 'auth_new',                      # DONE
                'checkout': 'auth_checkout',
                'delete': 'auth_delete',
                'find': {
                    'uuid': 'auth_find_uuid',
                    'year': 'auth_find_year',
                    'fname': 'auth_find_fname',
                    'lname': 'auth_find_lname',
                    'title': 'auth_find_title'
                },
            },
            'articles': {
                'find': {
                    'refkey': 'art_find_refkey',
                    'fname': 'art_find_fname',
                    'lname': 'art_find_lname',
                    'year': 'art_find_year',
                    'title': 'art_find_title'
                },
                'new': 'art_new',
                'checkout': 'art_checkout',
                'delete': 'art_delete',
                'cite': {
                    'bibtex': 'art_cite_bibtex',
                    'apa': 'art_cite_apa'
                },
                'retract': 'art_retract'
            },
            'annotations': {
                'new': 'annot_new',
                'checkout': 'annot_checkout',
                'delete': 'annot_delete',
                'find': {
                    'annotkey': 'annot_find_annotkey',
                    'refkey': 'annot_find_refkey',
                    'fname': 'annot_find_fname',
                    'lname': 'annot_find_lname',
                    'year': 'annot_find_year',
                    'title': 'annot_find_title'
                },
            },
            'sdb': {
                'list': {
                    'authors': 'sdb_list_auths',        # DONE
                    'articles': 'sdb_list_arts',        # DONE
                    'annots': 'sdb_list_annots',        # DONE
                    'tags': 'sdb_list_tags',            # DONE
                    'files': 'sdb_list_files',          # DONE
                    'refs': 'sdb_list_refs'             # DONE
                },
                'stats': 'sdb_stats',
                'dump': {
                    'csv': 'sdb_dump_csv',
                    'sql': 'sdb_dump_sql',
                    'bibtex': 'sdb_dump_bibtex',
                    'apa': 'sdb_dump_apa'
                },
                'import': 'sdb_import'
            },
            'help': 'meta',
            'clear': 'meta',                        # DONE
            'end': 'meta',                          # DONE
            'top': 'meta',                          # DONE
            'quit': 'meta'                          # DONE
        }
    }

    def __init__(self, db, dryrun=False, create=True, memquota=0):
        click.echo(click.style('Scientific Reference Stasher', fg='green', bold=True))
        click.echo('Santiago Núñez-Corrales <nunezco2@illinois.edu>\n')
        click.echo('For available commands, enter \'help\' into the REPL.\n')
        # Database handlers
        self.__pending = MemoryDBHandler(memquota)
        self.__db = SQLiteHandler(db, dryrun, create)
        self.__createdb = create
        # Contextual and fetch hashes
        self.__fetchhash = self.__db.buildfetchhash()
        self.__cntxhash = self.__db.buildcontexthash()
        # Operation stack handler
        self.__opstack = ['stash']
        # Prompt handler
        self.__scomp = StashCompleter()
        self.__scomp.setvocab(self.levels.get('stash').keys())
        self.__currprompt = ''
        self.__current = None
    @property
    def db(self):
        return self.__db

    @property
    def current(self):
        return self.__current

    @current.setter
    def current(self, val):
        self.__pending.put(self.current, self.__fetchhash)
        self.__current = val

    def makeprompt(self):
        if len(self.__opstack) == 1:
            self.__currprompt = self.__opstack[0]
        elif len(self.__opstack) == 2:
            self.__currprompt = '{0}|{1}'.format(self.__opstack[0], self.__opstack[1])
        else:
            self.__currprompt = '|'.join(self.__opstack)

    def opstacktolevel(self):
        out = self.levels

        for i in self.__opstack:
            out = out.get(i)

        return out

    def run(self):
        while True:
            # Set the prompt based on the operation stack
            self.makeprompt()
            self.__scomp.setvocab(self.opstacktolevel())
            user_input = prompt(self.__currprompt + '> ',
                                history=FileHistory('history.stash'),
                                auto_suggest=AutoSuggestFromHistory(),
                                completer=self.__scomp)
            self.process_input(user_input.split())

    def process_input(self, user_input):
        if not user_input:
            return
        if user_input[0] == 'quit':
            # TODO: when changes are pending or database is open, ask user to resolve
            self.__db.close()
            click.echo(click.style('Exiting.', fg='magenta'))
            quit()
        elif user_input[0] == 'clear':
            click.clear()
        elif user_input[0] == 'top':
            self.__opstack = ['stash']
        elif user_input[0] == 'help':
            outtext = """
            \x1b[1m\x1b[32mScientific Reference Stasher\x1b[0m\x1b[0m
            \x1b[32mHelp Manual\x1b[0m

            \x1b[32mGeneral commands\x1b[0m

               \x1b[1mCommand\x1b[0m            \x1b[1mFunction\x1b[0m
                quit                Exit the interpreter
                clear               Clear the current screen
                curr                Display current data object under modification
                help                Display this help
                end                 Exit most immediate context (right-most in prompt)

            \x1b[32mAuthor\x1b[0m

               \x1b[1mCommand\x1b[0m            \x1b[1mFunction\x1b[0m
                list                List current authors
                new                 Add new author
                edit                Change information about an author
                find                Search an author
                save                Save information of the most recently updated author
            """
            click.echo_via_pager(outtext)
        elif user_input[0] == 'end':
            if len(self.__opstack) is 1:
                click.echo(click.style('Already at top level.', fg='magenta'))
            else:
                self.__opstack = self.__opstack[:-1]
        else:
            # Process each command depending on where the last runnable command stops
            def recursiveparse(level, cmdlist, context):
                # Case 1: the list has been exhausted with a non-executable command path
                if not cmdlist:
                    return context, 'none', [], level.keys()
                # Case 2: we have either a keyword that does not exhaust the terms or an unknown term
                elif len(cmdlist) == 1:
                    # Check if it is a valid command, i.e. in the current keys of the dictionary
                    if cmdlist[0] in list(level.keys()):
                        if type(level.get(cmdlist[0])) is str:
                            # This is an executable command
                            return context, level.get(cmdlist[0]), [], level.keys()
                        else:
                            # This is a non-executable command
                            return context + [cmdlist[0]], 'none', [], level.get(cmdlist[0]).keys()
                    else:
                        # Not a valid command or parameter
                        return context, 'none', [], level.keys()
                # Case 3: we have more elements, in which one is in the non-executable command path and the second is
                else:
                    # Check if the first parameter is a command
                    if not cmdlist[0] in list(level.keys()):
                        # Not a valid command or parameter
                        return context, 'none', [], level.keys()
                    # Check if the first parameter is an executable command
                    elif type(level.get(cmdlist[0])) is str:
                        return context, level.get(cmdlist[0]), cmdlist[1:], level.keys()
                    # Check if the second element is a valid keyword
                    elif not cmdlist[1] in list(level.get(cmdlist[0]).keys()):
                        return context, 'none', [], level.keys()
                    # Check if the second element is an executable command (no children)
                    elif type(level.get(cmdlist[0]).get(cmdlist[1])) is str:
                        return context+[cmdlist[0]], level.get(cmdlist[0]).get(cmdlist[1]), cmdlist[2:], \
                               level.get(cmdlist[0]).keys()
                    else:
                        # All other cases
                        return recursiveparse(level.get(cmdlist[0]), cmdlist[1:], context + [cmdlist[0]])

            ctx, cmd, args, voc = recursiveparse(self.opstacktolevel(), user_input, [])

            if (not ctx) and (cmd == 'none') and (not args):
                click.echo(click.style('Command not valid in this context.', fg='red'))
            else:
                if cmd != 'none':
                    self.dispatch(cmd, args)
                else:
                    self.__opstack += ctx

    # Implementation of each command
    def dispatch(self, cmd, args):
        ###########################################
        # Current
        ###########################################
        if cmd == 'curr_id':
            self.__dispatch_curr_id(args)
        elif cmd == 'curr_fetch':
            self.__dispatch_curr_fetch(args)
        elif cmd == 'curr_show':
            self.__dispatch_curr_show(args)
        elif cmd == 'curr_save':
            self.__dispatch_curr_save(args)
        elif cmd == 'curr_scratch':
            self.__dispatch_curr_scratch(args)
        ###########################################
        # Pending
        ###########################################
        elif cmd == 'pend_show':
            self.__dispatch_pend_show(args)
        elif cmd == 'pend_scratch':
            self.__dispatch_pend_scratch(args)
        elif cmd == 'pend_scratch_all':
            self.__dispatch_pend_scratch_all(args)
        elif cmd == 'pend_save':
            self.__dispatch_pend_save(args)
        elif cmd == 'pend_chko_auth':
            self.__dispatch_pend_chko_auth(args)
        elif cmd == 'pend_chko_art':
            self.__dispatch_pend_chko_art(args)
        elif cmd == 'pend_chko_annot':
            self.__dispatch_pend_chko_annot(args)
        ###########################################
        # Authors
        ###########################################
        elif cmd == 'auth_new':
            self.__dispatch_auth_new(args)
        elif cmd == 'auth_new':
            self.__dispatch_auth_new(args)
        ###########################################
        # SDB
        ###########################################
        elif cmd == 'sdb_list_auths':
            self.__dispatch_sdb_list_auths(args)
        elif cmd == 'sdb_list_arts':
            self.__dispatch_sdb_list_arts(args)
        elif cmd == 'sdb_list_annots':
            self.__dispatch_sdb_list_annots(args)
        elif cmd == 'sdb_list_tags':
            self.__dispatch_sdb_list_tags(args)
        elif cmd == 'sdb_list_files':
            self.__dispatch_sdb_list_files(args)
        elif cmd == 'sdb_list_refs':
            self.__dispatch_sdb_list_refs(args)
        else:
            pass

    ###########################################
    # Current
    ###########################################

    def __dispatch_curr_id(self, args):
        if self.current is None:
            click.echo(click.style('No current working element has been set.', fg='magenta'))
        else:
            click.echo(click.style('ID of current working element:\t{0}'.format(self.current.id), fg='blue'))

    def __dispatch_curr_fetch(self, args: list):
        if not args:
            user_input = prompt('Entity identifier: ',
                                completer=self.__cntxhash.values())
            args.append(user_input.split()[0])

        try:
            obj = self.__db.object_fetch(uuid.UUID(args[0]), self.__fetchhash[uuid.UUID(args[0])])
        except Exception as e:
            click.echo(click.style('Malformed uuid ({0}).'.format(e), fg='red'))
            obj = None

        if obj is not None:
            self.current = obj

    def __dispatch_curr_show(self, args):
        if self.current is None:
            click.echo(click.style('No current working element has been set.', fg='magenta'))
        else:
            if type(self.current) is Author:
                currtype = 'Author'
            elif type(self.current) is Article:
                currtype = 'Article'
            elif type(self.current) is Annotation:
                currtype = 'Annotation'
            else:
                currtype = 'Unknown'

            click.echo(click.style('Current: {}\n'.format(currtype), fg='blue') + str(self.current))

    def __dispatch_curr_save(self, args):
        if self.current is not None:
            # Saving takes care of the fetch hash per object type
            self.__db.save(self.current, self.__fetchhash)
            self.current = None
        else:
            click.echo(click.style('No current working element has been set.', fg='magenta'))

    def __dispatch_curr_scratch(self, args):
        if self.current is not None:
            self.current = None

    def __editauthor(self, args, prmpt=False):
        if prmpt:
            # Horrible Python shortcoming. This should be a do...while structure.
            while True:
                click.echo(self.current)
                message = '''
                Edit author:
                ============
                [1] Change first name
                [2] Change last name

                [0] Exit editor

                '''
                click.echo(message)
                choice = click.prompt('Your edit choice: ', type=int)

                if choice == 0:
                    return
                elif choice == 1:
                    fname = click.prompt('Enter the new first name: ', type=str)
                    self.current.firstname = fname
                elif choice == 2:
                    lname = click.prompt('Enter the new last name: ', type=str)
                    self.current.lastname = lname
                else:
                    click.echo(click.style('Unrecognized option.', fg='red'))
        else:
            fields = ['firstname', 'lastname']
            for i in range(0, len(args), 2):
                if args[i] not in fields:
                    click.echo(click.style(f'Unrecognized field {args[i]}.', fg='red'))
                else:
                    pass

    def __editarticle(self, args, prmpt=False):
        if prmpt:
            # Horrible Python shortcoming. This should be a do...while structure.
            while True:
                click.echo(self.current)
                message = '''
                Edit article:
                =============
                [1] Change refkey
                [2] Change year
                [3] Change title
                [4] Change journal
                [5] Change volume
                [6] Change number
                [7] Change pages
                [8] Add author to article
                [9] Delete author from article

                [0] Exit editor

                '''
                click.echo(message)
                choice = click.prompt('Your edit choice: ', type=int)

                if choice == 0:
                    return
                elif choice == 1:
                    rkey = click.prompt('Enter the new refkey: ', type=str)
                    self.current.refkey = rkey
                elif choice == 2:
                    yr = click.prompt('Enter the new year: ', type=str)
                    self.current.year = yr
                elif choice == 3:
                    ttl = click.prompt('Enter the new title: ', type=str)
                    self.current.title = ttl
                elif choice == 4:
                    jrnl = click.prompt('Enter the new journal: ', type=str)
                    self.current.journal = jrnl
                elif choice == 5:
                    vlm = click.prompt('Enter the new volume: ', type=str)
                    self.current.volume = vlm
                elif choice == 6:
                    nmbr = click.prompt('Enter the new number: ', type=str)
                    self.current.number = nmbr
                elif choice == 7:
                    pgs_txt = (click.prompt('Enter the new pages (start-end): ', type=str)).split('-')
                    if len(pgs_txt) != 2:
                        click.echo(click.style('Wrong pages input format.', fg='red'))
                    else:
                        self.current.pages = (pgs_txt[0], pgs_txt[1])
                elif choice == 8:
                    auuid = click.prompt('Enter the new author uuid: ', type=str)

                    # Case 1: search in pending
                    if self.__pending.exists_fetch(auuid, Author):
                        author = self.__pending.object_fetch(auuid, Author)
                    # Case 2: search in DB, add to pending (in case modifications are needed)
                    elif self.__db.exists_fetch(auuid, Author):
                        author = self.__db.object_fetch(auuid, Author)
                        self.__pending.put(author, self.__fetchhash)
                    # Case 3: create a new author from scratch and add it
                    else:
                        fname = prompt('First name: ')
                        lname = prompt('Last name: ')
                        author = Author(fname, lname, False)
                        self.__pending.put(author, self.__fetchhash)
                    if not self.current.authors.addauthor(author):
                        click.echo(click.style('Author has already been associated with this article.', fg='magenta'))
                elif choice == 9:
                    nmbr = click.prompt('Enter the new author uuid: ', type=str)

                    self.current.number = nmbr
                else:
                    click.echo(click.style('Unrecognized option.', fg='red'))
        else:
            fields = ['refkey', 'year', 'title', 'journal', 'volume', 'number', 'pages']
            for i in range(0, len(args), 2):
                if args[i] not in fields:
                    click.echo(click.style(f'Unrecognized field {args[i]}.', fg='red'))
                else:
                    pass

    def __editannotation(self, args, prmpt=False):
        if prmpt:
            # Horrible Python shortcoming. This should be a do...while structure.
            while True:
                click.echo(self.current)
                message = '''
                Edit annotation:
                ============
                [1] Change summary
                [2] Change information

                [0] Exit editor

                '''
                click.echo(message)
                choice = click.prompt('Your edit choice: ', type=int)

                if choice == 0:
                    return
                elif choice == 1:
                    smry = click.prompt('Enter the new summary: ', type=str)
                    self.current.summary = smry
                elif choice == 2:
                    info = click.edit('Enter the new information: ')
                    self.current.info = info
                else:
                    click.echo(click.style('Unrecognized option.', fg='red'))
        else:
            fields = ['summary', 'info']
            for i in range(0, len(args), 2):
                if args[i] not in fields:
                    click.echo(click.style(f'Unrecognized field {args[i]}.', fg='red'))
                else:
                    pass

    def __dispatch_curr_edit(self, args):
        if self.current is not None:
            prmpt = False
            editable = {
                Author: self.__editauthor,
                Article: self.__editarticle,
                Annotation: self.__editannotation
            }

            if type(self.current) not in editable.keys():
                click.echo(click.style('Tags, files and references can only be added or deleted.', fg='red'))
                return

            if not args:
                prmpt = True
            else:
                if len(args) % 2 != 0:
                    click.echo(click.style('Malformed argument list.', fg='red'))
                    return

            editable[type(self.current)](args, prmpt)

        else:
            click.echo(click.style('No current working element has been set.', fg='magenta'))

    ###########################################
    # Pending
    ###########################################

    def __dispatch_pend_show(self, args):
        if not args:
            self.__pending.show('all')
        else:
            self.__pending.show(args[0])

    def __dispatch_pend_scratch(self, args):
        self.__pending.scratch(self.__fetchhash)

    def __dispatch_pend_scratch_all(self, args):
        self.__pending.scratchall(self.__fetchhash)

    def __dispatch_pend_save(self, args):
        if not args:
            self.__pending.save('all', self.__db, self.__fetchhash)
        else:
            self.__pending.save(args[0], self.__db, self.__fetchhash)

    def __dispatch_pend_chko_auth(self, args):
        data = self.__pending.checkout_fetch(args[0], Author, self.__fetchhash)
        if data is not None:
            self.current = data
        else:
            click.echo(click.style(f'Author with UUID { args[0] } does not exist.', fg='magenta'))

    def __dispatch_pend_chko_art(self, args):
        data = self.__pending.checkout_fetch(args[0], Article, self.__fetchhash)
        if data is not None:
            self.current = data
        else:
            click.echo(click.style(f'Article with UUID {args[0]} does not exist.', fg='magenta'))

    def __dispatch_pend_chko_annot(self, args):
        data = self.__pending.checkout_fetch(args[0], Annotation, self.__fetchhash)
        if data is not None:
            self.current = data
        else:
            click.echo(click.style(f'Annotation with UUID {args[0]} does not exist.', fg='magenta'))

    ###########################################
    # Authors
    ###########################################

    def __dispatch_auth_new(self, args):
        if args:
            auth = Author(args[0], args[1], False)
            self.current = auth
            click.echo(click.style('New author created.', fg='blue'))
        else:
            fname = prompt('First name: ')
            lname = prompt('Last name: ')
            auth = Author(fname, lname, False)
            self.current = auth
            click.echo(click.style('New author created.', fg='blue'))

    ###########################################
    # SDB
    ###########################################

    def __dispatch_sdb_list_auths(self, args):
        outcome = self.__db.list('authors')

        if outcome is not None:
            click.echo_via_pager(outcome)

    def __dispatch_sdb_list_arts(self, args):
        outcome = self.__db.list('articles')

        if outcome is not None:
            click.echo_via_pager(outcome)

    def __dispatch_sdb_list_annots(self, args):
        outcome = self.__db.list('annotations')

        if outcome is not None:
            click.echo_via_pager(outcome)

    def __dispatch_sdb_list_tags(self, args):
        outcome = self.__db.list('tags')

        if outcome is not None:
            click.echo_via_pager(outcome)

    def __dispatch_sdb_list_files(self, args):
        outcome = self.__db.list('files')

        if outcome is not None:
            click.echo_via_pager(outcome)

    def __dispatch_sdb_list_refs(self, args):
        outcome = self.__db.list('refs')

        if outcome is not None:
            click.echo_via_pager(outcome)


class Bill:
    """
    Object that contains data about a bill, such as
    total amount and period of the bill.
    """

    def __init__(self, amount, period_month):
        self.amount = amount
        self.period_month = period_month

class Flatmate:
    """
    Creates a flatmate person who lives in the flat
    and pays a share of the bill.
    """

    def __init__(self, name, days_in_house):
        self.name = name
        self.days_in_house = days_in_house

    def pays(self, bill, *flatmates): # *flatmates gives a tuple, that's why we need a for loop
        total_days_in_house = 0  # total_days_in_house__of_all_other_flatmates
        for flatmate in flatmates:
            total_days_in_house =  total_days_in_house + flatmate.days_in_house
        real_total_days = self.days_in_house + total_days_in_house
        total_amount = bill.amount
        days_coefficient = self.days_in_house / real_total_days
        amount_to_be_paid = days_coefficient * total_amount
        amount_to_be_paid = round(amount_to_be_paid, 2)
        return amount_to_be_paid


from mylib import euler_prime

primes = euler_prime(2 * 10**7)

def count(n, p):
    res = 0
    while n > 0:
        n //= p
        res += n
    return res

def solve(n, k):
    res = 0
    for p in primes:
        m = count(n, p) - count(k, p) - count(n - k, p)
        res += m * p
    print(res)

if __name__ == '__main__':
    solve(2 * 10**7, 5 * 10**6)


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

from telldus import Device
from .Protocol import Protocol

class ProtocolUpm(Protocol):

	@staticmethod
	def methods():
		return Device.TURNON | Device.TURNOFF

	# pylint: disable=C0103
	def stringForMethod(self, method, data=None):
		del data
		S = ';'
		L = '~'
		START = S
		B1 = L+S
		B0 = S+L
		intUnit = self.intParameter('unit', 1, 4)-1
		strReturn = ''
		code = self.intParameter('house', 0, 4095)
		for i in range(12):
			if code & 1:
				strReturn = B1 + strReturn
			else:
				strReturn = B0 + strReturn
			code >>= 1
		strReturn = START + strReturn  # Startcode, first
		code = 0
		if method == Device.TURNON:
			code += 2
		elif method != Device.TURNOFF:
			return None

		code <<= 2
		code += intUnit
		check1 = 0
		check2 = 0
		for i in range(6):
			if code & 1:
				if i % 2 == 0:
					check1 += 1
				else:
					check2 += 1
			if code & 1:
				strReturn += B1
			else:
				strReturn += B0
			code >>= 1

		if check1 % 2 == 0:
			strReturn += B0
		else:
			strReturn += B1

		if check2 % 2 == 0:
			strReturn += B0
		else:
			strReturn += B1

		return {'S': strReturn}


# Anisotropic Diffusion 2D
# parameters: [<scenario_name> [<dt> [<dx>]]]

import sys, os

# parse command line options (scenario name)
scenario_name = ""
if len(sys.argv) <= 2:
  scenario_name = ""

dt = 1e-3
dx = 0.6
if len(sys.argv) >= 2+1:
  scenario_name = sys.argv[0]

if len(sys.argv) >= 2+2:
  dt = float(sys.argv[1])

if len(sys.argv) >= 2+3:
  dx = float(sys.argv[2])

prefactor = 0.01      # this is realistic (diffusion prefactor = Conductivity/(Am*Cm))
n = (int)(3.2/dx)    # number of elements in transversal direction

# number of elements
nx = 3*n
ny = n
nz = n

# number of nodes
mx = nx+1
my = ny+1
mz = nz+1

# initial values
initial_values = {}
k_begin = int(0.4*mz)
k_end = max(k_begin+2, int(0.6*mz))
j_begin = int(0.2*my)
j_end = max(j_begin+2, int(0.4*my))
i_begin = int(0.5*mx)
i_end = max(i_begin+2, int(0.8*mx))

for k in range(k_begin, k_end):
  for j in range(j_begin, j_end):
    for i in range(i_begin,i_end):
      index = k*mx*my + j*mx + i
      initial_values[index] = 100.0

print("dt: {}, dx: {}, n: {}, {} nodes in total, {} initial values".format(dt, dx, n, mx*my*mz, len(initial_values)))

config = {
  "solverStructureDiagramFile":     "solver_structure.txt",     # output file of a diagram that shows data connection between solvers
  "mappingsBetweenMeshesLogFile":  "",
  "scenarioName": scenario_name,
  "Solvers": {
    "linearSolver":
    {
      "solverType":         "gamg",
      "preconditionerType": "none",
      "gamgType":           "agg",
      "cycleType":          "cycleV",
      "nLevels":            25,

      "relativeTolerance":  1e-15,
      "absoluteTolerance":  1e-10,         # 1e-10 absolute tolerance of the residual
      "maxIterations":      1e5,
      "dumpFormat":         "ascii",
      "dumpFilename":       "",

    }
  },
  "ImplicitEuler": {
    "initialValues":                initial_values,
    "timeStepWidth":                dt,
    "logTimeStepWidthAsKey":        "dt",
    "durationLogKey":               "duration_implicit_euler",
    "endTime":                      5.0,
    "checkForNanInf":               True,
    "solverName":                   "linearSolver",
    "timeStepOutputInterval":       100,
    "nAdditionalFieldVariables":    0,
    "inputMeshIsGlobal":            True,
    "dirichletBoundaryConditions":  {},

    "FiniteElementMethod" : {
      "nElements":        [3*n,n,n],
      "inputMeshIsGlobal": True,
      "physicalExtent":   [9.6, 3.2, 3.2],
      "solverName":       "linearSolver",
      "prefactor":        prefactor,
      "diffusionTensor":  [
        0.2, 0.2,  0,
        0.2, 1.0,  0,
        0,   0,    1,
      ],
    },

    "OutputWriter" : [
      #{"format": "Paraview", "outputInterval": 100, "filename": "out/out_diffusion3d", "fixedFormat": False, "combineFiles": True, "binary": False, "onlyNodalValues": True, "fileNumbering": "incremental"}
      {"format": "PythonFile", "outputInterval": 100, "filename": "out/out_diffusion3d", "fixedFormat": False, "combineFiles": True, "binary": False, "onlyNodalValues": True, "fileNumbering": "incremental"}
    ]
  },
}


# letra = str("Digite o sexo do usuário: ")

# if letra == "F" or letra == "Feminino" or letra == "FEMININO" or "feminino":
#     print("O Sexo informado é FEMININO")
# elif letra == "M" or letra == "Masculino" or "MASCULINO" or "masculino":
#     print("O Sexo informado é MASCULINO")

# QUESTÃO 3:

sexo = str(input("""
Digite o seu sexo:
F - Feminino
M - Masculino
""")).upper().strip()
# upper transforma tudo em uppercase(maiusculo) e strip tira o espaçamento a esquerda e direita da string

if sexo == 'F' or sexo == 'FEMININO':
    print("F - Feminino")
elif sexo == "M" or sexo == 'MASCULINO':
    print("M - Masculino")
else:
    print("Alternativa inválida")


"""
Created on Mon Nov  5 14:37:29 2018

@author: epinsky
this scripts reads your ticker file (e.g. MSFT.csv) and
constructs a list of lines
"""
import os
from pathlib import Path

ticker: str = "SPY"
input_dir: Path = Path(__file__).parent.absolute()
ticker_file: Path = Path(input_dir.joinpath(f"{ticker}.csv"))

try:
    with open(ticker_file) as f:
        lines = f.read().splitlines()
    print("opened file for ticker: ", ticker)
    print(lines)
    """    your code for assignment 1 goes here
    """

except Exception as e:
    print(e)
    print("failed to read stock data for ticker: ", ticker)


import abc

class EmailServiceInterface(metaclass=abc.ABCMeta):
    @classmethod
    def __subclasshook__(cls, subclass):
        return (
            hasattr(subclass, "send_mail")
            and callable(subclass.send_mail)
            or NotImplemented
        )

    @abc.abstractmethod
    def send_mail(self, email: str, subject: str, message: str):
        """
        Send email
        """
        raise NotImplementedError


TOL = 1e-5
MAX_ITER_DEPTH = 500

#performs the bisection algo
def _bisection(F, left, right, depth):

    p_0 = (left + right) / 2
    FP = F(p_0)

    print(f'ITERATION: {depth}  a={left} | b={right} | p_{depth} = {p_0} | F(p_{depth}) = {FP}')

    if depth >= MAX_ITER_DEPTH or abs(FP - p_0) <= TOL or (right - left) / 2 <= TOL:
        return p_0

    F_left = F(left)

    if F_left * FP > 0: #both same sign
        return _bisection(F, p_0, right, depth + 1)

    #if both are not the same sign the root has to between them
    return _bisection(F, left, p_0, depth + 1)

def bisection(F, left, right):
    return _bisection(F, left, right, 0)

#3\left(x+1\right)\left(x-1\right)\left(x-\frac{1}{2}\right)\left\{-1.25\le x\le2.5\right\}
def poly2b(x):
    a = x + 1
    b = x - (1.0/2.0)
    c = x - 1

    return 3 * a * b * c

bounds = [-1.25, 2.5]

College Math/Numerical Analysis I/snippets/bisection.py


'''			Problem 27: Quadratic Primes

Find the product of the coefficients, a and b, for the below quadratic
expression that produces the maximum number of primes for consecutive
values of n, starting with n = 0.

n^2 + an + b , where |a| < 1000 and |b| < 1000

'''
import math

# Generate primes
primes = [2,3,5,7]
def gen_primes():
	for n in range(9, 9999, 2):
		isPrime = True
		for divisor in range(3, int(math.sqrt(n)) + 1, 2):
			if n % divisor == 0:
				isPrime = False
				break
		if isPrime:
			primes.append(n)

# b must be a prime between 1-1000
# else the equation won't return a prime
# when n = 0

gen_primes()
b_range = primes[0:168]
primes = set(primes) # For O(1) lookup
# Represent count, product, a, and b respectively
values = [0,0,0,0]

# Check for streaks
for a in range(-1000, 1000):
	for b in b_range:
		n = 0
		while True:
			if (n**2 + a * n + b) in primes:
				n += 1
			else:
				break
		if n > values[0]:
			values = [n, a * b, a, b]

print("Max streak: " + str(values[0]) +
      "\nProduct: " + str(values[1]) +
	  "\na value: " + str(values[2]) +
	  "\nb value: " + str(values[3]))


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

# # Statements Assessment Test
# Let's test your knowledge!

# _____
# **Use for, .split(), and if to create a Statement that will print out words that start with 's':**

# In[1]:

st = 'Print only the words that start with s in this sentence Said Ronney'

# In[9]:

st = 'Print only the words that start with s in this sentence Said Ronney'
for i in st.split():
    if i.startswith('s'):
        print(i)

# ______
# **Use range() to print all the even numbers from 0 to 10.**

# In[10]:

#Code Here
for i in range(10):
    if i%2==0:
        print(i)

# ___
# **Use a List Comprehension to create a list of all numbers between 1 and 50 that are divisible by 3.**

# In[4]:

#Code in this cell
l=[i for i in range(1,50) if i%3==0]
l

# _____
# **Go through the string below and if the length of a word is even print "even!"**

# In[ ]:

st = 'Print every word in this sentence that has an even number of letters'

# In[13]:

#Code in this cell
st = 'Print every word in this sentence that has an even number of letters'
for i in st.split():
    if len(i)%2==0:
        print('EVEN')
    else:
        print('odd')

# ____
# **Write a program that prints the integers from 1 to 100. But for multiples of three print "Fizz" instead of the number, and for the multiples of five print "Buzz". For numbers which are multiples of both three and five print "FizzBuzz".**

# In[15]:

#Code in this cell
for i in range(1,100):
    if i%3==0 and i%5==0:
        print(i,"FizzBuzz")
    elif i%3==0:
        print(i,"Fizz")
    elif i%5==0:
        print(i,"Buzz")

# ____
# **Use List Comprehension to create a list of the first letters of every word in the string below:**

# In[ ]:

st = 'Create a list of the first letters of every word in this string'

# In[42]:

#Code in this cell
st = 'Create a list of the first letters of every word in this string'
l=[j[0] for j in [i for i in st.split()]]
l

# ### Great Job!


__author__ = ['Migyeong Gwak']
__credit__ = ['Migyeong Gwak']
__email__ = ['mgwak@ucla.edu']
__date__ = ['2019_05_10']

# 1 when Toe walking
# 2 when normal sitting
# 3 when Toe sitting and Toe standing
# 4 when Heel standing and heel sitting
# 5 when normal standing
# 6 when Flat walking
# 7 when normal walking

import json
import os
import numpy as np
import matplotlib.pyplot as plt

def step_counter(data_directory, sid, cdate):
    toe_walking = 0
    flat_walking = 0
    normal_walking = 0
    plt.figure()
    with open(data_directory) as json_file:
        data = json.load(json_file)
        for p in data:
            flat_walking += int(p['FlatCount'])
            normal_walking += int(p['NormalCount'])
            toe_walking += int(p['ToeCount'])

    print("Toe_walking = ", toe_walking)
    print("Flat_walking = ", flat_walking)
    print("Normal_walking = ", normal_walking)

    walking_type = [toe_walking, flat_walking, normal_walking]
    objects = ('Toe', 'Flat', 'Normal')
    y_pos = np.arange(len(objects))
    plt.bar(y_pos, walking_type, align='center', alpha=0.8, color=['red', 'yellow', 'green'])
    plt.xticks(y_pos, objects)
    plt.ylabel('Counts')
    plt.title(sid + '-' + cdate)
    for i, v in enumerate(walking_type):
        plt.text(i, v, " " + str(v), color='blue', horizontalalignment='center', va='bottom', fontweight='bold')

    plt.savefig(data_directory[:-4] + 'png', dpi=100)

def step_counter_by_log(dataDirectory, sid, cdate):
    Toe_walking = 0
    Normal_sitting = 0
    Toe_sitstand = 0
    Heel_sitstand = 0
    Normal_standing = 0
    Flat_walking = 0
    Normal_walking = 0
    with open(dataDirectory) as json_file:
        data = json.load(json_file)
        list_shoeState = []
        for p in data:
            list_shoeState.extend(p['shoeState'])

    clean_shoeState = []
    for n in list_shoeState:
        if n > 10:
            multiState = [int(d) for d in str(n)]
            clean_shoeState.extend(multiState)
        else:
            clean_shoeState.append(n)

    for n in clean_shoeState:
        if n == 1:
            Toe_walking += 1
        elif n == 2:
            Normal_sitting += 1
        elif n == 3:
            Toe_sitstand += 1
        elif n == 4:
            Heel_sitstand += 1
        elif n == 5:
            Normal_standing += 1
        elif n == 6:
            Flat_walking += 1
        elif n == 7:
            Normal_walking += 1

    print("Toe_walking = ", Toe_walking)
    print("Normal_sitting = ", Normal_sitting)
    print("Toe_sitstand = ", Toe_sitstand)
    print("Heel_sitstand = ", Heel_sitstand)
    print("Normal_standing = ", Normal_standing)
    print("Flat_walking = ", Flat_walking)
    print("Normal_walking = ", Normal_walking)
    print("Total detected shoe states = ", Toe_walking + Normal_sitting + Toe_sitstand + Heel_sitstand + Normal_standing + Flat_walking + Normal_walking)

    walking_type = [Toe_walking, Flat_walking, Normal_walking]
    objects = ('Toe', 'Flat', 'Normal')
    y_pos = np.arange(len(objects))
    plt.bar(y_pos, walking_type, align='center', alpha=0.8, color=['red', 'yellow', 'green'])
    plt.xticks(y_pos, objects)
    plt.ylabel('Counts')
    plt.title(sid + '-' + cdate)
    for i, v in enumerate(walking_type):
        plt.text(i, v, " " + str(v), color='blue', horizontalalignment='center', va='bottom', fontweight='bold')

    plt.show()


def retrocontador(e):
    print("{},".format(e), end = "")

    if e > 0:
        retrocontador(e-1) # Recursividad, usando una función que se llama asímisma. Da problemas.

retrocontador(10)

def sumatorio(n):
    if n > 0:
        return n + sumatorio(n-1)

    else:
        return 0

print(sumatorio(5))