"""
Author: Dan Yamins (dyamins@gmail.com)
Date: 2015-05-28

This is NOT a general-purpose vml-to-obj converter.
This code works ONLY for the specific format of VML file in the BU-4DFE dataset as
described here:

    http://www.cs.binghamton.edu/~lijun/Research/3DFE/3DFE_Analysis.html

Each VMl file in that collection comes with a single JPG texture file.

inputs:
    fn = path to vml source
    jpgfl = path to jpg texture file
    outfl = output path base, e.g. to which '.obj' and '.mtl' will be appended

usage:
    a = parse(fn)
    write_obj(outfl, jpgfl, *a)

"""

def parse(fn):
    lines = open(fn, 'rU').read().split('\n')
    i = 0
    N = len(lines)
    for i in range(N):
        l = lines[i]
        if 'material' in l:
            break
    appearance_lines = []
    for j in range(i+1, N):
        l = lines[j]
        if '}' in l:
            break
        appearance_lines.append(l)
    for i in range(j, N):
        l = lines[i]
        if 'coord' in l:
            break
    geom_lines = []
    for j in range(i+1, N):
        l = lines[j]
        if ']' in l:
            break
        geom_lines.append(l)
    for i in range(j, N):
        l = lines[i]
        if 'texCoord' in l:
            break
    texCoords = []
    for j in range(i+1, N):
        l = lines[j]
        if ']' in l:
            break
        texCoords.append(l)
    for i in range(j, N):
        l = lines[i]
        if 'texCoordIndex' in l:
            break
    texCoordIndex = []
    for j in range(i+1, N):
        l = lines[j]
        if ']' in l:
            break
        texCoordIndex.append(l)
    for i in range(j, N):
        l = lines[i]
        if 'coordIndex' in l:
            break
    coordIndex = []
    for j in range(i+1, N):
        l = lines[j]
        if ']' in l:
            break
        coordIndex.append(l)

    appearance_lines = parse_appearance(appearance_lines)
    geom_lines = parse_coords(geom_lines)
    texCoords = parse_coords(texCoords)
    texCoordIndex = parse_index(texCoordIndex)
    coordIndex = parse_index(coordIndex)
    return appearance_lines, geom_lines, texCoords, coordIndex, texCoordIndex

def parse_appearance(X):
    def parse_ap(l):
        l = l.strip(' \t')
        l = l.split(' ')
        return l[0], map(float, l[1:])
    X = map(parse_ap, X)
    return dict(X)

def parse_coords(X):
    def parse_c(l):
        l = l.strip(' \t,')
        return map(float, l.split(' '))
    return map(parse_c, X)

def parse_index(X):
    def parse_i(l):
        l = l.strip(' \t,').split(', ')
        return [1 + _x for _x in map(int, l[:-1])]
    return map(parse_i, X)

tdict = {'ambientIntensity': 'Ka',
         'diffuseColor': 'Kd',
         'shininess': 'Ns',
         'specularColor': 'Ks',
         'transparency': 'd'}

def write_obj(fn, jpgfl, app, geom, texCoords, coordIndex, texCoordIndex):
    mtl_lines = ['newmtl Mat']
    for a in app:
        n = tdict[a]
        v = app[a]
        if n in ['Kd', 'Ka', 'Ks'] and len(v) == 1:
            v = 3 * v
        v = ' '.join(map(str, v))
        newl = n + ' ' + v
        mtl_lines.append(newl)
    mtl_lines.append('illum 2')
    mtl_lines.append('map_Kd %s\n' % os.path.split(jpgfl)[-1])

    mtl_fn = fn + '.mtl'
    with open(mtl_fn, 'wb') as _f:
        _f.write('\n'.join(mtl_lines))

    obj_lines = ['mtllib %s\n' % os.path.split(mtl_fn)[-1]]

    for l in geom:
        newl = 'v  %s' % ('  '.join(map(str, l)))
        obj_lines.append(newl)

    obj_lines.append('\n')
    for l in texCoords:
        newl = 'vt  %s' % ('  '.join(map(str, l)))
        obj_lines.append(newl)

    obj_lines.append('\nusemtl Mat')

    for l1, l2, in zip(coordIndex, texCoordIndex):
        t = ['%d/%d' % (_l1, _l2) for _l1, _l2 in zip(l1, l2)]
        newl = 'f  %s' % '  '.join(t)
        obj_lines.append(newl)

    obj_lines.append('\n')

    obj_fn = fn + '.obj'
    with open(obj_fn, 'wb') as _f:
        _f.write('\n'.join(obj_lines))


import ifcopenshell
from ifc_common import *

# 表示位置がずれてるIfcAnnotationの情報をIfcOpenShellでダンプしてみる
gid = "0OL3LCjon8C8eMGVs718Tk"

model = ifcopenshell.open('./test_data/AC20-FZK-Haus.ifc')
annotations = model.by_type("IfcAnnotation")

for a in annotations:
    if get_global_id(a) == gid:
        dump_ifc_item("", a, 0)

# IfcTextLiteralWithExtent
# https://standards.buildingsmart.org/IFC/DEV/IFC4_3/RC1/HTML/schema/ifcpresentationdefinitionresource/lexical/ifctextliteralwithextent.htm


import os
import numpy as np
from math import cos,sin,pi,atan2
from urdf_create import *
from urdf_create_primitives import *

length = 0.4
width  = 0.2
height = 0.1

def GetXMLString(robot_name):
  hstr   = '<?xml version="1.0"?>\n'
  hstr  += '<robot name="'+robot_name+'">\n'

    #      y
    #       |
    # width |
    #       |---------
    #          length     x

  hstr  += createCuboid("chassi" , 0, 0, 0, length, width, height)
  ll = 0.4*length
  lw = 0.2*width
  px = 0.4*length
  py = 0.65*width

  hstr  += createRotatedCylinder("wheel1" , -px, +py, 0,
      r=0, p=1.57, yaw=1.57, radius=0.5*ll, length=lw)
  hstr  += createRotatedCylinder("wheel2" , -px, -py, 0,
      r=0, p=1.57, yaw=1.57, radius=0.5*ll, length=lw)
  hstr  += createRotatedCylinder("wheel3" , +px, +py, 0,
      r=0, p=1.57, yaw=1.57, radius=0.5*ll, length=lw)
  hstr  += createRotatedCylinder("wheel4" , +px, -py, 0,
      r=0, p=1.57, yaw=1.57, radius=0.5*ll, length=lw)

  hstr  += createRotatedCuboid("frontspoiler" , 0.5*length, 0, 0,
      l=  np.sqrt(2)*0.5*width,
      w = np.sqrt(2)*0.5*width,
      h = height,
      r=0, p=0,
      yaw=0.5*1.57)

  aw = py - 0.5*width - 0.5*lw
  ap = py - 0.5*lw - 0.6*aw
  hstr  += createCuboid("axis1", +px, +ap, 0, 0.05*length, aw, 0.3*height)
  hstr  += createCuboid("axis2" , -px, +ap, 0, 0.05*length, aw, 0.3*height)
  hstr  += createCuboid("axis3" , +px, -ap, 0, 0.05*length, aw, 0.3*height)
  hstr  += createCuboid("axis4" , -px, -ap, 0, 0.05*length, aw, 0.3*height)
  #hstr = createRotatedCylinder("body",0,0,0,0,0,yaw,radius,length)
  hstr  += createRigidJoint( "chassi", "wheel1")
  hstr  += createRigidJoint( "chassi", "wheel2")
  hstr  += createRigidJoint( "chassi", "wheel3")
  hstr  += createRigidJoint( "chassi", "wheel4")
  hstr  += createRigidJoint( "chassi", "frontspoiler")
  hstr  += createRigidJoint( "chassi", "axis1")
  hstr  += createRigidJoint( "chassi", "axis2")
  hstr  += createRigidJoint( "chassi", "axis3")
  hstr  += createRigidJoint( "chassi", "axis4")

  hstr += '  <klampt package_root="../../.." default_acc_max="4" >\n'
  hstr += '  </klampt>\n'
  hstr += '</robot>'
  return hstr

robot_name = 'planar/car'
fname = getPathname(robot_name)

f = open(fname,'w')
f.write(GetXMLString(robot_name))
f.close()
print("\nCreated new file >>",fname)

CreateCylinderRobot(robot_name + "_capsule_inner", 0.5*width, height)


TITLE = "Astro"
# screen dims
WIDTH = 480
HEIGHT = 600
# frames per second
FPS = 60
# colors
WHITE = (0, 153, 0)
BLACK = (0,0,0)
REDDISH = (255,255,153)
SKY_BLUE = (143, 185, 252)
FONT_NAME = 'times new roman'
SPRITESHEET = "spritesheet_jumper.png"
SPRITESHEET2 = "spritesheet.png"
# data files
HS_FILE = "highscore.txt"
# player settings
PLAYER_ACC = 0.5
PLAYER_FRICTION = -0.12
PLAYER_GRAV = 0.8
PLAYER_JUMP = 20
# game settings
BOOST_POWER = 60
POW_SPAWN_PCT = 13
COIN_SPAWN_PCT = 15
MOB_FREQ = 600
# layers - uses numerical value in layered sprites
PLAYER_LAYER = 2
#Platform Layers
PLATFORM_LAYER = 1
MOVINGPFORM_LAYER = 1
# POW, MOB, and cloud layers
POW_LAYER = 1
MOB_LAYER = 2
CLOUD_LAYER = 0

# platform settings
PLATFORM_LIST = [(0, HEIGHT - 40),
                 (65, HEIGHT - 300),
                 (20, HEIGHT - 350),
                 (200, HEIGHT - 150),
                 (200, HEIGHT - 450)]

# moving platform settings
MOVINGPFORM_LIST = [(0, HEIGHT - 40),
                 (65, HEIGHT - 300),
                 (20, HEIGHT - 350),
                 (200, HEIGHT - 150),
                 (200, HEIGHT - 450)]


"""agent.py
"""
from agent.interactions import US_AG_INTERACTION_MAP, US_AG_RESPONSE_MAP
from agent.kb_handler import KB
import re
import random

def process_text(in_text: str):
    """
    Applies RE to find the interaction type and interaction arguments given an input text in_text
    :param in_text: str
    :return:
    """
    for k in US_AG_INTERACTION_MAP:
        for i, interaction in enumerate(US_AG_INTERACTION_MAP[k]):
            match = re.search(interaction, in_text)
            if match:
                # Found a match, analyze the match object
                if k == 'askzone1':
                    # If match has more complex terms, we can use this condition to extract
                    # indexed dictionary
                    return k, match.groupdict()
                return k, match.groups() #TODO: return interaction args (ie: Subjects and so on)
    return None, None

class Agent:
    def __init__(self, speaker, listener, path=None):
        self.speaker = speaker
        self.listener = listener
        self.handle_fn = {
            #'int1': agent_inter1_cb,
            'greet1':agent_greet1_cb,
            'NOT_UNDERSTOOD': agent_not_understood_cb,
            # Default question-answer callbacks
            'int3':agent_autores_cb,
            'int4':agent_autores_cb,
            'int5':agent_autores_cb,
            'int6':agent_autores_cb,
            'int7':agent_autores_cb,
            'int8':agent_autores_cb,
            'int9':agent_autores_cb,
            'int10':agent_autores_cb,
            'int11':agent_autores_cb,
            'int12':agent_autores_cb,
            'int13':agent_autores_cb,
            'int14':agent_autores_cb,
            'int15':agent_autores_cb,
            'int16':agent_autores_cb,
            'int17':agent_autores_cb,
            'int19':agent_autores_cb,
            'int20':agent_autores_cb,
            'int21':agent_autores_cb,
            'int22':agent_autores_cb,
            'int23':agent_autores_cb,
            'int24':agent_autores_cb,
            'int25':agent_autores_cb,
            'askzone1':agent_askzone1_cb,
            'setzone1':agent_setzone1_cb,
            'setzone2':agent_setzone2_cb,
            'askregion1': agent_askregion1_cb,
            'askregion2': agent_askregion1_cb,
            'asktasso1': agent_asktasso_cb
        }
        self.kb = KB(path)

    def process(self, in_text: str):
        inter, inter_args = process_text(in_text)
        response = None
        if inter is None:
            response = self.handle_fn['NOT_UNDERSTOOD'](self.speaker)
        else:
            # Inter and inter_args can be used
            response = self.handle_fn[inter](self.speaker, inter,  inter_args, self.kb)
        print('Bot: ' + response)
        self.speaker.speak(response)

def agent_inter1_cb(speaker, inter_args):
    speaker.speak("Executing inter 1 callback.")
    return

def agent_not_understood_cb(speaker):
    return "Non ho capito"

def agent_greet1_cb(speaker, inter, inter_args, kb=None) -> str:
    response_lst = US_AG_RESPONSE_MAP['greet1']
    # Sample a response
    response = response_lst[0]
    response = response.format(name=inter_args[0])
    return response

def agent_autores_cb(speaker, inter, inter_args, kb=None) -> str:
    """
    Default auto-response callback
    Automatically answer to the user with one of the predefined answers
    """
    response_lst = US_AG_RESPONSE_MAP[inter]
    assert len(response_lst) > 0
    # Sample a response
    response = None
    if len(response_lst) == 1:
        response = response_lst[0]
    else:
        response = random.choice(response_lst)
    return response

def agent_askzone1_cb(speaker, inter, inter_args_dict: dict, kb=None) -> str:
    """
    Query callback. The function uses inter_args to query the KB and extract
    user requested informations.
    """
    # WARNING: This function uses complex inter_args (groupdict), thus first convertion must
    # be applied
    # print(inter_args_dict)
    inter_args = [inter_args_dict['zona'], inter_args_dict['prop'], inter_args_dict['luogo']]
    color_zone = kb.get_zone(inter_args[0])
    location = color_zone[inter_args[2]]
    if location is None:
        return "Non ti so dire nulla a riguardo"
    response = None
    if location is True:
        response = f'In zona {inter_args[0]} si puo andare {inter_args[1]} {inter_args[2]}'
    else:
        response = f'In zona {inter_args[0]} non si puo andare {inter_args[1]} {inter_args[2]}'
    return response

def agent_setzone1_cb(speaker, inter, inter_args, kb=None) -> str:
    """
    Set query callback. The function uses inter_args to write inside the KB
    """
    color_zone = inter_args[0]
    key = inter_args[2]
    kb.set_dato(color_zone, key, 'posso')
    response = f'Salvo che in zona {color_zone}  si puo andare {inter_args[1]} {key}'
    return response

def agent_setzone2_cb(speaker, inter, inter_args, kb=None) -> str:
    """
    Set query callback. The function uses inter_args to write inside the KB
    """
    color_zone = inter_args[0]
    key = inter_args[2]
    kb.set_dato(color_zone, key, 'non posso')
    response = f'Salvo che in zona {color_zone} non si puo andare {inter_args[1]} {key}'
    return response

def agent_askregion1_cb(speaker, inter, inter_args, kb=None) -> str:
    """
    Query callback. The function uses inter_args to query the KB and extract
    user requested informations.
    """
    reg_name = inter_args[2]
    prop = inter_args[1]
    key = inter_args[0]
    region = kb.get_region(reg_name)
    response = None

    if region is not None:
        response = f'Il numero di {key} {prop} {reg_name} è {region[key]}'
    else:
        response = f'Non ho informazioni per questa regione'
    return response

def agent_asktasso_cb(speaker, inter, inter_args, kb=None) -> str:

    reg_name = inter_args[2]
    prop = inter_args[1]
    key = inter_args[0]

    region = kb.get_region(reg_name)
    response = None

    if key == 'mortalità':
        tasso = (region['morti']/region['popolazione'])*100
        tasso = round(tasso,2)
        response = f'Il tasso di {key} {prop} {reg_name} è {tasso} per cento'
    elif key == 'guarigione':
        tasso = (region['guariti']/region['popolazione'])*100
        tasso = round(tasso,2)
        response = f'Il tasso di {key} {prop} {reg_name} è {tasso} per cento'
    elif key == 'contagio':
        tasso = (region['contagiati']/region['popolazione'])*100
        tasso = round(tasso,2)
        response = f'Il tasso di {key} {prop} {reg_name} è {tasso} per cento'

    return response


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Python version: 3.6

import copy
import torch
from torchvision import datasets, transforms
import torchvision
import pandas as pd
import matplotlib.pyplot as plt
import os
import random
import numpy as np
from torch.utils.data.dataset import Dataset

def cifar_iid(dataset, num_users):
    """
    Sample I.I.D. client data from CIFAR10 dataset
    :param dataset:
    :param num_users:
    :return: dict of image index
    """
    num_items = int(len(dataset)/num_users)
    dict_users, all_idxs = {}, [i for i in range(len(dataset))]
    for i in range(num_users):
        dict_users[i] = set(np.random.choice(all_idxs, num_items,
                                             replace=False))
        all_idxs = list(set(all_idxs) - dict_users[i])
    return dict_users

def average_weights(w):

    w_avg = copy.deepcopy(w[0])
    for key in w_avg.keys():
        for i in range(1, len(w)):
            w_avg[key] += w[i][key]
        w_avg[key] = torch.div(w_avg[key], len(w))
    return w_avg

def exp_details(args):
    print('\nExperimental details:')
    print(f'    Model     : {args.model}')
    print(f'    Optimizer : {args.optimizer}')
    print(f'    Learning  : {args.lr}')
    print(f'    Global Rounds   : {args.epochs}\n')

    print('    Federated parameters:')
    if args.iid:
        print('    IID')
    else:
        print('    Non-IID')
    print(f'    Fraction of users  : {args.frac}')
    print(f'    Local Batch size   : {args.local_bs}')
    print(f'    Local Epochs       : {args.local_ep}\n')
    return

def plotFigure(args, df1):
  os.chdir("/content/drive/MyDrive/FL2022/ULTIMATE/Results")
  if args.norm == "batch_norm":
        n_type="Batch Normalization"
  if args.norm == "group_norm":
        n_type="Group Normalization"

  train_loss = list(df1["train_loss"].values)
  test_loss = list(df1["test_loss"].values)
  train_acc = list(df1["train_acc"].values)
  test_acc = list(df1["test_acc"].values)

  fig, ax = plt.subplots(1, 2, figsize=(20, 7))

  ax[0].plot(range(len(train_loss)), train_loss, linewidth=2, linestyle='-', label="Train")
  ax[0].plot(range(len(test_loss)), test_loss, linewidth=2, linestyle='-', label="Test")

  ax[1].plot(range(len(train_acc)), train_acc, linewidth=2, linestyle='-', label="Train")
  ax[1].plot(range(len(test_acc)), test_acc, linewidth=2, linestyle='-', label="Test")

  ax[0].title.set_text("Average Loss")
  ax[1].title.set_text("Average Accuracy")
  tlt= f"{args.model}_{n_type}_{args.optimizer}_{args.local_bs}_{args.lr}"
  plt.suptitle(tlt, weight="bold")

  ax[0].set(xlabel="# Epochs", ylabel="Loss")
  ax[1].set(xlabel="# Epochs", ylabel="Accuracy")

  ax[0].legend()
  ax[0].grid()
  ax[1].legend()
  ax[1].grid()
  direc ="/content/drive/MyDrive/FL2022/Results/"
  plt.savefig(f"{direc}+{tlt}.png")
  plt.show()

def baseline_data(num):

  xtrain, ytrain, xtmp,ytmp = get_cifar10()
  x , y = shuffle_list_data(xtrain, ytrain)

  x, y = x[:num], y[:num]
  transform, _ = get_default_data_transforms(train=True, verbose=False)
  loader = torch.utils.data.DataLoader(CustomImageDataset(x, y, transform), batch_size=16, shuffle=True)

  return loader

def get_cifar10():
  data_train = torchvision.datasets.CIFAR10('./data', train=True, download=True)
  data_test = torchvision.datasets.CIFAR10('./data', train=False, download=True)

  x_train, y_train = data_train.data.transpose((0,3,1,2)), np.array(data_train.targets)
  x_test, y_test = data_test.data.transpose((0,3,1,2)), np.array(data_test.targets)

  return x_train, y_train, x_test, y_test

def shuffle_list(data):

  for i in range(len(data)):
    tmp_len= len(data[i][0])
    index = [i for i in range(tmp_len)]
    random.shuffle(index)
    data[i][0],data[i][1] = shuffle_list_data(data[i][0],data[i][1])
  return data

def shuffle_list_data(x, y):

  inds = list(range(len(x)))
  random.shuffle(inds)
  return x[inds],y[inds]

class CustomImageDataset(Dataset):

  def __init__(self, inputs, labels, transforms=None):
      assert inputs.shape[0] == labels.shape[0]
      self.inputs = torch.Tensor(inputs)
      self.labels = torch.Tensor(labels).long()
      self.transforms = transforms

  def __getitem__(self, index):
      img, label = self.inputs[index], self.labels[index]

      if self.transforms is not None:
        img = self.transforms(img)

      return (img, label)

  def __len__(self):
      return self.inputs.shape[0]

def get_default_data_transforms(train=True, verbose=True):
  transforms_train = {
  'cifar10' : transforms.Compose([
    transforms.ToPILImage(),
    transforms.RandomCrop(32, padding=4),
    transforms.RandomHorizontalFlip(),
    transforms.ToTensor(),
    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010))]),
  }
  transforms_eval = {
  'cifar10' : transforms.Compose([
    transforms.ToPILImage(),
    transforms.ToTensor(),
    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010))])
  }
  if verbose:
    print("\nData preprocessing: ")
    for transformation in transforms_train['cifar10'].transforms:
      print(' -', transformation)
    print()

  return (transforms_train['cifar10'], transforms_eval['cifar10'])

def baseline_data(num):

  xtrain, ytrain, xtmp,ytmp = get_cifar10()
  x , y = shuffle_list_data(xtrain, ytrain)

  x, y = x[:num], y[:num]
  transform, _ = get_default_data_transforms(train=True, verbose=False)
  loader = torch.utils.data.DataLoader(CustomImageDataset(x, y, transform), batch_size=16, shuffle=True)

  return loader

def print_image_data_stats(data_train, labels_train, data_test, labels_test):
  print("\nData: ")
  print(" - Train Set: ({},{}), Range: [{:.3f}, {:.3f}], Labels: {},..,{}".format(
    data_train.shape, labels_train.shape, np.min(data_train), np.max(data_train),
      np.min(labels_train), np.max(labels_train)))
  print(" - Test Set: ({},{}), Range: [{:.3f}, {:.3f}], Labels: {},..,{}".format(
    data_test.shape, labels_test.shape, np.min(data_train), np.max(data_train),
      np.min(labels_test), np.max(labels_test)))

def get_data_loaders(nclients,batch_size,classes_pc=10, real_wd =False ,verbose=True ):

  x_train, y_train, x_test, y_test = get_cifar10()

  if verbose:
    print_image_data_stats(x_train, y_train, x_test, y_test)

  transforms_train, transforms_eval = get_default_data_transforms(verbose=False)

  if real_wd:
    split = split_image_data_realwd(x_train, y_train, n_clients=nclients, verbose = verbose)
  else:
    split = split_image_data(x_train, y_train, n_clients=nclients,
          classes_per_client=classes_pc, verbose=verbose)

  split_tmp = shuffle_list(split)

  client_loaders = [torch.utils.data.DataLoader(CustomImageDataset(x, y, transforms_train),
                                                                batch_size=batch_size, shuffle=True) for x, y in split_tmp]

  test_loader  = torch.utils.data.DataLoader(CustomImageDataset(x_test, y_test, transforms_eval), batch_size=100, shuffle=False)

  return client_loaders, test_loader

def split_image_data_realwd(data, labels, n_clients=100, verbose=True):

  n_labels = np.max(labels) + 1

  def break_into(n,m):
    to_ret = [1 for i in range(m)]
    for i in range(n-m):
        ind = random.randint(0,m-1)
        to_ret[ind] += 1
    return to_ret

  n_classes = len(set(labels))
  classes = list(range(n_classes))
  np.random.shuffle(classes)
  label_indcs  = [list(np.where(labels==class_)[0]) for class_ in classes]

  tmp = [np.random.randint(1,10) for i in range(n_clients)]
  total_partition = sum(tmp)

  class_partition = break_into(total_partition, len(classes))

  class_partition = sorted(class_partition,reverse=True)
  class_partition_split = {}

  for ind, class_ in enumerate(classes):
      class_partition_split[class_] = [list(i) for i in np.array_split(label_indcs[ind],class_partition[ind])]

  clients_split = []
  count = 0
  for i in range(n_clients):
    n = tmp[i]
    j = 0
    indcs = []

    while n>0:
        class_ = classes[j]
        if len(class_partition_split[class_])>0:
            indcs.extend(class_partition_split[class_][-1])
            count+=len(class_partition_split[class_][-1])
            class_partition_split[class_].pop()
            n-=1
        j+=1

    classes = sorted(classes,key=lambda x:len(class_partition_split[x]),reverse=True)
    if n>0:
        raise ValueError(" Unable to fulfill the criteria ")
    clients_split.append([data[indcs], labels[indcs]])

  def print_split(clients_split):
    print("Data split:")
    for i, client in enumerate(clients_split):
      split = np.sum(client[1].reshape(1,-1)==np.arange(n_labels).reshape(-1,1), axis=1)
      print(" - Client {}: {}".format(i,split))
    print()

    if verbose:
      print_split(clients_split)

  clients_split = np.array(clients_split)

  return clients_split

def split_image_data(data, labels, n_clients=100, classes_per_client=10, shuffle=True, verbose=True):
  '''
  Splits (data, labels) among 'n_clients s.t. every client can holds 'classes_per_client' number of classes
  Input:
    data : [n_data x shape]
    labels : [n_data (x 1)] from 0 to n_labels
    n_clients : number of clients
    classes_per_client : number of classes per client
    shuffle : True/False => True for shuffling the dataset, False otherwise
    verbose : True/False => True for printing some info, False otherwise
  Output:
    clients_split : client data into desired format
  '''
  n_data = data.shape[0]
  n_labels = np.max(labels) + 1

  data_per_client = clients_rand(len(data), n_clients)
  data_per_client_per_class = [np.maximum(1,nd // classes_per_client) for nd in data_per_client]

  data_idcs = [[] for i in range(n_labels)]
  for j, label in enumerate(labels):
    data_idcs[label] += [j]
  if shuffle:
    for idcs in data_idcs:
      np.random.shuffle(idcs)

  clients_split = []
  c = 0
  for i in range(n_clients):
    client_idcs = []

    budget = data_per_client[i]
    c = np.random.randint(n_labels)
    while budget > 0:
      take = min(data_per_client_per_class[i], len(data_idcs[c]), budget)

      client_idcs += data_idcs[c][:take]
      data_idcs[c] = data_idcs[c][take:]

      budget -= take
      c = (c + 1) % n_labels

    clients_split += [(data[client_idcs], labels[client_idcs])]

  def print_split(clients_split):
    print("Data split:")
    for i, client in enumerate(clients_split):
      split = np.sum(client[1].reshape(1,-1)==np.arange(n_labels).reshape(-1,1), axis=1)
      print(" - Client {}: {}".format(i,split))
    print()

    if verbose:
      print_split(clients_split)

  print_bar_classes(clients_split, n_labels)
  clients_split = np.array(clients_split)

  return clients_split

def print_bar_classes(clients_split, n_labels):
  di={}
  for i, client in enumerate(clients_split):
    split = np.sum(client[1].reshape(1,-1)==np.arange(n_labels).reshape(-1,1), axis=1)
    di[f'client{i}']=split
  df= pd.DataFrame.from_dict(di, orient='index',
                       columns=['class1', 'class2','class3','class4','class5','class6', 'class7','class8','class9','class10'])
  #print(df)
  df.plot(kind='bar', stacked=True)
  plt.title("Distribution of Classes into Clients")
  plt.xlabel("Clients")
  plt.xticks([])
  plt.legend(loc='upper left')
  plt.ylabel("Number of Images")
  plt.figure(figsize=(40, 40))

def clients_rand(train_len, nclients):
  '''
  train_len: size of the train data
  nclients: number of clients

  Returns: to_ret

  This function creates a random distribution
  for the clients, i.e. number of images each client
  possess.
  '''
  client_tmp=[]
  sum_=0
  for i in range(nclients-1):
    tmp=random.randint(10,100)
    sum_+=tmp
    client_tmp.append(tmp)

  client_tmp= np.array(client_tmp)
  clients_dist= ((client_tmp/sum_)*train_len).astype(int)
  num  = train_len - clients_dist.sum()
  to_ret = list(clients_dist)
  to_ret.append(num)
  return to_ret

def get_data_loaders(nclients,batch_size,classes_pc=10, real_wd =False ,verbose=True ):

  x_train, y_train, x_test, y_test = get_cifar10()

  if verbose:
    print_image_data_stats(x_train, y_train, x_test, y_test)

  transforms_train, transforms_eval = get_default_data_transforms(verbose=False)

  if real_wd:
    split = split_image_data_realwd(x_train, y_train, n_clients=nclients, verbose = verbose)
  else:
    split = split_image_data(x_train, y_train, n_clients=nclients,
          classes_per_client=classes_pc, verbose=verbose)

  split_tmp = shuffle_list(split)

  client_loaders = [torch.utils.data.DataLoader(CustomImageDataset(x, y, transforms_train),
                                                                batch_size=batch_size, shuffle=True) for x, y in split_tmp]

  test_loader  = torch.utils.data.DataLoader(CustomImageDataset(x_test, y_test, transforms_eval), batch_size=100, shuffle=False)

  return client_loaders, test_loader

def client_syn(client_model, global_model):
  '''
  This function synchronizes the client model with global model
  '''
  client_model.load_state_dict(global_model.state_dict())

def cifar_iid(dataset, num_users):
    """
    Sample I.I.D. client data from CIFAR10 dataset
    :param dataset:
    :param num_users:
    :return: dict of image index
    """
    num_items = int(len(dataset) / num_users)
    dict_users = {}
    all_idxs = [i for i in range(len(dataset))]
    for i in range(num_users):
        dict_users[i] = set(np.random.choice(all_idxs, num_items,
                                             replace=False))  # i.i.d. selection from dataset
        all_idxs = list(set(all_idxs) - dict_users[i])
    return dict_users

def cifar_noniid(dataset, num_users):
    """
    Sample non-I.I.D client data from CIFAR10 dataset
    :param dataset:
    :param num_users:
    :return: dict of image index
    """
    num_shards, num_imgs = 200, 250
    idx_shard = [i for i in range(num_shards)]
    dict_users = {i: np.array([]) for i in range(num_users)}
    idxs = np.arange(num_shards * num_imgs)
    labels = np.array(dataset.targets)

    idxs_labels = np.vstack((idxs, labels))
    idxs_labels = idxs_labels[:, idxs_labels[1, :].argsort()]
    idxs = idxs_labels[0, :]

    for i in range(num_users):
        rand_set = set(np.random.choice(idx_shard, 2, replace=False))
        idx_shard = list(set(idx_shard) - rand_set)
        for rand in rand_set:
            dict_users[i] = np.concatenate(
                (dict_users[i], idxs[rand * num_imgs:(rand + 1) * num_imgs]), axis=0)
    return dict_users

def cifar_noniid_unbalanced(dataset, num_users):
    """
    Sample non-I.I.D client data from CIFAR10 dataset such that
    clients have unequal amount of data
    :param dataset:
    :param num_users:
    :returns a dict of clients with each clients assigned certain
    number of training imgs
    """
    num_shards, num_imgs = 1000, 50
    idx_shard = [i for i in range(num_shards)]
    dict_users = {i: np.array([]) for i in range(num_users)}
    idxs = np.arange(num_shards * num_imgs)
    labels = np.array(dataset.targets)

    idxs_labels = np.vstack((idxs, labels))
    idxs_labels = idxs_labels[:, idxs_labels[1, :].argsort()]
    idxs = idxs_labels[0, :]

    min_shard = 1
    max_shard = 30

    random_shard_size = np.random.randint(min_shard, max_shard + 1,
                                          size=num_users)
    random_shard_size = np.around(random_shard_size /
                                  sum(random_shard_size) * num_shards)
    random_shard_size = random_shard_size.astype(int)

    if sum(random_shard_size) > num_shards:

        for i in range(num_users):
            rand_set = set(np.random.choice(idx_shard, 1, replace=False))
            idx_shard = list(set(idx_shard) - rand_set)
            for rand in rand_set:
                dict_users[i] = np.concatenate(
                    (dict_users[i], idxs[rand * num_imgs:(rand + 1) * num_imgs]),
                    axis=0)

        random_shard_size = random_shard_size - 1

        for i in range(num_users):
            if len(idx_shard) == 0:
                continue
            shard_size = random_shard_size[i]
            if shard_size > len(idx_shard):
                shard_size = len(idx_shard)
            rand_set = set(np.random.choice(idx_shard, shard_size,
                                            replace=False))
            idx_shard = list(set(idx_shard) - rand_set)
            for rand in rand_set:
                dict_users[i] = np.concatenate(
                    (dict_users[i], idxs[rand * num_imgs:(rand + 1) * num_imgs]),
                    axis=0)
    else:

        for i in range(num_users):
            shard_size = random_shard_size[i]
            rand_set = set(np.random.choice(idx_shard, shard_size,
                                            replace=False))
            idx_shard = list(set(idx_shard) - rand_set)
            for rand in rand_set:
                dict_users[i] = np.concatenate(
                    (dict_users[i], idxs[rand * num_imgs:(rand + 1) * num_imgs]),
                    axis=0)

        if len(idx_shard) > 0:
            shard_size = len(idx_shard)
            k = min(dict_users, key=lambda x: len(dict_users.get(x)))
            rand_set = set(np.random.choice(idx_shard, shard_size,
                                            replace=False))
            idx_shard = list(set(idx_shard) - rand_set)
            for rand in rand_set:
                dict_users[k] = np.concatenate(
                    (dict_users[k], idxs[rand * num_imgs:(rand + 1) * num_imgs]),
                    axis=0)

    return dict_users

def get_dataset(iid=1, unbalanced=0, num_users=100):
    """
    Returns train and test datasets and a user group which is a dict where
    the keys are the user index and the values are the corresponding data for
    each of those users.
    """
    transform_train = transforms.Compose([
        transforms.RandomCrop(32, padding=4),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
        # mean and std of the CIFAR-10 dataset
    ])

    transform_test = transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
        # mean and std of the CIFAR-10 dataset
    ])

    # choose the training and test datasets
    train_dataset = datasets.CIFAR10('data', train=True,
                                     download=True, transform=transform_train)
    test_dataset = datasets.CIFAR10('data', train=False,
                                    download=True, transform=transform_test)

    if iid:
        user_groups = cifar_iid(train_dataset, num_users)
    else:
        if unbalanced:
            user_groups = cifar_noniid_unbalanced(train_dataset, num_users)
        else:
            user_groups = cifar_noniid(train_dataset, num_users)

    return train_dataset, test_dataset, user_groups

def get_n_params(model):
    pp=0
    for p in list(model.parameters()):
        nn=1
        for s in list(p.size()):
            nn = nn*s
        pp += nn
    return pp


def test():
    N = int(input())
    nums = list(map(int, input().split()))
    count = 0
    for i in range(len(nums)-1):
        for j in range(i+1, len(nums)):
            if nums[i] > nums[j]:
                count += 1
    result.append(count)

result = []
for i in range(int(input())):
    test()

for i in result:
    print(i)


"""
https://leetcode.com/problems/sqrtx/

Given a non-negative integer x, return the square root of x rounded down to the nearest integer. The returned integer should be non-negative as well.

You must not use any built-in exponent function or operator.

For example, do not use pow(x, 0.5) in c++ or x ** 0.5 in python.

Example 1:

Input: x = 4
Output: 2
Explanation: The square root of 4 is 2, so we return 2.
Example 2:

Input: x = 8
Output: 2
Explanation: The square root of 8 is 2.82842..., and since we round it down to the nearest integer, 2 is returned.

Constraints:

0 <= x <= 231 - 1

"""

"""
Approach: Binary search
- If x is less than 2, return x
- Set left and right pointers to 1 and x/2, respectively
- While left <= right:
    - Set mid to the average of left and right
    - If mid * mid is greater than x, set right to mid - 1
    - Else, set left to mid + 1
- Return right

"""
class Solution:
    def mySqrt(self, x: int) -> int:
        if x <= 1:
            return x

        l, r = 1, x//2
        while l <= r:
            m = (l + r) // 2
            if m * m < x:
                l = m + 1
            elif m * m > x:
                r = m - 1
            else:
                return m
        return r


import matplotlib.pyplot as plt
import os
import pandas as pd
#pyxl is also required. If you don't have it, please install it by using pip3 install pyxl

#导入数据
def read_file():
    close_price_table = pd.read_excel('沪深300成分股收盘价.xlsx', index_col=0)
    #weight_table = pd.read_excel('沪深300成分股.xlsx')
    close_price_table = close_price_table.replace(0, pd.np.nan)
    return close_price_table

#生成因子/涨跌幅表格
def calculate_return(close_price_table):
    return_table = close_price_table.pct_change()
    return_table.to_csv('涨跌幅表格.csv')
    return return_table

#分成五级组合
def portfolio_divider(return_table):
    total_week_dict = {}
    for i in range(0, len(return_table)):
        weekly_table = return_table.iloc[i]
        weekly_table = weekly_table.dropna()
        weekly_table = weekly_table.sort_values(ascending=False)
        week_dict = {}
        for level in range(0,5):
            week_dict[(level+1)] = list()
            for k in range(level*int(len(weekly_table)/5),(level+1)*int(len(weekly_table)/5)):
                week_dict[(level+1)].append(weekly_table.index[k])
        total_week_dict[return_table.index[i]] = week_dict
    return total_week_dict

#输出每周每个组合的详细持仓列表
def weekly_holding(total_week_holding):
    df = pd.DataFrame(total_week_holding)
    df = df.T
    df = df.stack()
    df = df.reset_index()
    df.columns = ['date', 'level', 'holding']
    df = df.set_index(['date', 'level'])
    df = df['holding'].apply(pd.Series)
    df.to_csv('五个组合每周详细持仓.csv')

#输出每周每个组合的平均收益率
def weekly_portf_return(return_table, holding_dict):
    weekly_porf_return_dict = {}
    for date in holding_dict:
        try:
            nextdate = return_table.index[return_table.index.get_loc(date)+1]
            for level in holding_dict[date]:
                return_percentage_list = []
                for stock in holding_dict[date][level]:
                    return_percentage_list.append(return_table[stock][nextdate])
                try:
                    weekly_porf_return_dict[(date, level)] = sum(return_percentage_list)/len(return_percentage_list)
                except:
                    weekly_porf_return_dict[(date, level)] = 0
        except:
            pass

    #生成表格
    df = pd.DataFrame(weekly_porf_return_dict, index=[0])
    df = df.T
    df = df.reset_index()
    df.columns = ['date', 'level', 'return']
    df = df.set_index(['date', 'level'])

    return_sheet = pd.DataFrame()
    return_sheet['date'] = (df.loc[df.index.get_level_values('level') == 1]).index.get_level_values('date')
    return_sheet = return_sheet.set_index('date')
    for i in range(1,6):
        df_level = df.loc[df.index.get_level_values('level') == i]
        df_level = df_level.droplevel('level')
        for j in range(0, len(df_level)):
            return_sheet.loc[df_level.index[j], str("Level"+str(i))] = df_level.iloc[j]['return']
    return_sheet.to_csv('五个组合每周收益率.csv')

    return df

#计算净值曲线
def value_test(df):
    #分级计算价值并输出表格
    initia_value = 1
    value_sheet = pd.DataFrame()
    value_sheet['date'] = (df.loc[df.index.get_level_values('level') == 1]).index.get_level_values('date')
    value_sheet = value_sheet.set_index('date')
    for i in range(1,6):
        value = initia_value
        df_level = df.loc[df.index.get_level_values('level') == i]
        df_level = df_level.droplevel('level')
        for j in range(0, len(df_level)):
            value = value * (1 + df_level.iloc[j]['return'])
            value_sheet.loc[df_level.index[j], str("Level"+str(i))] = value
    value_sheet.to_csv('净值曲线表格.csv')

    #生成净值曲线图
    plt.clf()
    for i in range(1,6):
        plt.plot(value_sheet.index, value_sheet['Level'+str(i)])
    plt.legend(['Level1', 'Level2', 'Level3', 'Level4', 'Level5'])
    plt.title('Value Curve')
    plt.xlabel('Date')
    plt.ylabel('Value')
    plt.savefig('净值曲线图.png')

if __name__ == '__main__':
    close_price_table = read_file()
    return_table = calculate_return(close_price_table)
    portf_divided = portfolio_divider(return_table)
    weekly_holding(portf_divided)
    weekly_por_return = weekly_portf_return(return_table, portf_divided)
    value_test(weekly_por_return)


'''
Created on Mar 27, 2018

@author: Stefan
'''
from Algorithm import Algorithm
import matplotlib.pyplot as plt
import numpy as np

def main():
    a = Algorithm()
    return a.run(100)

if __name__ == '__main__':
    results = []
    for i in range(30):
        results.append(main())

    print(results)
    arr = np.array(results)
    m = np.mean(arr,axis=0)
    means=[]
    for i in range(30):
        means.append(m)
    plt.plot(range(0,30),means)
    plt.plot( range(0,30),results,"ro")
    plt.show()


#!/usr/bin/env python3
import sys
import numpy as np

def find_invalid_number(numbers):
    preamble_length = 25
    preamble = []
    for i in range(preamble_length):
        preamble.append(numbers[i])

    for number in numbers[preamble_length:]:
        preamble_matrix = np.zeros((preamble_length, preamble_length))
        for i in range(preamble_length):
            preamble_matrix[i, :] = preamble
            preamble_matrix[i, :] += preamble[i]
            preamble_matrix[i, i] = np.nan  # Invalidate main diagonal

        if number not in preamble_matrix:
            return number

        preamble.pop(0)
        preamble.append(number)

def find_encryption_weakness(numbers, target):
    l = 0
    h = 0
    while h < len(numbers):
        sum = np.sum(numbers[l:h+1])
        if sum == target:
            break
        elif sum > target:
            l += 1
            h = l
        else:
            h += 1

    return min(numbers[l:h+1]) + max(numbers[l:h+1])

def main():
    with open("aoc_day_9_data.txt", "r") as file:
        numbers = [int(line) for line in file]

        invalid_number = find_invalid_number(numbers)
        print(f'Invalid number: {invalid_number}')

        encryption_weakness = find_encryption_weakness(numbers, invalid_number)
        print(f'Encryption weakness: {encryption_weakness}')

if __name__ == '__main__':
    sys.exit(main())


from selenium import webdriver

from webdriver.WebDriverWrapper import WebDriverWrapper

if __name__ == '__main__':
    yetis_worlds = ["Adra", "Antica", "Bona", "Celesta", "Damora", "Famosa", "Harmonia", "Karna",
              "Marcia", "Monza", "Olima", "Peloria", "Refugia", "Secura", "Suna", "Thyria", "Vunira"]
    ocyakao_worlds = ['Antica', 'Bona', 'Celesta', 'Damora', 'Famosa', 'Harmonia', 'Monza',
                'Peloria', 'Premia', 'Refugia', 'Secura', 'Suna', 'Thyria', 'Vunira']

    print("Starting...")
    chrome_options = webdriver.ChromeOptions()
    chrome_options.add_argument("--headless")
    webdriver = webdriver.Chrome(options=chrome_options)

    wrapper = WebDriverWrapper(webdriver)

    bosses = wrapper.get_boss_data('yetis', worlds=yetis_worlds)
    bosses += wrapper.get_boss_data('Ocyakao', worlds=ocyakao_worlds)

    bosses.sort(key=lambda x: (x.name, x.data.get_chances_text_value(), x.data.get_chances(), x.data.last_seen_days()), reverse=True)

    for boss in bosses:
        print(boss)


import os
import pathlib

import pytest
import requests

from unstructured.documents.elements import NarrativeText
from unstructured.partition.api import partition_via_api

DIRECTORY = pathlib.Path(__file__).parent.resolve()

class MockResponse:
    def __init__(self, status_code):
        self.status_code = status_code

    @property
    def text(self):
        return """[
    {
        "element_id": "f49fbd614ddf5b72e06f59e554e6ae2b",
        "text": "This is a test email to use for unit tests.",
        "type": "NarrativeText",
        "metadata": {
            "date": "2022-12-16T17:04:16-05:00",
            "sent_from": [
                "Matthew Robinson <mrobinson@unstructured.io>"
            ],
            "sent_to": [
                "Matthew Robinson <mrobinson@unstructured.io>"
            ],
            "subject": "Test Email",
            "filename": "fake-email.eml"
        }
    }
]"""

def test_partition_via_api_from_filename(monkeypatch):
    monkeypatch.setattr(
        requests,
        "post",
        lambda *args, **kwargs: MockResponse(status_code=200),
    )
    filename = os.path.join(DIRECTORY, "..", "..", "example-docs", "fake-email.eml")
    elements = partition_via_api(filename=filename, api_key="FAKEROO")
    assert elements[0] == NarrativeText("This is a test email to use for unit tests.")

def test_partition_via_api_from_file(monkeypatch):
    monkeypatch.setattr(
        requests,
        "post",
        lambda *args, **kwargs: MockResponse(status_code=200),
    )
    filename = os.path.join(DIRECTORY, "..", "..", "example-docs", "fake-email.eml")

    with open(filename, "rb") as f:
        elements = partition_via_api(file=f, file_filename=filename, api_key="FAKEROO")
    assert elements[0] == NarrativeText("This is a test email to use for unit tests.")

def test_partition_via_api_raises_with_bad_response(monkeypatch):
    monkeypatch.setattr(
        requests,
        "post",
        lambda *args, **kwargs: MockResponse(status_code=500),
    )
    filename = os.path.join(DIRECTORY, "..", "..", "example-docs", "fake-email.eml")

    with pytest.raises(ValueError):
        partition_via_api(filename=filename, api_key="FAKEROO")


# compress string
# ex: aabcccccaaa -> a2b1c5a2

import unittest
from collections import Counter

def compressString(string):
	compress = []
	counter = 0

	# count up number of each
	for c in range(len(string)):
		# as soon as they stop being equal we want to append and reset counter
		if c != 0 and string[c] != string[c - 1]:
			compress.append(string[c - 1] + str(counter))
			counter = 0
		counter += 1

	# add the last character
	compress.append(string[-1] + str(counter))

	# fix spacing
	compress = ''.join(compress)

	# checks to see if compressed string is smaller
	string1 = min(string, compress, key=len)
	return string1

class Test(unittest.TestCase):
    '''Test Cases'''
    data = [
        ('aabcccccaaa', 'a2b1c5a3'),
        ('abcdef', 'abcdef')
    ]

    def test_compressString(self):
        for [test_string, expected] in self.data:
            actual = compressString(test_string)
            self.assertEqual(actual, expected)

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


from providers.input import plex
from providers.metadata import tmdb, tvdb
from providers.output import tvtime

from DaemonLite import DaemonLite
import configparser
import logging
import time
import argparse
import sys
import json

global connected_providers
connected_providers = []

class Daemon(DaemonLite):
    def __init__(self, pidFile, configFile):
        DaemonLite.__init__(self, pidFile=pidFile)
        self.Tmdb = None
        self.Tvdb = None
        self.Plex = None
        self.delay = 3600
        self.config_file = configFile
        self.extract_config()

    def run(self):
        while True:
            self.update_providers()
            time.sleep(self.delay)

    def update_providers(self):
        episodes = self.Plex.get_watched()
        for provider in connected_providers:
            provider.update(episodes)

    def extract_config(self):
        config = configparser.ConfigParser()
        config.read(self.config_file)

        self.Tmdb = tmdb.Tmdb(
            api_key=config['TMDB']['api_key'],
            language=config['TMDB']['language']
        )
        self.tvdb = tvdb.TVDB(
            config['TVDB']['username'],
            config['TVDB']['account_identifier'],
            config['TVDB']['api_key']
        )
        self.Plex = plex.Plex(
            url=config['Plex']['url'],
            token=config['Plex']['token'],
            tmdb=self.Tmdb,
            tvdb=self.tvdb
        )

        if config['DEFAULT']['delay']:
            try:
                self.delay = int(config['DEFAULT']['delay'])
            except Exception as e:
                logging.error("Delay value is not valid")
        # MyAnimeList
        # if config['MyAnimeList']['enabled']:
        #     connected_providers.append(myanimelist.MyAnimeList(
        #         config['MyAnimeList']['username'],
        #         config['MyAnimeList']['password']))

        # TV TIME
        if config['TV Time']['enabled']:
            connected_providers.append(
                tvtime.TVTIME(
                    config['TV Time']['token']
                )
            )
            config.set('TV Time', 'token', connected_providers[-1].token)
            config['TV Time']['token'] = connected_providers[-1].token
            with open(self.config_file, 'w') as configfile:
                config.write(configfile)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Syncronize Plex with multiple providers')
    parser.add_argument('--config', help="Path to config file", type=str, default='/etc/shows_sync.ini')
    parser.add_argument('--pid', help="Path to pid file", type=str, default='/var/run/shows_sync.pid')
    parser.add_argument('--log', help="Path to log file", type=str, default='/var/log/shows_sync.log')
    parser.add_argument('--fg', help="Run the program in the foreground", action='store_true')
    parser.add_argument('--debug', help="Debug mode", action="store_const", dest="loglevel", const=logging.DEBUG, default=logging.INFO)
    args = parser.parse_args()

    logging.basicConfig(
        filename=args.log,
        level=args.loglevel,
        format='%(asctime)s - %(module)s - %(levelname)s - %(message)s'
    )

    staff = Daemon(args.pid, args.config)
    if args.fg:
        staff.run()
    else:
        staff.start()


from .base import StoryboardOperator

__all__ = ("UpdateFrameRangeFromStoryboardOperator",)

class UpdateFrameRangeFromStoryboardOperator(StoryboardOperator):
    """Blender operator that updates the render frame range according to the storyboard."""

    bl_idname = "skybrush.update_frame_range_from_storyboard"
    bl_label = "Update Frame Range from Storyboard"
    bl_description = "Updates the frame range to be synchronized with the storyboard"

    def execute_on_storyboard(self, storyboard, context):
        if context.scene.use_preview_range:
            context.scene.frame_preview_start = storyboard.frame_start
            context.scene.frame_preview_end = storyboard.frame_end
        else:
            context.scene.frame_start = storyboard.frame_start
            context.scene.frame_end = storyboard.frame_end

        return {"FINISHED"}


# -*- coding: utf-8 -*-
"""
Created on Fri Mar  9 18:01:48 2018

@author: andersson
"""

from tkinter import *
import pyaudio
import scipy.io.wavfile as wavfile
import matplotlib.pylab as plt
import wave
from scipy.fftpack import fft
import numpy as np
#from tkFileDialog import *
from scipy.fftpack import fft
from PIL import Image, ImageTk

from scipy import signal

ventana=Tk()
ventana.geometry("1200x800+100+100")
ventana.title("FILTROS")

def periodo():

    #definir funcion saludar del boton
    def grabar():
            global  fs, data, w, h, filtrado
            periodo.destroy()
            periododemuestreo=entradaper.get()
            tiempodegraba=entradatime.get()
            chunk=1024
            FORMAT = pyaudio.paInt16
            CHANNELS = 1
            fs = periododemuestreo
            tiempo = tiempodegraba
            samples = (fs/1024)*tiempo
            p = pyaudio.PyAudio()

            stream = p.open(format=FORMAT,channels=CHANNELS,rate =fs,input=True,frames_per_buffer=chunk)
            stream1 = p.open(format=FORMAT,channels=CHANNELS,rate =fs,output=True,frames_per_buffer=chunk)

            print ("*grabando")
            arreglo = []
            for i in range(0, samples):
                data = stream.read(chunk)
                arreglo.append(data)

            stream.stop_stream()
            stream.close()
            stream1.stop_stream()
            stream1.close()

            wf = wave.open('audio1.wav', 'wb')
            wf.setnchannels(CHANNELS)
            wf.setframerate(fs)
            wf.setsampwidth(p.get_sample_size(FORMAT))
            wf.writeframes(b''.join(arreglo))
            wf.close()
            print ("*fin de la grabacion")
            fs, data = wavfile.read("audio1.wav")
            print(data.size)
            a=len(data)
            t=np.linspace(0,(a-1)*1.0/fs,a)
            plt.figure(1).clf()
            plt.figure(1)
            plt.plot(t,data)
            plt.savefig("imagentiempo1.png")

    #definir funcion despedir del boton

    #creando la ventana
    periodo=Toplevel(ventana)
    periodo.geometry("400x200+450+200")
    periodo.focus_set()
    periodo.grab_set()
    periodo.transient(master=ventana)
    periodo.title("SELECCION PARAMETROS DE GRABACION")
    lblperiodo=Label(periodo,text="Ingrese periodo de muestreo",fg="black",font=("Agency FB",14) ).place(x=80,y=10)
    entradaper=IntVar()
    entradaper.set("16000")
    txtperiodo=Entry(periodo,textvariable=entradaper).place(x=90,y=40)

    lbltime=Label(periodo,text="Ingrese tiempo de grabacion",fg="black",font=("Agency FB",14) ).place(x=80,y=70)
    entradatime=IntVar()
    entradatime.set("3")
    txttime=Entry(periodo,textvariable=entradatime).place(x=90,y=100)
    btnper=Button(periodo,text="Aceptar",command=grabar,font=("Agency FB",14)).place(x=100,y=130)
    periodo.wait_window(periodo)

    print ("*fin de la grabacion")

    #plt.show()

def pintar_imagen():
    ancho=300
    alto=200
    img = Image.open('imagentiempo1.png', "rb")
    img.thumbnail((ancho,alto), Image.ANTIALIAS)
    imagen1 = ImageTk.PhotoImage(img)
    label1=Label(ventana, image=imagen1, width=ancho, height=alto).place(x=1, y=75)

    img2 = Image.open('imagenfreq.png', "rb")
    img2.thumbnail((ancho,alto), Image.ANTIALIAS)
    imagen2 = ImageTk.PhotoImage(img2)
    label2=Label(ventana, image=imagen2, width=ancho, height=alto).place(x=310, y=75)

    img3 = Image.open('imagenbode.png', "rb")
    img3.thumbnail((ancho,alto), Image.ANTIALIAS)
    imagen3 = ImageTk.PhotoImage(img3)
    label3=Label(ventana, image=imagen3, width=ancho, height=alto).place(x=620, y=75)

    img4 = Image.open('filtrado.png', "rb")
    img4.thumbnail((ancho,alto), Image.ANTIALIAS)
    imagen4 = ImageTk.PhotoImage(img4)
    label4=Label(ventana, image=imagen4, width=ancho, height=alto).place(x=620, y=280)

    img5 = Image.open('filtradoFFT.png', "rb")
    img5.thumbnail((ancho,alto), Image.ANTIALIAS)
    imagen5 = ImageTk.PhotoImage(img5)
    label5=Label(ventana, image=imagen5, width=ancho, height=alto).place(x=620, y=490)

    Image.show()

def t1():

    pintar_imagen()

def t2():
    global dataf

    plt.figure(1).clf()
    plt.figure(2)
    plt.plot(dataf)
    plt.show()

def f1():
    global data, fs
    N = len(data)

     # sample spacing
    T = 1.0 / fs

    x = np.linspace(0.0, N*T, N)

    yf = fft(data)
    xf = np.linspace(0.0, 1.0/(2.0*T), N/2)
    plt.figure().clf()
    plt.figure()
    plt.plot(xf, 2.0/N * np.abs(yf[0:N/2]))
    plt.grid()
    plt.savefig("imagenfreq.png")
    pintar_imagen()

def f2():
    global dataf, fs
    N = len(dataf)

     # sample spacing
    T = 1.0 / fs

    x = np.linspace(0.0, N*T, N)

    yf = fft(data)
    xf = np.linspace(0.0, 1.0/(2.0*T), N/2)
    plt.figure().clf()
    plt.figure()

    plt.plot(xf, 2.0/N * np.abs(yf[0:N/2]))
    plt.grid()
    plt.show()

def play1():

    rf1 = wave.open("audio1.wav", 'rb')
   # fs, rf1 = wavfile.read("audio1.wav")
    prof1 = rf1.getsampwidth()
    channels1 = rf1.getnchannels()
    rate1 = rf1.getframerate()
    audioN1 = pyaudio.PyAudio()
    stream2  = audioN1.open(format=audioN1.get_format_from_width(prof1), channels=channels1, rate=rate1, output=True)
    datos1 = rf1.readframes(1024)
    #rate1, data1 = wavfile.read(root.filename)

    while datos1 != '':
        stream2.write(datos1)
        datos1 = rf1.readframes(1024)

    rf1.close()

def play2():
    rf = wave.open('filtro.wav', 'rb')

    prof = rf.getsampwidth()
    channels = rf.getnchannels()
    rate = rf.getframerate()
    audioN = pyaudio.PyAudio()
    stream1  = audioN.open(format=audioN.get_format_from_width(prof), channels=channels, rate=rate, output=True)
    datos = rf.readframes(1024)

    while datos != '':
        stream1.write(datos)
        datos = rf.readframes(1024)

    rf.close()

def aplicar():
    global b, a, data, fs, filtrado
    filtrado=signal.lfilter(b, a, data)
    wavfile.write('filtro.wav', fs, filtrado)
    plt.figure(4).clf()
    plt.figure(4)
    plt.plot(filtrado)
    plt.savefig("filtrado.png")
    N = len(filtrado)
    T = 1.0 / fs
    x = np.linspace(0.0, N*T, N)
    yf = fft(filtrado)
    xf = np.linspace(0.0, 1.0/(2.0*T), N/2)
    plt.figure(4).clf()
    plt.figure(4)
    plt.plot(xf, 2.0/N * np.abs(yf[0:N/2]))
    plt.savefig("filtradoFFT.png")

    pintar_imagen()

def eventos():
    global b, a
    nyq = fs * 0.5
    s=selec.get()
    s1=selec1.get()
    if s==1 and s1==1:
        print ("Pasa Altos Butterworth")
        cutoff= highcut
        stopfreq = float(cutoff)
        cornerfreq = 0.4 * stopfreq # (?)
        ws = cornerfreq/nyq
        wp = stopfreq/nyq
        N1, wn =signal.buttord(wp, ws, orden, 40) # (?)
        b, a = signal.butter(N1, wn, btype='high')
        w,h = signal.freqz(b,a)
        plt.figure(3).clf()
        plt.figure(3)
        plt.plot(w, abs(h))
        plt.grid()
        plt.savefig("imagenbode.png")
        pintar_imagen()

    elif s==1 and s1==2:
        print("Pasa Altos Chevichev I")
        cutoff= highcut
        rp=(riso*0.1)
        stopfreq = float(cutoff)
        cornerfreq = 0.4 * stopfreq # (?)
        ws = cornerfreq/nyq
        wp = stopfreq/nyq
        N1, wn =signal.buttord(wp, ws, orden, 40) # (?)
        b, a = signal.cheby1(N1, rp, wn, btype='highpass') #N es el numero de orden, rp=el rizo maximo permitido, Wn= frecuencias de corte y stop
        w,h = signal.freqz(b,a)
        plt.figure(3).clf()
        plt.figure(3)
        plt.plot(w, abs(h))
        plt.grid()
        plt.savefig("imagenbode.png")
        pintar_imagen()

    elif s==1 and s1==3:
        print("Pasa Altos Chevichev II")
        cutoff= highcut
        rp=riso*5
        stopfreq = float(cutoff)
        cornerfreq = 0.4 * stopfreq # (?)
        ws = cornerfreq/nyq
        wp = stopfreq/nyq
        N1, wn =signal.buttord(wp, ws, orden, 40) # (?)
        b, a = signal.cheby2(N1, rp, wn, btype='highpass') #N es el numero de orden, rp=el rizo maximo permitido, Wn= frecuencias de corte y stop
        w,h = signal.freqz(b,a)
        plt.figure(3).clf()
        plt.figure(3)
        plt.plot(w, abs(h))
        plt.grid()
        plt.savefig("imagenbode.png")
        pintar_imagen()

    elif s==1 and s1==4:
        print("Pasa Altos Eliptico")
        cutoff= highcut
        rp=riso*0.1
        rse=rs*5
        stopfreq = float(cutoff)
        cornerfreq = 0.4 * stopfreq # (?)
        ws = cornerfreq/nyq
        wp = stopfreq/nyq
        N1, wn =signal.buttord(wp, ws, orden, 40) # (?)
        b, a = signal.ellip(N1, rp, rse, wn, btype='highpass') #N es el numero de orden, rp=el rizo maximo permitido, Wn= frecuencias de corte y stop
        w,h = signal.freqz(b,a)
        plt.figure(3).clf()
        plt.figure(3)
        plt.plot(w, abs(h))
        plt.grid()
        plt.savefig("imagenbode.png")
        pintar_imagen()

    if s==2 and s1==1:
        print (" Pasa bajo Butterworth")
        cutoff= lowcut
        stopfreq = float(cutoff)
        cornerfreq = 0.7 * stopfreq # (?)
        ws = cornerfreq/nyq
        wp = stopfreq/nyq
        N1, wn =signal.buttord(wp, ws, orden, 40) # (?)
        b, a = signal.butter(N1, wn, btype='lowpass')
        w,h = signal.freqz(b,a)
        plt.figure(3).clf()
        plt.figure(3)
        plt.plot(w, abs(h))
        plt.grid()
        plt.savefig("imagenbode.png")
        pintar_imagen()

    elif s==2 and s1==2:
        print(" Pasa bajo Chevichev I")
        cutoff= lowcut
        rp=(riso*0.1)
        stopfreq = float(cutoff)
        cornerfreq = 0.7 * stopfreq # (?)
        ws = cornerfreq/nyq
        wp = stopfreq/nyq
        N1, wn =signal.buttord(ws, wp, orden, 40) # (?)
        b, a = signal.cheby1(N1, rp, wn, btype='lowpass') #N es el numero de orden, rp=el rizo maximo permitido, Wn= frecuencias de corte y stop
        w,h = signal.freqz(b,a)
        plt.figure(3).clf()
        plt.figure(3)
        plt.plot(w, abs(h))
        plt.grid()
        plt.savefig("imagenbode.png")
        pintar_imagen()

    elif s==2 and s1==3:
        print("Pasa bajo Chevichev II")
        cutoff= lowcut
        rp=(riso*5)
        stopfreq = float(cutoff)
        cornerfreq = 0.7 * stopfreq # (?)
        ws = cornerfreq/nyq
        wp = stopfreq/nyq
        N1, wn =signal.buttord(ws, wp, orden, 40) # (?)
        b, a = signal.cheby2(N1, rp, wn, btype='lowpass') #N es el numero de orden, rp=el rizo maximo permitido, Wn= frecuencias de corte y stop
        w,h = signal.freqz(b,a)
        plt.figure(3).clf()
        plt.figure(3)
        plt.plot(w, abs(h))
        plt.grid()
        plt.savefig("imagenbode.png")
        pintar_imagen()

    elif s==2 and s1==4:
        print("Pasa bajo Eliptico")
        cutoff= lowcut
        rp=(riso*0.1)
        rse=rs*5
        stopfreq = float(cutoff)
        cornerfreq = 0.7 * stopfreq # (?)
        ws = cornerfreq/nyq
        wp = stopfreq/nyq
        N1, wn =signal.buttord(ws, wp, orden, 40) # (?)
        b, a = signal.ellip(N1, rp, rse, wn, btype='lowpass') #N es el numero de orden, rp=el rizo maximo permitido, Wn= frecuencias de corte y stop
        w,h = signal.freqz(b,a)
        plt.figure(3).clf()
        plt.figure(3)
        plt.plot(w, abs(h))
        plt.grid()
        plt.savefig("imagenbode.png")
        pintar_imagen()

    if s==3 and s1==1:
        print (" Pasa Banda Butterworth")
        low = lowcut / nyq
        high = highcut / nyq
        b, a = signal.butter(orden, [low, high], btype='band')
        w,h = signal.freqz(b,a)
        plt.figure(3).clf()
        plt.figure(3)
        plt.plot(w, abs(h))
        plt.grid()
        plt.savefig("imagenbode.png")
        pintar_imagen()

    elif s==3 and s1==2:
        print(" Pasa Banda Chevichev I")
        low = lowcut / nyq
        high = highcut / nyq
        rp=(riso*0.1)
        N1= orden
        b, a = signal.cheby1(N1, rp, [low, high], btype='bandpass') #N es el numero de orden, rp=el rizo maximo permitido, Wn= frecuencias de corte y stop
        w,h = signal.freqz(b,a)
        plt.figure(3).clf()
        plt.figure(3)
        plt.plot(w, abs(h))
        plt.grid()
        plt.savefig("imagenbode.png")
        pintar_imagen()

    elif s==3 and s1==3:
        print("Pasa Banda Chevichev II")
        low = lowcut / nyq
        high = highcut / nyq
        rp=(riso*5)
        N1= orden
        b, a = signal.cheby2(N1, rp, [low, high], btype='bandpass') #N es el numero de orden, rp=el rizo maximo permitido, Wn= frecuencias de corte y stop
        w,h = signal.freqz(b,a)
        plt.figure(3).clf()
        plt.figure(3)
        plt.plot(w, abs(h))
        plt.grid()
        plt.savefig("imagenbode.png")
        pintar_imagen()

    elif s==3 and s1==4:
        print("Pasa Banda Eliptico")
        low = lowcut / nyq
        high = highcut / nyq
        rp=(riso*0.1)
        rse=rs*5
        N1= orden
        b, a = signal.ellip(N1, rp, rse, [low, high], btype='bandpass') #N es el numero de orden, rp=el rizo maximo permitido, Wn= frecuencias de corte y stop
        w,h = signal.freqz(b,a)
        plt.figure(3).clf()
        plt.figure(3)
        plt.plot(w, abs(h))
        plt.grid()
        plt.savefig("imagenbode.png")
        pintar_imagen()

    if s==4 and s1==1:
        print (" Rechazabanda Butterworth")
        low = lowcut / nyq
        high = highcut / nyq
        b, a = signal.butter(orden, [low, high], btype='bandstop')
        w,h = signal.freqz(b,a)
        plt.figure(3).clf()
        plt.figure(3)
        plt.plot(w, abs(h))
        plt.grid()
        plt.savefig("imagenbode.png")
        pintar_imagen()

    elif s==4 and s1==2:
        print(" Rechazabanda Chevichev I")
        low = lowcut / nyq
        high = highcut / nyq
        rp=(riso*0.1)
        N1= orden
        b, a = signal.cheby1(N1, rp, [low, high], btype='bandstop') #N es el numero de orden, rp=el rizo maximo permitido, Wn= frecuencias de corte y stop
        w,h = signal.freqz(b,a)
        plt.figure(3).clf()
        plt.figure(3)
        plt.plot(w, abs(h))
        plt.grid()
        plt.savefig("imagenbode.png")
        pintar_imagen()

    elif s==4 and s1==3:
        print("Rechazabanda Chevichev II")
        low = lowcut / nyq
        high = highcut / nyq
        rp=(riso*5)
        N1= orden
        b, a = signal.cheby2(N1, rp, [low, high], btype='bandstop') #N es el numero de orden, rp=el rizo maximo permitido, Wn= frecuencias de corte y stop
        w,h = signal.freqz(b,a)
        plt.figure(3).clf()
        plt.figure(3)
        plt.plot(w, abs(h))
        plt.grid()
        plt.savefig("imagenbode.png")
        pintar_imagen()

    elif s==4 and s1==4:
        print("Rechazabanda Eliptico")
        low = lowcut / nyq
        high = highcut / nyq
        rp=(riso*0.1)
        rse=rs*5
        N1= orden
        b, a = signal.ellip(N1, rp, rse, [low, high], btype='bandstop') #N es el numero de orden, rp=el rizo maximo permitido, Wn= frecuencias de corte y stop
        w,h = signal.freqz(b,a)
        plt.figure(3).clf()
        plt.figure(3)
        plt.plot(w, abs(h))
        plt.grid()
        plt.savefig("imagenbode.png")
        pintar_imagen()

def LC(event):
    global lowcut, highcut, orden, fs, riso, rs
    lowcut= Throttle.get()
    print(lowcut)
    eventos()

def HC(event):
    global lowcut, highcut, orden, fs, riso, rs
    highcut= Throttle1.get()
    print(highcut)
    eventos()

def Ord(event):
    global lowcut, highcut, orden, fs, riso, rs
    orden= Throttle2.get()
    print(orden)
    eventos()

def Riso(event):
    global lowcut, highcut, orden, fs, riso, rs
    riso= Throttle3.get()
    print(riso)
    eventos()

def rs(event):
    global lowcut, highcut, orden, fs, riso, rs
    nyq = fs * 0.5
    rs= Throttle4.get()
    print(rs)
    eventos()

Throttle = Scale(ventana,label="LowCut",orient=VERTICAL,length=350, width=25,from_=1,to=8000,tickinterval=1, command=LC,bg='#f0f0ff')
Throttle.set(0)
Throttle.pack()
Throttle.place(x=20,y=320)

Throttle1 = Scale(ventana,label="Highcut",orient=VERTICAL,length=350, width=25,from_=1,to=8000,tickinterval=1, command=HC,bg='#f0f0ff')
Throttle1.set(0)
Throttle1.pack()
Throttle1.place(x=160,y=320)

Throttle2 = Scale(ventana,label="Orden",orient=VERTICAL,length=350, width=25,from_=1,to=20,tickinterval=1, command=Ord,bg='#f0f0ff')
Throttle2.set(0)
Throttle2.pack()
Throttle2.place(x=310,y=320)

Throttle3 = Scale(ventana,label="Riso",orient=VERTICAL,length=350, width=25,from_=0,to=10,tickinterval=1, command=Riso,bg='#f0f0ff')
Throttle3.set(0)
Throttle3.pack()
Throttle3.place(x=450,y=320)

Throttle4 = Scale(ventana,label="Rs-Ell",orient=VERTICAL,length=350, width=25,from_=0,to=10,tickinterval=1, command=rs,bg='#f0f0ff')
Throttle4.set(0)
Throttle4.pack()
Throttle4.place(x=1000,y=320)
#sldbarra=Scale(ventana,label="Lowcut",orient=VERTICAL,length=350,width=20,from_=0,to=8000,tickinterval=10,variable=valor0,bg='#f0f0ff').place(x=10,y=130)

selec=IntVar()

rd1=Radiobutton(ventana,text="Pasa Alto",
                     value=1,variable=selec,bg='#f0f0ff').place(x=10,y=10)
rd2=Radiobutton(ventana,text="Pasa Bajo",
                     value=2,variable=selec,bg='#f0f0ff').place(x=10,y=25)
rd3=Radiobutton(ventana,text="Pasa Banda",
                     value=3,variable=selec,bg='#f0f0ff').place(x=10,y=40)
rd4=Radiobutton(ventana,text="Rechaza Banda",
                     value=4,variable=selec,bg='#f0f0ff').place(x=10,y=55)

selec1=IntVar()
rd5=Radiobutton(ventana,text="Butterworth",value=1,variable=selec1,bg='#f0f0ff').place(x=150,y=10)
rd6=Radiobutton(ventana,text="Chebyshev I",value=2,variable=selec1,bg='#f0f0ff').place(x=150,y=25)
rd7=Radiobutton(ventana,text="Chebyshev II",value=3,variable=selec1,bg='#f0f0ff').place(x=150,y=40)
rd8=Radiobutton(ventana,text="Eliptico",value=4,variable=selec1,bg='#f0f0ff').place(x=150,y=55)

btnplay1=Button(ventana,text="Play1",command=play1,height=1,activebackground=('green'),width=4,font=("Agency FB",12)).place(x=1000,y=1)
btnapply=Button(ventana,text="Aplicar",command=aplicar,height=1,activebackground=('green'),width=5,font=("Agency FB",12)).place(x=1000,y=35)

btnp2=Button(ventana,text="play2",command=play2,height=1,activebackground=('green'),width=4,font=("Agency FB",12)).place(x=1000,y=70)

barramenu=Menu(ventana)

#paso 2 crear los menus

mnuarchivo=Menu(barramenu)

mnugrafi=Menu(barramenu)

mnutiempo=Menu(mnugrafi)
mnufrec=Menu(mnugrafi)

#paso 3 crear los comandos de los menus

mnuarchivo.add_command(label="Grabar",command=periodo)

mnuarchivo.add_separator()
mnuarchivo.add_command(label="Salir",command=ventana.destroy)

#####

mnutiempo.add_command(label="1",command=t1)

#paso 4 agergar los menus a la barra de menus
barramenu.add_cascade(label="Archivo",menu=mnuarchivo)

barramenu.add_cascade(label="Graficas",menu=mnugrafi)

mnugrafi.add_cascade(label="Tiempo",menu=mnutiempo)

ventana.config(menu=barramenu, bg='#f0f0ff')

ventana.mainloop()


import pandas as pd
from sklearn import datasets
from sklearn.model_selection import train_test_split
import numpy as np
import copy
from src.diagnostics import Diagnostics

class GLM(object):

    def __init__(self):
        self.betas = None

    @staticmethod
    def glm(c):
        if c == 'logit':
            return Logistic()
        if c == 'gamma':
            return Gamma()
        if c == 'poisson':
            return Poisson()

    def fit(self):
        pass

    def predict(self, x):
        pass

class Logistic(GLM):

    @staticmethod
    def sigmoid(z):
        return 1 / (1 + np.exp(-z))

    @staticmethod
    def predictfromprob(probs, threshold=.5):
        return [1 if prob >= threshold else 0 for prob in probs]

    def predict(self, x, threshold=.5):
        link = self.betas[0] + sum([self.betas[col + 1] * x.iloc[:, col] for col in range(len(self.betas) - 1)])
        probs = self.sigmoid(link)
        return self.predictfromprob(probs, threshold)

    def fit(self, x, y_true, epochs, alpha):
        epoch = 1
        self.betas = np.zeros(shape=x.shape[1] + 1)

        n = len(x)

        while epoch < epochs:
            lp = self.betas[0] + sum([self.betas[col + 1] * x.iloc[:, col] for col in range(len(self.betas) - 1)])
            probs = self.sigmoid(lp)
            pred = self.predictfromprob(probs, .5)

            for j in range(self.betas.shape[0]):
                if j == 0:
                    update = sum([(pred[i] - y_true[i]) for i in range(n)])
                else:
                    update = sum([x.iloc[i, j - 1] * (pred[i] - y_true[i]) for i in range(n)])

                self.betas[j] = self.betas[j] - alpha * update

            epoch += 1

            if epoch % 500 == 0:
                print(self.betas)

        return self.betas

class Poisson(GLM):

    def predict(self, x, threshold=.5):
        return None

    def fit(self, x, y_true, epochs, alpha):
        return None

class Gamma(GLM):
    def predict(self, x, threshold=.5):
        return None

    def fit(self, x, y_true, epochs, alpha):
        return None

def practice_data():
    iris = datasets.load_iris()

    colnames = copy.deepcopy(iris['feature_names'])
    colnames.append('target')

    iris = (
        pd.concat([pd.DataFrame(iris['data']), pd.Series(iris['target'])], axis=1)
            .set_axis(colnames, axis=1, inplace=False)
            .query('target.isin([0, 1])')
    )

    return iris

if __name__ == '__main__':
    df = practice_data()
    x_train, x_test, y_train, y_test = train_test_split(df.iloc[:, 0:4], df.iloc[:, 4], random_state=646)

    mod = GLM().glm('logit')
    weights = mod.fit(x_train.reset_index(drop=True),
                      y_train.reset_index(drop=True),
                      1000,
                      .01)

    preds = mod.predict(x_test.reset_index(drop=True))

    print(preds)
    print(Diagnostics.accuracy(y_test, preds))
    print(Diagnostics.recall(y_test, preds))
    print(Diagnostics.precision(y_test, preds))


# coding: utf-8

# Standard Libraries
import asyncio
import logging
from typing import Any
from typing import List

# Third Party Libraries
import asynctest

# Dopplerr
from dopplerr.tasks.queued import QueuedTask

log = logging.getLogger(__name__)

class MyTask(QueuedTask):
    name: str = "MyTask"

    def __init__(self) -> None:
        super(MyTask, self).__init__()
        self.input_processed: List[Any] = []
        self.event_sequence: List[Any] = []

    def add_event(self, event: str, *args) -> None:
        log.info(event, *args)
        self.event_sequence.append(event % args)

    async def _run(self, task) -> str:
        self.add_event("Task %s: work started", task)
        await asyncio.sleep(0.2)
        self.input_processed.append(task)
        self.add_event("Task %s: work finished", task)
        return "finished task {}".format(task)

class TestTaskQueue(asynctest.TestCase):
    maxDiff: int = None

    async def test_fire_and_forget(self) -> None:
        task = MyTask()
        task.start()
        await task.fire_and_forget("#1")
        await task.fire_and_forget("#2")
        task.add_event("EventLoop: doing other stuff...")
        await asyncio.sleep(1)
        await task.fire_and_forget("#3")
        await task.fire_and_forget("#4")
        task.add_event("EventLoop: doing other other stuff...")
        await asyncio.sleep(1)
        await task.fire_and_forget("maybe unprocessed task")
        task.add_event("EventLoop: stopping everything...")
        await asyncio.sleep(1)
        # await task.join()
        task.stop()
        self.assertIn('#1', task.input_processed)
        self.assertIn('#2', task.input_processed)
        self.assertIn('#3', task.input_processed)
        self.assertIn('#4', task.input_processed)
        self.assertListEqual([
            'EventLoop: doing other stuff...',
            'Task #1: work started',
            'Task #1: work finished',
            'Task #2: work started',
            'Task #2: work finished',
            'EventLoop: doing other other stuff...',
            'Task #3: work started',
            'Task #3: work finished',
            'Task #4: work started',
            'Task #4: work finished',
            'EventLoop: stopping everything...',
            'Task maybe unprocessed task: work started',
            'Task maybe unprocessed task: work finished',
        ], task.event_sequence)

    async def test_run_with_additional_work(self) -> None:

        async def job_with_task_and_additional_work(task: MyTask, task_id: str) -> None:
            task.add_event("Job %s: asking to execute the sequential task", task_id)
            res = await task.run_and_wait(task_id)
            task.add_event("Job %s: result received '%s'", task_id, res)
            task.add_event("Job %s: additional work start (can be executed in //)", task_id)
            await asyncio.sleep(0.4)
            task.add_event("Job %s: additional work end", task_id)

        task = MyTask()
        task.start()
        task.add_event("EventLoop: launching 2 tasks that should be executed sequentially later...")
        asyncio.ensure_future(job_with_task_and_additional_work(task, "#1"))
        asyncio.ensure_future(job_with_task_and_additional_work(task, "#2"))
        task.add_event("EventLoop: doing other other stuff...")
        await asyncio.sleep(1)
        task.stop()
        self.assertListEqual([
            'EventLoop: launching 2 tasks that should be executed sequentially later...',
            'EventLoop: doing other other stuff...',
            'Job #1: asking to execute the sequential task',
            'Job #2: asking to execute the sequential task',
            'Task #1: work started',
            'Task #1: work finished',
            'Task #2: work started',
            "Job #1: result received 'finished task #1'",
            'Job #1: additional work start (can be executed in //)',
            'Task #2: work finished',
            "Job #2: result received 'finished task #2'",
            'Job #2: additional work start (can be executed in //)',
            'Job #1: additional work end',
            'Job #2: additional work end',
        ], task.event_sequence)


"""Tests for Logger class."""
import pytest
import pygame

from context import logger

# Need to initialize pygame parts (like pygame.font.init()) or the whole
# pygame with pygame.init().
pygame.init()

@pytest.mark.parametrize('msg,count,expected',
    (
        (None, 2, []),
        ('', 2, ['']),
        ('123456', 0, ['123456']),
        ('123', 3, ['1', '2', '3']),
        ('1234', 3, ['1', '2', '3', '4']),
        ('12345', 3, ['1', '2', '3', '4', '5']),
        ('123456', 3, ['12', '34', '56']),
        ('1234567890123456789012', 3, ['1234567', '8901234', '5678901', '2']),
        ('1234567890123456789012', 2.5, ['12345678', '90123456', '789012']),
    ),
    ids=('TEST1_CASE1', 'TEST1_CASE2', 'TEST1_CASE3', 'TEST1_CASE4',
         'TEST1_CASE5', 'TEST1_CASE6', 'TEST1_CASE7', 'TEST1_CASE8',
         'TEST1_CASE9'),
)
def test_Logger_splitText(msg, count, expected):
    """Tests for Logger.splitText()

    Logger.splitText() uses pygame.font, so pygame.font.init() must be called
    for these tests to work.
    """
    loger = logger.Logger(screenWidth=640, screenHeight=800)
    result = loger.splitText(msg, count)

    msg = "expected '%s', but got '%s'" % (expected, result)
    assert result == expected, msg

@pytest.mark.parametrize('msg,logToScreen,logToStdout,expReturn,expected',
    (
        ('abc', False, False, None, []),
        ('abc', False, True, None, []),

        (('This module contains several simple classes to be used within '
          'games. There is the main Sprite class and several Group classes '
          'that contain Sprites.'),
         True, False, None,
         [('This module contains several simple classes to be used within '
           'games. There is the main Sprite class '),
           'and several Group classes that contain Sprites.']
        ),

    ),
    ids=('TEST2_CASE1', 'TEST2_CASE2', 'TEST2_CASE3'),
)

def test_Logger_log(msg, logToScreen, logToStdout, expReturn, expected):
    """Tests for Logger.log()

    Logger.log() uses pygame.font, so pygame.font.init() must be called
    for these tests to work.
    """
    loger = logger.Logger(screenWidth=640, screenHeight=800)
    result = loger.log(msg, logToScreen=logToScreen, logToStdout=logToStdout)

    msg = "expected '%s', but got '%s'" % (expReturn, result)
    assert expReturn == result, msg

    msg = "expected '%s', but got '%s'" % (expected, loger.messages)
    assert expected == loger.messages, msg


import json
import requests
import os

def path_finder(path):
    if os.name == "nt":
        return path.replace("/", "\\")
    else:
        return path.replace("\\", "/")

filepath = os.path.dirname(os.path.abspath(
    __file__)) + "/src/data/menus/newmenu.json"

filepath = path_finder(filepath)

if not os.path.exists(filepath):
    with open(filepath, "w") as f:
        json.dump([], f, indent=4)

def clear_screen():
    if os.name == 'nt':
        os.system('cls')
    else:
        os.system('clear')

def valid_image(image_url: str) -> bool:
    """Checks if the URL is a valid image."""
    image_formats = (
        "image/png", "image/jpeg", "image/jpg", "image/gif", "image/bmp", "image/webp"
    )
    try:
        req = requests.head(image_url)
        if req.headers["content-type"] in image_formats:
            return True
    except:
        pass
    return False

def menu_loader() -> list:
    """Loads the menu from the JSON file."""
    with open(filepath, "r") as f:
        menu = json.load(f)
    return menu

def menu_saver(menu: list):
    """Saves the menu to the JSON file."""
    with open(filepath, "w") as f:
        json.dump(menu, f, indent=4)

def item_in_menu(item: str):
    """Checks if the item is in the menu."""
    menu = menu_loader()
    for options in menu:
        if options["ITEM"].lower() == item.lower():
            return options
    if item.isdigit():
        if int(item) <= len(menu):
            return menu[int(item)-1]

    return False

def add_item():
    menu = menu_loader()
    clear_screen()
    print("ADD WIZARD")
    item = input(
        "Enter the item name you want to add (your case will be saved, type 'cancel' to exit): ")
    if item.lower() == "cancel":
        print("Cancelled!")
        return
    if item_in_menu(item):
        print("Item already exists!")
    else:
        while True:
            description = input(
                "Enter the item description (your case will be saved): ")
            if description == "":
                print("Description cannot be empty!")
                continue
            break
        while True:
            price = input("Enter the item price (Numbers only!): ")
            if price == "":
                print("Price cannot be empty!")
                continue
            try:
                float(price)
            except ValueError:
                print("Price must be a number!")
                continue
            price = str(round(float(price), 2))
            if float(price) < 0:
                print("Price cannot be negative!")
                continue
            break
        while True:
            prep = input(
                "Enter the item preparation time (your case will be saved): ")
            if prep == "" or not prep.isdecimal():
                print("Preparation time must be a number! (integer only)")
                continue
            if int(prep) <= 0:
                print("Preparation time cannot be zero or negative!")
                continue
            prep = " "+prep+" minutes"
            break
        image = input(
            "[Optional] Enter the item image URL (your case will be saved): ")
        while True:
            confirm = input("Are you sure you want to add this item? (Y/N): ")
            if confirm.lower() == "y":
                break
            elif confirm.lower() == "n":
                print("Cancelled!")
                return
            else:
                print("Invalid input!")
                continue
        if valid_image(image):
            menu.append({"ITEM": item, "COST": str(price).strip(),
                        "DESC": description, "TIME": prep, "IMAG": image})
        else:
            image = None
            menu.append({"ITEM": item, "COST": str(price).strip(),
                        "DESC": description, "TIME": prep})
        clear_screen()
        print(f"Item added!"
              f"\nItem: {item}"
              f"\nDescription: {description}"
              f"\nPrice: {price}"
              f"\nPreparation time: {prep}"
              f"\nImage: {image if not None else 'No valid image'}")
        menu_saver(menu)
    while True:
        choice = input("Do you want to add another item? (Y/N): ")
        if choice.lower() == "y":
            add_item()
        break
    clear_screen()

def remove_item():
    menu = menu_loader()
    clear_screen()
    print("REMOVAL WIZARD")
    item = input(
        "Enter the item name you want to remove(type 'cancel' to exit): ")
    if item.lower() == "cancel":
        print("Cancelled!")
        return
    item_obj = item_in_menu(item)
    if not item_obj:
        print("Item not found!")
    else:
        while True:
            confirm = input(
                "Are you sure you want to delete this item? (Y/N): ")
            if confirm.lower() == "y":
                break
            elif confirm.lower() == "n":
                print("Cancelled!")
                return
            else:
                print("Invalid input!")
                continue
        menu.remove(item_obj)
        menu_saver(menu)
        print("Item removed!")
        print(f"Item: {item_obj['ITEM']}"
                f"\nPrice: {item_obj['COST']}"
        )
    while True:
        choice = input("Do you want to delete another item? (Y/N): ")
        if choice.lower() == "y":
            remove_item()
        break
    clear_screen()

def backup():
    """Makes a backup of the menu."""
    import datetime
    menu = menu_loader()
    path = os.path.dirname(os.path.abspath(__file__)) + "/backups/menus/"
    backup_name = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S_")+"menu.json"
    path += backup_name
    path = path_finder(path)
    print("Creating backup...")
    with open(path,"w") as f:
        json.dump(menu, f, indent=4)
    print("Backup created! Name: "+backup_name)
    input("Press enter to continue...")
    clear_screen()

def show_items():
    clear_screen()
    menu = menu_loader()
    print("MENU")
    l = len(menu)
    for i in range(l):
        print(f"{i+1}. {menu[i]['ITEM']} - Rs.{menu[i]['COST']}")
    print(f"Total items: {l}")
    print("Press enter to continue...")
    input()
    clear_screen()

def edit_item():
    menu = menu_loader()
    clear_screen()
    print("EDIT WIZARD")
    item = input(
        "Enter the item name or index you want to edit(type 'cancel' to exit): ")
    if item.lower() == "cancel":
        print("Cancelled!")
        return
    item_obj = item_in_menu(item)
    if not item_obj:
        print("Item not found!")
    else:
        new_item = {}
        while True:
            new_item["ITEM"] = input(
                "Enter the new item name (your case will be saved): ")
            if new_item["ITEM"].strip() == "":
                print("Empty name. Using old name.")
                new_item["ITEM"] = item_obj["ITEM"]
                break
            if item_in_menu(new_item["ITEM"]):
                print("Item already exists!")
                continue
            break
        while True:
            new_item["COST"] = input(
                "Enter the new item price (Numbers only!): ")
            if new_item["COST"].strip() == "":
                print("Empty price. Using old price.")
                new_item["COST"] = item_obj["COST"]
                break
            try:
                float(new_item["COST"])
            except ValueError:
                print("Price must be a number!")
                continue
            new_item["COST"] = str(round(float(new_item["COST"]), 2))
            if float(new_item["COST"]) < 0:
                print("Price cannot be negative!")
                continue
            new_item["COST"] = str(new_item["COST"]).strip()
            break
        while True:
            new_item["DESC"] = input(
                "Enter the new item description (your case will be saved): ")
            if new_item["DESC"].strip() == "":
                print("Empty description. Using old description.")
                new_item["DESC"] = item_obj["DESC"]
                break
            break
        while True:
            new_item["TIME"] = input(
                "Enter the new item preparation time (your case will be saved): ")
            if new_item["TIME"].strip() == "":
                print("Empty preparation time. Using old preparation time.")
                new_item["TIME"] = item_obj["TIME"]
                break
            if not new_item["TIME"].isdecimal():
                print("Preparation time must be a number! (integer only)")
                continue
            if int(new_item["TIME"]) <= 0:
                print("Preparation time cannot be zero or negative!")
                continue
            new_item["TIME"] = " "+new_item["TIME"]+" minutes"
            break
        while True:
            new_item["IMAG"] = input(
                "[Optional] Enter the new item image URL (type 'delete' to delete the image): ")
            if new_item["IMAG"].strip() == "":
                print("Empty image URL. Using old image URL. (if any)")
                if "IMAG" in item_obj:
                    new_item["IMAG"] = item_obj["IMAG"]
                else:
                    del new_item["IMAG"]
                break
            if valid_image(new_item["IMAG"]):
                break
            elif new_item["IMAG"].lower() == "DELETE".lower():
                print("Image deleted!")
                del new_item["IMAG"]
                break
            else:
                print("Invalid image URL, ignoring...")
                del new_item["IMAG"]
                if "IMAG" in item_obj:
                    new_item["IMAG"] = item_obj["IMAG"]
                break
        menu[menu.index(item_obj)] = new_item
        while True:
            confirm = input("Are you sure you want to edit this item? (Y/N): ")
            if confirm.lower() == "y":
                break
            elif confirm.lower() == "n":
                print("Cancelled!")
                return
            else:
                print("Invalid input!")
                continue
        menu_saver(menu)
        print("Item edited! Name: "+item_obj["ITEM"])
    while True:
        choice = input("Do you want to edit another item? (Y/N): ")
        if choice.lower() == "y":
            edit_item()
        break
    clear_screen()

def change_position():
    menu = menu_loader()
    clear_screen()
    print("POSITION CHANGE WIZARD")
    show_items()
    item = input(
        "Enter the item name or index you want to change position (type 'cancel' to exit): ")
    if item.lower() == "cancel":
        print("Cancelled!")
        return
    item_obj = item_in_menu(item)
    if not item_obj:
        print("Item not found!")
        return
    else:
        new_pos = ""
        while True:
            new_pos = input("Enter the new position (integer only): ")
            if new_pos.strip() == "":
                print("Empty position. Using old position.")
                return
            if not new_pos.isdecimal():
                print("Position must be a number (integer only)!")
                continue
            if int(new_pos) <= 0:
                print("Position cannot be zero or negative!")
                continue
            if int(new_pos) > len(menu):
                print("Position cannot be greater than total items.")
                continue
            break
        menu.remove(item_obj)
        menu.insert(int(new_pos)-1, item_obj)
        while True:
            confirm = input("Are you sure you want to edit this item? (Y/N): ")
            if confirm.lower() == "y":
                break
            elif confirm.lower() == "n":
                print("Cancelled!")
                return
            else:
                print("Invalid input!")
                continue
        menu_saver(menu)
        print("Position changed! Name: " +
              item_obj["ITEM"], "New position: "+new_pos)
        print("Show new menu? (y/n)", end=" ")
        if input().lower() == "y":
            show_items()
    while True:
        choice = input("Do you want to edit another item? (Y/N): ")
        if choice.lower() == "y":
            change_position()
        break
    clear_screen()

def switch_good():
    """Case like menu system"""
    print("Menu Editor for Discord-Ordering-Bot by The-Parth")
    print("If you want to reset the menu, type 'reset_menu'")
    input("Press enter to continue...")
    while True:
        print("1. Add item")
        print("2. Delete item")
        print("3. Edit item")
        print("4. Change position")
        print("5. Show menu")
        print("6. Exit")
        choice = input("Enter your choice: ")
        if choice == "1" or choice == "add":
            add_item()
        elif choice == "2" or choice == "delete":
            remove_item()
        elif choice == "3" or choice == "edit":
            edit_item()
        elif choice == "4" or choice == "change":
            change_position()
        elif choice == "5" or choice == "show":
            show_items()
        elif choice == "6" or choice == "exit":
            print("Exiting menu editor...")
            print("Goodbye!")
            break
        elif choice == "reset_menu":
            check = input("Are you sure you want to reset the menu? (Y/N): ")
            if check.lower() == "n":
                print("Cancelled!")
                continue
            check = input("Are you really sure? Type 'reset' to reset: ")
            if check.lower() != "reset":
                print("Cancelled!")
                continue
            print("Resetting menu...")
            backup()
            menu_saver([])
            print("Menu reset!")

        else:
            print("Invalid input!")

if __name__ == "__main__":
    clear_screen()
    switch_good()
    input("Press enter to exit...")


import PySimpleGUI as sg
from random import choice

class Tools:
    def __init__(self):
        self

    @staticmethod
    def open_file_read(arch_name):
        with open(arch_name) as archive:
            return archive.read()

    def open_file_readlines(arch_name):
        with open(arch_name) as archive:
            return archive.readlines()

class Functionalities:
    def __init__(self):
        self

    def archive_name() -> str:
        while True:
            ARCH_NAME = sg.popup_get_text('Enter the archive name (without the file type)').strip() + ".txt"

            if ARCH_NAME == "":
                sg.popup("Invalid archive name")

            else:
                return ARCH_NAME

    def add(arch_name):
        add_name_popup = sg.popup_get_text("Enter a student's name").strip()

        if not arch_name == "":

            if not add_name_popup == "":
                with open(arch_name, 'a') as archive:
                    return archive.write(f'\n{add_name_popup}')

            else:
                sg.popup("Valid name required")

        else:
            with open(arch_name, 'a') as archive:
                return archive.write(f'\n{add_name_popup}')

    def pick_random(arch_name):
        names = Tools.open_file_readlines(arch_name)

        return choice(names).strip()

    def remove(arch_name, chosen):
        rows = Tools.open_file_readlines(arch_name)

        if not chosen == "":
            rows = [name.strip() for name in rows if name.strip() != chosen]

        else:
            sg.popup("Enter a valid name")

        with open(arch_name, 'w') as archive:
                for name in rows:
                    if rows.index(name) == len(rows)-1:
                        archive.write(name)

                    else:
                        archive.write(name + '\n')


from django.urls import path
from .views import RegisterAPIView, RegisterConfirmAPIView, LoginAPIView, AgentDetailAPIView, AgentListingsAPIView

app_name = "accounts"

urlpatterns = [
    path('login/', LoginAPIView.as_view(), name="login"),
    path('register/', RegisterAPIView.as_view(), name="register"),
    path('email/confirm/', RegisterConfirmAPIView.as_view(), name="email_confirm"),
    path('<str:username>/', AgentDetailAPIView.as_view(), name="detail"),
    path('<str:username>/listings/', AgentListingsAPIView.as_view(), name="listings")
]


import nltk
import re
from pickle import load
from nltk.corpus import stopwords
from nltk.stem import PorterStemmer
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences

def cleaning_one(stri):

    stri = stri.split(" ")
    for i in range(len(stri)):
        for j in ['@', '#']:
            if j in stri[i]:
                stri[i] = stri[i].replace(stri[i], "")
    stri = " ".join(stri)
    stri = re.sub(r"[\W+0-9+]", " ", stri)
    stri = re.findall(r"[A-Za-z]+", stri)
    stri = " ".join(stri)
    stri = stri.lower()

    return stri

def nltk_processing(stri):

    stop_words = set(stopwords.words('english'))
    ps = PorterStemmer()
    stri = stri.split(" ")
    stri = [ps.stem(i) for i in stri if i not in stop_words]
    stri = " ".join(stri)

    return stri

def tf_processing(corpus):

    with open('tokenizer.pkl', 'rb') as file:
        tokenizer = load(file)
    sequences = tokenizer.texts_to_sequences(corpus)
    maxlen = 115
    sequences = pad_sequences(sequences, maxlen=maxlen)

    return sequences


import torch
from matplotlib import pyplot as plt
import numpy as np

class visualizer(object):
    def __init__(self, num, y_label) -> None:
        self.data = []
        self.x = np.arange(0, num)
        self.labels = []
        self.y_label = y_label

    def load(self, data_path, label):
        data = torch.load(data_path)
        self.data.append(data)
        self.labels.append(label)
        print(label, max(data), min(data))
    def show(self):
        plt.cla()
        plt.clf()

        for i in range(len(self.data)):
            plt.plot(self.x, self.data[i], label = self.labels[i])

        plt.xlabel("Epochs")
        plt.ylabel(self.y_label)
        plt.legend()
        plt.show()

def load_acc(root_path, tag=""):
    acc_visualizer.load(f"./{root_path}/train_acc.txt", f"{tag} Train Acc")
    # acc_visualizer.load(f"./{root_path}/test_acc.txt", f"{tag} Test Acc")

def load_loss(root_path, tag=""):
    loss_visualizer.load(f"./{root_path}/train_loss.txt", f"{tag} Train Loss")
    # loss_visualizer.load(f"./{root_path}/test_loss.txt", f"{tag} Test Loss")

acc_visualizer = visualizer(20, "ACC")
loss_visualizer = visualizer(20, "Loss")

root_path = "./with_aug"
load_acc(root_path, "f32+Aug")
load_loss(root_path, "f32+Aug")

root_path = "./original"
load_acc(root_path,"f32")
load_loss(root_path,"f32")

root_path = "./float16"
load_acc(root_path,"f16")
load_loss(root_path,"f16")

root_path = "./float16+aug"
load_acc(root_path,"f16+Aug")
load_loss(root_path,"f16+Aug")

acc_visualizer.show()
loss_visualizer.show()


'''Dynamic programming example: memoized fib'''

'''Abstract characteristics of DP algorithms

* Small(linear) # of subproblems
* Can solve larger subproblems quickly based on the solutions of previously computed subproblems(Memoization)
* Solving all the subproblems makes it trivial to provide final solution'''

'''This is non memoized version, therefore it will be extremely slow
if the compute number is approximately at most 50'''
def fib(n):
    if n <= 1:
        return n
    return fib(n-1) + fib(n-2)

'''This is memoized version, it's using d as global variable stores the result of the computation, therefore
the fib2 doesn't need to repeat'''
d = {}
def fib2(n):
    if n <= 1:
        d[n] = n
    if n not in d:
        d[n] = fib2(n-1) + fib2(n-2)
    return d[n]

'''This is another memoized version with using local cache instead of global dictionary variable, therefore
the fib3's cache would not be conflict with other variable names'''
def fib3(n, cache = None):
    if cache is None:
        cache = {0:0,1:1}
    if n not in cache:
        cache[n] = fib3(n-1,cache)+fib3(n-2,cache)
    return cache[n]

'''fib bottom up'''
def bottom_up(n):
    fib = {}
    fib[0] = 0
    fib[1] = 1
    for i in range(2,n+1):
        fib[i] = fib[i-1]+ fib[i-2]
    return fib[n]

'''if the trial # is greater 20, let's say 50. Then while fib still computing the number, the fib2 and fib3
will be done. This is Dynamic Programming'''
# print(fib(20))
# print(fib2(100))
print(fib3(200))

# print(bottom_up(100))