from json import dumps as json_dumps
import markdown
from django import template
from django.utils.safestring import mark_safe

from statblocks.models import Action, Monster, StatblockBit, AbilityScore
from base.utils import Die
from places.models import Place
from places.serializers import PlaceLiteSerializer, PlaceSerializer

register = template.Library()

@register.simple_tag(takes_context=True)
def breakpoint_with_context(context):
    pass

@register.filter
def get_attr(obj, accessor):
    if hasattr(obj, accessor):
        return getattr(obj, accessor)
    else:
        return ''

@register.filter
def print_type_and_return(value):
    print(type(value))
    return value

@register.filter
def print_and_return(value):
    print(value)
    return value

@register.simple_tag
def val_in_iterable_in_dict_under_key(val, _dict, key):
    if _dict.get(key):
        _iterable = _dict[key]
        for item in _iterable:
            if str(item) == str(val):
                return True
    return False

@register.filter
def multiply(value, arg):
    return value * arg

@register.simple_tag
def get_attack_to_hit_for_monster(attack: Action, monster: Monster):

    mod_to_get = '{}_mod'.format(attack.attack_uses)
    if hasattr(monster, mod_to_get) and monster.proficiency is not None:
        return monster.proficiency + int(getattr(monster, mod_to_get))
    else:
        return 0

@register.filter
def range_or_reach_text(attack: Action):
    if not attack.attack_type:
        return ''
    if attack.attack_type in [Action.MELEE_WEAPON_ATTACK, Action.MELEE_SPELL_ATTACK]:
        return 'reach {}'.format(attack.get_reach_range_display())
    elif attack.range_secondary:  # ranged weapon attack or a ranged spell attack with a second range increment
        return 'range {}/{} ft.'.format(attack.reach_range, attack.range_secondary)
    else:  # ranged spell attack or a ranged weapon attack without a second range increment
        return 'range {}'.format(attack.get_reach_range_display())

@register.simple_tag
def avg_with_die_in_parens(num_die, die_type, constant_to_add=None):
    avg = Die.expected_value(num=num_die, size=die_type)
    if constant_to_add is None or constant_to_add == 0:
        return '{} ({}d{})'.format(avg, num_die, die_type)
    elif constant_to_add > 0:
        return '{} ({}d{} + {})'.format(
            avg + constant_to_add,
            num_die,
            die_type,
            constant_to_add
        )
    else:
        return '{} ({}d{} - {})'.format(
            avg + constant_to_add,
            num_die,
            die_type,
            -1*constant_to_add
        )

@register.filter
def get_mod(monster: Monster, mod):
    mod_to_get = '{}_mod'.format(mod)
    if hasattr(monster, mod_to_get):
        return getattr(monster, mod_to_get)
    else:
        return -5

@register.filter
def replace_generic_monster(description: str, monster: Monster=None):
    if description is None:
        return ''
    GENERIC_MONSTER_TAG = '$monster$'
    if monster is None:
        replace_with = 'monster'
    else:
        replace_with = monster.statblock_generic_name
    return description.replace(GENERIC_MONSTER_TAG, replace_with)

@register.filter
def fill_generic_statblock_descr(statbit: StatblockBit, monster: Monster=None):
    GENERIC_MONSTER_TAG = '$monster$'
    GENERIC_DC_TAG = '$dc$'
    GENERIC_SAVETYPE_TAG = '$savetype$'

    if statbit.description is None:
        return ''
    else:
        to_return = statbit.description
        if monster is not None:
            to_return = to_return.replace(
                GENERIC_MONSTER_TAG, monster.statblock_generic_name
            )
        if statbit.save_dc is not None:
            to_return = to_return.replace(
                GENERIC_DC_TAG, str(statbit.save_dc)
            )
        if statbit.save_type is not None:
            to_return = to_return.replace(
                GENERIC_SAVETYPE_TAG, str(AbilityScore.get_full_name(statbit.save_type)).title()
            )
        return to_return

@register.filter
def markdownify(text):
    return markdown.markdown(text, safe_mode='escape', extensions=[
        'markdown.extensions.nl2br',
        'markdown.extensions.tables',
        'markdown.extensions.sane_lists',
    ])

@register.filter
def user_props_json(user):
    try:
        props = {
            'is_authenticated': user.is_authenticated
        }
    except AttributeError:
        props = {}
    return mark_safe(json_dumps(props))

@register.filter
def place_json(place):
    if not place:
        return ''
    elif isinstance(place, Place):
        serializer = PlaceSerializer(place)
    else:
        serializer = PlaceLiteSerializer(place, many=True)
    return mark_safe(json_dumps(serializer.data))

@register.simple_tag(takes_context=True)
def template_context_to_json(context):
    to_return = {}
    api_url = context.get('api_url', None)
    if api_url:
        to_return['api_url'] = api_url
    user = context.get('user', None)
    profile = None
    if user:
        to_return['user'] = {
            'is_authenticated': user.is_authenticated
        }
        if user.is_authenticated:
            profile = user.profile
    # todo - alternative way of getting profile
    if profile:
        campaign = profile.cur_campaign
        if campaign:
            to_return['campaign'] = {
                'place_inclusion_distance': campaign.place_inclusion_distance
            }

    return mark_safe(json_dumps(to_return))


from Consts import Consts
from requests import post, get
from threading import Lock
from pickle import dump, load
from os.path import isfile
from datetime import datetime
import Networking

mutex = Lock()

class Ingest:
    def __init__(self):
        # Loading data from file if available
        if isfile(Consts.INGEST_ID_BACKUP):
            with open(Consts.INGEST_ID_BACKUP, 'rb') as backup:
                count = load(backup)
            self.__countid = count
        else:
            self.__countid = 0

    # Sending a new scan to the PROCESS module and returning the scan id
    # While also updating the list of scans
    def add_scan(self, content):
        # Locking the count id resource
        mutex.acquire()
        self.__countid += 1

        # Backing up count id
        with open(Consts.INGEST_ID_BACKUP, 'w+b') as backup:
            dump(self.__countid, backup)
        mutex.release()

        # Send a new scan task to the PROCESS module
        # Checking availability of the service
        if Networking.check_connection('127.0.0.1', Consts.PROCESS_PORT):
            # Adding the scan to the scans list
            post("http://127.0.0.1:" + str(Consts.PROCESS_PORT) +
                 "/addtoqeue/" + str(self.__countid) + "/" + str(content) + "/" + str(datetime.now()))
            return self.__countid

        # Go a step back as a call could not be made
        mutex.acquire()
        self.__countid -= 1
        mutex.release()

        # Return failure value
        return -1


# run_search.py
# 使用一个常驻线程执行搜索任务
# Written by Steve D. J. on 2022/7/6.

import json
import time
import os
from threading import Thread
# from multiprocessing import Process

import eventlet

from database_new import DATABASE
from email_sender import EmailSender
from controller import CONTROLLER

class Runner:
    """
    搜索任务队列：
    search_task_queue: (list) 待处理的搜索任务，其中每个元素为列表 [robust_keywords, result_dir]

    """
    def __init__(self):
        self.search_task_queue = []
        # self.thread = Thread(target=self.search_thread)
        # self.thread.start()
        # self.process = Process(target=self.search_thread)
        # self.process.start()

    def run_search(self, robust_keywords: str, timestamp: int, raw_keywords, start_time, end_time, filter_article_type, filter_age, filter_language, filter_species, filter_sex):
        """适用于单个线程的执行搜索及搜索完成善后任务的函数

        将 robust_keywords 输入搜索脚本，启动搜索服务；完成搜索后将本次搜索在 search_history 表中的条目修改为已完成搜索

        :param robust_keywords: (str) 经过鲁棒性处理后的搜索关键词组合
        :param timestamp: (int) 本次搜索对应的搜索记录的时间戳
        :return: None
        """
        print("Searching")

        # 获取结果保存路径
        history = DATABASE.get_result(timestamp)[0]
        result_timestamp = history[1]
        result_dir = 'static/search_result/' + str(result_timestamp) + '/'

        # 判断结果保存路径是否已经存在
        if os.path.exists(result_dir) is False:
            os.mkdir(result_dir)

        # TODO: 启动搜索，使用 robust_keywords 作为关键词进行搜索，将 paper_info.xlsx 和 clue_info.xlsx 两个文件输出到 result_dir 下

        # TODO: 在这里执行翻译，Thread()中 target=函数名（不要加括号） args=实参元组
        # translate_thread = Thread(target=, args=())       # 添加函数后取消注释
        # translate_thread.start()      # 添加函数后取消注释
        # TODO: 在这里执行NLP
        # NLP_thread = Thread(target=, args=())     # 添加函数后取消注释
        # NLP_thread.start()        # 添加函数后取消注释

        # 阻塞主线程
        # translate_thread.join()       # 添加函数后取消注释
        # NLP_thread.join()     # 添加函数后取消注释

        # 测试模式
        if CONTROLLER.test_mode is True:
            result_dir = 'static/search_result/114514/'

        # 查看结果文件是否已写入指定目录
        if os.path.exists(result_dir+'paper_info.xlsx') and os.path.exists(result_dir+'clue_info.xlsx') and os.path.exists(result_dir+'web_session.zip') and os.path.exists(result_dir+'clue_info.json') and os.path.exists(result_dir+'file.list'):
            # 从json文件中提取结果文献的 abstract_highlight 字段，生成HTML标签，保存至数据库 paper_abstract 表
            if CONTROLLER.test_mode is True:
                # 更改至测试用路径
                result_dir = 'static/json_data_test/'

            # 读取 file.list 获取包含结果文献信息的json文件目录
            file_list = open(result_dir + 'file.list', 'r')
            json_dir_list = file_list.readlines()
            for json_dir in json_dir_list:
                json_dir = json_dir[:-1]  # 删除换行符 \n
                raw_paper_info = json.load(open(json_dir, 'r'))
                pmid = int(raw_paper_info['pmid'])
                abstract_highlight_list = raw_paper_info['abstract_highlight']
                # 生成带有高亮的HTML字符串
                abstract_highlight_str = ''
                for i in range(len(abstract_highlight_list)):
                    word = abstract_highlight_list[i]
                    if word != '':
                        if word[0] == '<':
                            color_sp = word.find('font_color=') + 11
                            color_ep = word.find('>')
                            color = word[color_sp:color_ep]
                            abstract_highlight_str += ''
                            abstract_highlight_str += abstract_highlight_list[i + 1] + ''
                            try:
                                abstract_highlight_list[i + 1] = ''
                            except:
                                pass
                        else:
                            abstract_highlight_str += word
                # 写入数据库
                # DATABASE.add_paper_highlight_abstract(pmid, abstract_highlight_str)

                # 将高亮文本以文本文件的形式保存至指定目录
                highlight_dir = 'static/highlight_text/'
                category_num = pmid % 996       # pmid 除 996 取余数作为存放目录
                highlight_dir += str(category_num) + '/'
                if os.path.exists(highlight_dir) is False:
                    os.mkdir(highlight_dir)
                highlight_text_file = open(highlight_dir + str(pmid) + '.txt', 'w')
                highlight_text_file.write(abstract_highlight_str)
                highlight_text_file.close()

            # 将数据库中所有搜索该关键词的搜索记录标记为已完成搜索
            DATABASE.search_completed(raw_keywords, start_time, end_time, filter_article_type, filter_age, filter_language,
                                      filter_species, filter_sex)

            # 向发起搜索的用户发送提醒邮件
            # 生成验证码
            uuids = DATABASE.get_uuids_with_keywords(raw_keywords, start_time, end_time, filter_article_type, filter_age,
                                                     filter_language, filter_species, filter_sex)
            for uuid in uuids:
                uuid = uuid[0]
                user = DATABASE.get_user(uuid)
                email = user.email
                username = user.username
                email_sender = EmailSender(email, username)
                email_sender.generate_search_completed_content(robust_keywords)
                # 发送验证邮件
                email_sender.send()

    def search_thread(self):
        while True:
            if len(self.search_task_queue) > 0:
                search_task = self.search_task_queue[0]
                self.search_task_queue.pop(0)
                eventlet.monkey_patch()
                with eventlet.Timeout(CONTROLLER.search_max_time, False):
                    # print(search_task)
                    self.run_search(search_task[0], search_task[1], search_task[2], search_task[3], search_task[4], search_task[5], search_task[6], search_task[7], search_task[8], search_task[9])
            else:
                time.sleep(1)

SEARCH_RUNNER = Runner()


import cv2
import numpy as np
import pyautogui
import time

resolution = (1920,1080)
x = time.time()
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('vid%s.avi'%(x),fourcc,20.0,(resolution))
fps = 60
prev = 0
while True:
    time_elapsed = time.time() - prev
    img = pyautogui.screenshot()
    if time_elapsed > 1.0/fps:
        prev = time.time()
        frame = np.array(img)
        frame = cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)
        out.write(frame)
    cv2.waitKey(40)
cv2.destroyAllWindows()
cv2.release()


from currency_converter import CurrencyConverter
from tkinter import *
import tkinter as tk

window = tk.Tk()

window.geometry('500x360')
a = CurrencyConverter()
def clicked():
    amount = int(e1.get())
    cur1 = e2.get()
    cur2 = e3.get()
    data = a.convert(amount,cur1,cur2)
    l5 = tk.Label(window, text = data,font = "Times 25 bold").place(x = 230, y= 290)

l1 = tk.Label(window, text = "Currency Converter", font = "Times 20 bold").place(x =100,y=30)
l2 = tk.Label(window, text="Enter amount here:",font = "Times 18 bold").place(x = 50, y = 80)
e1 = tk.Entry(window)

l3 = tk.Label(window, text="Enter currency here:",font = "Times 18 bold").place(x = 50, y = 130)
e2 = tk.Entry(window)

l4 = tk.Label(window, text="Enter require currency:",font = "Times 18 bold").place(x = 50, y = 180)
e3 = tk.Entry(window)

b1 = tk.Button(window, text = "click",command = clicked).place(x = 230,y = 240)
e1.place(x = 300, y = 90)
e2.place(x = 300, y = 140)
e3.place(x = 300, y = 190)
window.mainloop()

a = CurrencyConverter()
# print(a.convert(12,"USD","INR"))


#!/usr/bin/env python3

from __future__ import print_function
from robotic_arm.srv import InverseKinematics,InverseKinematicsResponse
import rospy
import numpy as np
from std_msgs.msg import Time
from std_msgs.msg import Header
from std_msgs.msg import Duration
from trajectory_msgs.msg import JointTrajectory
from trajectory_msgs.msg import JointTrajectoryPoint

# Forward Kinematics function
def forward_kinematics(dh_params):
    theta = np.deg2rad(dh_params[0, :])
    alpha = np.deg2rad(dh_params[1, :])
    a = dh_params[2, :]
    d = dh_params[3, :]

    num_joints = len(a)
    joint_locations = np.zeros((num_joints + 1, 3))
    T = np.eye(4)

    for i in range(num_joints):
        A = np.array([[np.cos(theta[i]), -np.sin(theta[i]) * np.cos(alpha[i]),
                       np.sin(theta[i]) * np.sin(alpha[i]), a[i] * np.cos(theta[i])],
                      [np.sin(theta[i]), np.cos(theta[i]) * np.cos(alpha[i]),
                       -np.cos(theta[i]) * np.sin(alpha[i]), a[i] * np.sin(theta[i])],
                      [0, np.sin(alpha[i]), np.cos(alpha[i]), d[i]],
                      [0, 0, 0, 1]])

        T = np.dot(T, A)
        joint_locations[i + 1, :] = T[:3, 3].T

    return joint_locations

def jacobian(dh, delta_theta):
    jac = np.zeros((3, len(dh[0,:])))  # Initialize an empty Jacobian matrix

    temp = np.copy(dh)
    for i in range(len(dh[0, :])):

        temp = np.copy(dh)
        temp[0, i] = temp[0, i] - delta_theta
        ee_pos0 = forward_kinematics(temp)  # Assuming func is defined elsewhere
        ee_pos0 = ee_pos0[-1, :].T

        #print(ee_pos0)

        temp = np.copy(dh)
        temp[0, i] = temp[0, i] + delta_theta
        ee_pos1 = forward_kinematics(temp)  # Assuming func is defined elsewhere
        ee_pos1 = ee_pos1[-1, :].T

        df_dtheta = (ee_pos1 - ee_pos0) / (2 * delta_theta)

        jac[0, i] = df_dtheta[0];
        jac[1, i] = df_dtheta[1];
        jac[2, i] = df_dtheta[2];

    return jac

# Inverse Kinematics function
def inverse_kinematics(dh, ee_pos_target, tol, max_iter):

    temp = np.copy(dh)

    theta_current = temp[0, :]
    iter = 0
    while True:
        temp[0, :] = theta_current

        ee_pos_current = forward_kinematics(temp)
        ee_pos_current = ee_pos_current[-1, :]

        jac = jacobian(temp, 0.00001)
        jac_inv = np.linalg.pinv(jac, rcond=1e-7)

        delta = (ee_pos_target - ee_pos_current).T

        theta_current = theta_current.T

        theta_update = theta_current + np.dot(jac_inv, delta)

        theta_current = theta_update.T
        iter = iter + 1
        val = np.linalg.norm(delta);
        print("Running IK solver, tol: {:.9f}, iter: {:.1f}".format(val, iter))
        if val < tol or iter >=max_iter:
            if val > tol and iter >=max_iter:
                print("IK solver could not converge")
            else:
                print("IK Solver converged!")
            break

    theta_current = np.mod(theta_current, 360)

    for i in range(len(theta_current)):
        if theta_current[i] > 180:
            theta_current[i] -= 360

    theta_out = theta_current
    temp[0, :] = theta_out
    joints = forward_kinematics(temp)

    return theta_out, joints

def handle_IK(req):

    theta = rospy.get_param("/DH_params/theta")
    alpha = rospy.get_param("/DH_params/alpha")
    a = rospy.get_param("/DH_params/a")
    d = rospy.get_param("/DH_params/d")
    tol = rospy.get_param("/IK_solver/tol")
    max_iter = rospy.get_param("/IK_solver/max_iter")
    x_target = rospy.get_param("/target/x")
    y_target = rospy.get_param("/target/y")
    z_target = rospy.get_param("/target/z")

    ind = req.ind;

    dh_params = np.array([theta, alpha, a, d])
    ee_pos_target = np.array([x_target[ind], y_target[ind], z_target[ind]])

    if req.move == True and ind<=len(x_target)-1:

        theta_out, joints = inverse_kinematics(dh_params, ee_pos_target, tol, max_iter)

        theta_rad = np.deg2rad(theta_out)

        pub = rospy.Publisher("/arm_controller/command", JointTrajectory, queue_size=10)

        joints_str = JointTrajectory()
        joints_str.header = Header()
        joints_str.header.stamp = rospy.Time.now()
        joints_str.joint_names = ['arm_1_joint', 'arm_2_joint', 'arm_3_joint', 'arm_4_joint', 'arm_5_joint', 'arm_6_joint']

        point = JointTrajectoryPoint()
        point.positions = [theta_rad[0], theta_rad[1], theta_rad[2], theta_rad[3], theta_rad[4], theta_rad[5]]
        point.time_from_start = rospy.Duration(2)

        joints_str.points.append(point)
        print("Moving Robotic Arm ...")
        pub.publish(joints_str)
        print("Movement Complete!")

    else:
        if ind>len(x_target)-1:
            print('Target Index Out of Bounds')
        theta_out = [0, 0, 0, 0, 0, 0]

    return InverseKinematicsResponse(theta_out[0], theta_out[1], theta_out[2], theta_out[3], theta_out[4], theta_out[5])

def IK_server():
    rospy.init_node('IK_server')
    s = rospy.Service('Inverse_Kinematics', InverseKinematics, handle_IK)
    print("Ready to perform Inverse Kinematics.")
    rospy.spin()

if __name__ == "__main__":
    IK_server()


import tflearn
from tflearn.layers.conv import conv_2d, max_pool_2d
from tflearn.layers.core import input_data, dropout, fully_connected
from tflearn.layers.estimator import regression
from tflearn.data_preprocessing import ImagePreprocessing
from tflearn.data_augmentation import ImageAugmentation

# Build the preloader array, resize images to 128x128
from tflearn.data_utils import image_preloader
from tflearn.metrics import R2

#%%
import numpy as np
from numpy.random import randint

import random

import os
from random import sample

import tensorflow as tf

from PIL import Image, ImageOps

#%%

# Real-time data preprocessing
img_prep = ImagePreprocessing()
img_prep.add_featurewise_zero_center()
img_prep.add_featurewise_stdnorm()

# Real-time data augmentation
img_aug = ImageAugmentation()
img_aug.add_random_flip_leftright()
img_aug.add_random_rotation(max_angle=25.)

def defineArchitecture():

	# Input is a 32x32 image with 1 color channels (grayscale)
	network = convnet = input_data(shape=[None, 32, 32, 1], data_preprocessing=img_prep,
                     data_augmentation=img_aug, name='input')

	network = conv_2d(network, 32, 1, activation='relu', regularizer='L2')

	network = max_pool_2d(network, 2)

	network = conv_2d(network, 64, 1, activation='relu', regularizer='L2')

	network = max_pool_2d(network, 1)

	network = conv_2d(network, 64, 1, activation='relu', regularizer='L2')

	network = max_pool_2d(network, 2)

	# Step 6: Fully-connected 512 node neural network
	network = fully_connected(network, 512, activation='relu')

	network = dropout(network, 0.5)

	network = fully_connected(network, 16, activation='softmax')
	network = regression(network, optimizer='adam', learning_rate=0.001, loss='categorical_crossentropy', name='targets')

	return network
#%%

model = tflearn.DNN(defineArchitecture(), tensorboard_verbose=0, tensorboard_dir="/output")

train_images = []
train_labels = []

test_images = []
test_labels = []

train_dataset_file = 'files.txt'

feature_set = 'corpus.txt'
with open(feature_set) as inFile:
	list = []
	for line in inFile:
		parts = line.split(' ')
		labels = []
		for i in parts[1:]:
			labels.append(float(i))
		list.append(labels)
	Y = np.array(list)

X, _ = image_preloader(train_dataset_file, image_shape=(32, 32),   mode='file', categorical_labels=False, normalize=False, grayscale=True)
X = np.reshape(X, (-1, 32, 32, 1))

model.fit({'input': X}, {'targets': Y}, shuffle=True, batch_size=96, n_epoch=300, validation_set=0.2, show_metric=True, run_id='da-simulated')

del tf.get_collection_ref(tf.GraphKeys.TRAIN_OPS)[:]

model.save('da.model')

print("Testing")

folder_names = ["7","8","9","10"]
direction_names = ["Up", "Down", "Left", "Right"]

images = []

for dir in folder_names:
	for subdir in os.listdir(dir):
		images.append(dir + "/" + subdir + "/" + sample(os.listdir(dir + "/" + subdir),1)[0])

predictions = []

for img in images:
	image_vector = np.array(Image.open(img)).reshape(-1, 32, 32, 1).astype("float")
	prediction = model.predict(image_vector)
	#print(img)
	#print(np.round(prediction, 2))

	possibilities = (-prediction[0]).argsort()[:3]

	output = img + "\t\t"
	for pos in possibilities:
		output = output + " " + folder_names[int(pos/len(folder_names))] + "-" + direction_names[pos%len(direction_names)] + "(" + str(round(prediction[0][pos]*100)) + "%) "

	print(output)


import boto3
import json
from hashlib import sha256
import string
import random
import time
import argparse

def add_api_key_to_dynamodb(organization_ID, api_key, iam_user, graphql_api_id, env):

    table_name = 'APIKeyPermission'

    client_session = boto3.Session(profile_name=iam_user)

    dynamo_client = client_session.resource('dynamodb')

    full_table_name = table_name + '-' + graphql_api_id + '-' + env

    table = dynamo_client.Table(full_table_name)

    api_key_hashed = sha256(api_key.encode('utf-8')).hexdigest()

    id = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(10)) + str(int(time.time()*1000))

    table.put_item(
        Item={
            "id": id,
            "APIKeyHashed": api_key_hashed,
            "organizationID": organization_ID
        }
    )

if __name__ == '__main__':

    parser = argparse.ArgumentParser(description='Add api_key to dynamodb')
    parser.add_argument('organization_ID', help='organizationID : This is a string which uniquely identifies the organization')
    parser.add_argument('api_key', help='API_Key: API_Key which can be used to access the api for the organization')

    args = parser.parse_args()

    organization_ID = args.organization_ID
    api_key = args.api_key

    with open('parameters.json') as parameters_file:
        parameters = json.load(parameters_file)

    destination_iam_user = parameters['destination_iam_user']
    destination_graphql_api_id = parameters['destination_graphql_api_id']
    destination_env = parameters['destination_env']
    print(destination_env, destination_iam_user, destination_graphql_api_id)
    add_api_key_to_dynamodb(organization_ID, api_key, destination_iam_user, destination_graphql_api_id, destination_env)


"""Solution to the ISBN Verifier exercise."""

def is_valid(isbn: str) -> bool:
    """Check whether the given ``isbn`` is valid.

    Args:
        isbn (str): the isbn number to check

    Returns:
        bool: ``True`` if the given ``isbn`` is valid.
    """

    digits = [x.replace('X', '10') for x in list(isbn.replace('-', ''))]

    if len(digits) != 10 or any(not d.isdigit() for d in digits) or any(d == '10' for d in digits[:-1]):
        return False

    checksum = sum((10 - i) * int(d) for i, d in enumerate(digits))

    return checksum % 11 == 0


# https://codefights.com/interview/9JbYrEhK9tz6ANKLC
def reverseVowelsOfString(s):
    vowels = ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']
    s_vowels = []
    s_list = list(s)
    i = 0
    special_char = '+'
    for ch in s_list:
        if ch in vowels:
            s_vowels.append(ch)
            s_list[i] = special_char
        i = i + 1
    j = 0
    k = len(s_vowels) - 1
    for ch in s_list:
        if ch is special_char:
            s_list[j] = s_vowels[k]
            k = k - 1
        j = j + 1

    return "".join(s_list)

print(reverseVowelsOfString("Sore was I ere I saw Eros."))


# -*- coding: utf-8 -*-
import pandas as pn
import numpy as np
import codecs
import re
import urllib2

def valid_and_separate(line):
    vals = line.split(';')
    if len(vals) != 2:
        return None
    for i in range(2):
        v = re.sub(r'[\.\,\%«"\)\(]', '', vals[i]).strip()
        if not v:
            return None
        vals[i] = v
    if vals[0] == vals[1]:
        return None
    return vals

def readvocub(filename):
    tr = {}
    with codecs.open(filename, 'r', encoding='utf8') as fin:
        for line in fin:
            vals = valid_and_separate(line)
            if vals is None:
                continue
            tr[vals[0]] = [vals[1]]
    fin.close()
    return tr

def request(words):
    data = {}
    data = words
    req = urllib2.Request()


####  This script is draw points in 3D space with chosed axis
from mpl_toolkits.mplot3d import Axes3D  # noqa: F401 unused import

from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
import numpy as np
import json
from os import walk
import random

JSON_PATH = "remove_data/old_count/"
JSON_PREFIX = "count_result_"

all_axis = [
    "Subject",
    "Scene",
    "Aspect",
    "Action",
    "Moment",
    "Non_sequitur"
    ]

import matplotlib,numpy
import pylab

cmap = matplotlib.colors.ListedColormap ( numpy.random.rand ( 256,3))
# pylab.imshow ( Z, cmap = cmap)
# pylab.show()

def normalize_vector(input_vector):
    ### normalize input list (vecter)
    total = 0
    normalized_vector = []
    for number in input_vector:
        total = total + number

    for number in input_vector:
        if total != 0:
            new_number = float(number/float(total))
        else:
            new_number = float(0)

        normalized_vector.append(new_number)

    return normalized_vector

def chose_axis(axis_1, axis_2, axis_3, data):
    ### choose needed 3 axis

    x_axis = axis_1
    # print(regroup_axis(data, axis_1))
    column_x = regroup_axis(data, axis_1)
    y_axis= axis_2
    # print(regroup_axis(data, axis_2))
    column_y = regroup_axis(data, axis_2)
    z_axis = axis_3
    # print(regroup_axis(data, axis_3))
    column_z = regroup_axis(data, axis_3)
    print(" x = "+x_axis+", y = "+y_axis+" z = "+z_axis)

    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')

    n = 100
    marker_sign = "o"
    x_array = np.array(column_x)
    y_array = np.array(column_y)
    z_array = np.array(column_z)

    # xs = randrange(n, 23, 32)
    # ys = randrange(n, 0, 100)
    # zs = randrange(n, 10, 20)

    ax.scatter(x_array, y_array, z_array, marker=marker_sign)

    ax.set_xlabel(axis_1)
    ax.set_ylabel(axis_2)
    ax.set_zlabel(axis_3)

    plt.show()

def chose_axis_w_cluster(axis_1, axis_2, axis_3, data, cluster_labels, max_label):
    ### choose needed 3 axis

    x_axis = axis_1
    # print(regroup_axis(data, axis_1))
    column_x = regroup_axis(data, axis_1)
    y_axis= axis_2
    # print(regroup_axis(data, axis_2))
    column_y = regroup_axis(data, axis_2)
    z_axis = axis_3
    # print(regroup_axis(data, axis_3))
    column_z = regroup_axis(data, axis_3)
    print(" x = "+x_axis+", y = "+y_axis+" z = "+z_axis)

    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')

    n = 100
    marker_sign = "o"
    x_array = np.array(column_x)
    y_array = np.array(column_y)
    z_array = np.array(column_z)

    # xs = randrange(n, 23, 32)
    # ys = randrange(n, 0, 100)
    # zs = randrange(n, 10, 20)

    # scatter_x = np.array([1,2,3,4,5])
    # scatter_y = np.array([5,4,3,2,1])
    group = np.array(cluster_labels)

    #### TODO: make the color dictionary randomly generated.
    cdict = {
        0: 'red', 1: 'blue', 2: 'green',
        3: 'orange', 4: 'purple', 5: 'brown',
        6: 'pink', 7: 'cyan', 8: 'gold',
        9: 'salmon', 10: 'darkturquoise', 11: 'orchid'
    }
    # cdict = {}
    # for index in range(max_label):
    #     r = random.random()

    #     b = random.random()

    #     g = random.random()

    #     color = (r, g, b)
    #     print(color)
    #     rgb = np.random.rand(3,)
    #     cdict[index] = rgb
    # print(cdict)
    # new_cmap = rand_cmap(100, type='bright', first_color_black=True, last_color_black=False, verbose=True)

    # fig, ax = plt.subplots()
    for g in np.unique(group):
        ix = np.where(group == g)
        ax.scatter(x_array[ix], y_array[ix], z_array[ix], c = cdict[g], label = g)
        # ax.scatter(x_array[ix], y_array[ix], z_array[ix], c = cmap[g], label = g)

    ax.legend()
    # plt.show()

    # ax.scatter(x_array, y_array, z_array, marker=marker_sign)

    ax.set_xlabel(axis_1)
    ax.set_ylabel(axis_2)
    ax.set_zlabel(axis_3)

    plt.show()

def axis_mapping(axis_name, name_array):
    ## mapping name to index

    target_index = -1
    list_count = 0
    for name in name_array:
        if name == axis_name:
            target_index = list_count
            break

        list_count = list_count + 1

    return target_index

def regroup_axis(data, axis_name):
    # load a vector array (many rows), and regroup then column wise
    target_vector = []
    for vector in data:
        ### expected [0.1, 0.2]
        ### expected [0.2, 0.3]
        ### expected [0.1, 0.2]
        # print(vector)
        target_vector.append(vector[axis_mapping(axis_name, all_axis)])
        #  print(vector[axis_mapping(axis_name, all_axis)])

    return target_vector

def json_2_vector(json_path, label_array):
    # load counts from json file and make them a list (be used as a vector)
    target_vector = []
    label_index = {}

    label_index_count = 0
    for label in label_array:
        if label not in label_index:
            label_index[label] = label_index_count
            label_index_count = label_index_count + 1

    for label in label_index:
        # a vector with all zeros
        target_vector.append(float(0))

    with open(json_path) as json_file:
        transition_counts = json.load(json_file)
        json_file.close()

        for transition_count in transition_counts:
            # target_vector.append(transition_counts[transition_count])
            target_vector[label_index[transition_count]] = float(transition_counts[transition_count])

    return target_vector

if __name__ == "__main__":
    print("Show the points in vector space")

    #### test imagine data
    # test_data_1 = [0.1, 0.2, 0.3, 0.0, 0.2, 0.1, 0.1]
    # test_data_2 = [0.2, 0.3, 0.1, 0.1, 0.1, 0.0, 0.2]
    # data_1 = {}
    # data_2 = {}

    # data_1["Action"] = test_data_1[0]
    # data_1["Aspect"] = test_data_1[1]
    # data_1["Moment"] = test_data_1[2]
    # data_1["Non_sequitur"] = test_data_1[3]
    # data_1["Other"] = test_data_1[4]
    # data_1["Scene"] = test_data_1[5]
    # data_1["Subject"] = test_data_1[6]

    # data_2["Action"] = test_data_2[0]
    # data_2["Aspect"] = test_data_2[1]
    # data_2["Moment"] = test_data_2[2]
    # data_2["Non_sequitur"] = test_data_2[3]
    # data_2["Other"] = test_data_2[4]
    # data_2["Scene"] = test_data_2[5]
    # data_2["Subject"] = test_data_2[6]

    # data = [test_data_1, test_data_2]

    # chose_axis("Action", "Subject", "Aspect", data)

    # JSON_PATH

    data = []
    print(JSON_PATH)
    for (_, _, file_names) in walk(JSON_PATH):
        # print(file_names)
        for single_file in file_names:
            print(single_file)

            book_vector = json_2_vector(JSON_PATH+single_file, all_axis)
            normalized_book_vector = normalize_vector(book_vector)

            data.append(normalized_book_vector)
            print(normalized_book_vector)

    # chose_axis("Action", "Subject", "Aspect", data)
    #print(type(data))

    ### data is the target data
    ### k-means

    num_cluster_centroid = 6
    #### test data
    # X = np.array([[1, 2], [1, 4], [1, 0], [10, 2], [10, 4], [10, 0]])

    data_for_clustering = np.array(data)
    kmeans = KMeans(n_clusters=num_cluster_centroid, random_state=0).fit(data_for_clustering)
    print(kmeans.labels_)

    # print(kmeans.predict([[0, 0], [12, 3]]))
    print(kmeans.cluster_centers_)
    data_clustering_labels = kmeans.labels_
    chose_axis_w_cluster("Action", "Subject", "Aspect", data, data_clustering_labels,num_cluster_centroid)


import networkx as nx
from subprocess import call
import igraph
from igraph import VertexCover
import os
import glob

from circulo.data.databot import CirculoData

class SchoolData(CirculoData):

    def __download__(self):
        """
        Downloads graphs from http://www.sociopatterns.org/datasets/primary-school-cumulative-networks/
        and saves them in a directory data. If data already exists, it will not redownload
        the files
        """

        try:
            # Probably shouldn't be starting a subprocess, do this with a library
            # like urllib2
            call(["curl", "--create-dirs","-o", os.path.join(self.raw_data_path, "out_#1.gexf.gz"),"http://www.sociopatterns.org/wp-content/uploads/2014/05/sp_data_school_day_[1-2]_g.gexf_.gz"])
        except Exception as e:
            print("cURL failed -- make sure you have cURL, and make sure the site still has the graph data.")
            raise(e)
        for filename in glob.glob(os.path.join(self.raw_data_path,"*.gz")):
            call(["gunzip", filename])

    def __prepare__(self):

        for f in glob.glob(os.path.join(self.raw_data_path, "*.gexf")):

            G = nx.read_gexf(f)
            for node in G.node:
                for attrib in G.node[node]:
                    if type(G.node[node][attrib]) == dict:
                        # graphML doesn't play nice with dictionaries as attributes.
                        # this line just deletes positional information.
                        G.node[node][attrib] = 0
            #newFileName = f[:f.rfind('.')] + ".graphml"
            nx.write_graphml(G, self.graph_path)

    def get_ground_truth(self, G):

        class_list = G.vs['classname']
        class_dict = dict.fromkeys(class_list)

        #set the indices for lookup purposes. These will be the cluster ids
        for idx, k in enumerate(class_dict):
            class_dict[k] = []

        for student_number, class_id in enumerate(class_list):
            class_dict[class_id].append(student_number)

        cluster_list = []

        for cluster in class_dict.values():
            cluster_list.append(cluster)

        return VertexCover(G, cluster_list)

def main():
    databot = SchoolData("school")
    databot.get_ground_truth(databot.get_graph())

if __name__ == "__main__":
    main()


# coding:utf-8

import jieba
from wordcloud import WordCloud

import sys
reload(sys)
sys.setdefaultencoding('utf8')

from figure_painting import *

def get_words_frequency():
    # 打开文件并读取文本内容
    content = open('sgyy.txt','r').read()
    # 使用结巴分词对文本进行分词
    words = jieba.lcut(content)

    # 定义一个字典去存储分词结果和出现的次数
    counts = {}
    for word in words:
        # 我们忽略长度为1的词
        if len(word) == 1:
            continue
        if word == u'\r\n':
            continue
        counts[word] = counts.get(word, 0) + 1

    items = list(counts.items())

    # 根据items的第二个值进行从大到小的排序
    items.sort(key=lambda x:x[1], reverse=True)

    words_list_sort = []
    words_list_count = []

    for i in range(20):
        word, count = items[i]
        words_list_sort.append(word)
        words_list_count.append(count)
        # 格式化输出
        print ("{:<8}{:>5}".format(word, count))
        # print (word, count)

    return words_list_sort, words_list_count, words

def word_cloud(words):

    # 对切分结果重新拼接用于词云制作
    newtxt = " ".join(words)
    # 词云制作
    wordcloud = WordCloud(background_color='black',
                          width=800,
                          height=600,
                          font_path="/home/fuyinwen/Downloads/simhei.ttf",
                          max_words=100,
                          max_font_size=80
                          ).generate(newtxt)
    # 保存词云图
    wordcloud.to_file("word_cloud1.png")

def main():
    words_list_sort, words_list_count, words = get_words_frequency()
    # word_cloud(words)
    show_words_barh(words_list_sort, words_list_count)

if __name__ == '__main__':
    main()


import argparse

import funcx
from funcx.sdk.client import FuncXClient

def container_sum(event):
    return sum(event)

def test(fxc, ep_id):

    fn_uuid = fxc.register_function(
        container_sum,
        container_uuid="3861862b-152e-49a4-b15e-9a5da4205cad",
        description="New sum function defined without string spec",
    )
    print("FN_UUID : ", fn_uuid)

    task_id = fxc.run([1, 2, 3, 9001], endpoint_id=ep_id, function_id=fn_uuid)
    r = fxc.get_task_status(task_id)
    print("Got from status :", r)

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("-e", "--endpoint", required=True)
    args = parser.parse_args()

    print("FuncX version : ", funcx.__version__)
    fxc = FuncXClient()
    test(fxc, args.endpoint)


class Solution:
    def nextGreaterElements(self, nums: List[int]) -> List[int]:
        stack = []
        temp = [nums[0]]
        ans = [float('inf')]*len(nums)
        for idx , num in enumerate(nums):
            while stack and nums[stack[-1]] < num:
                ans[stack.pop()] = num
                temp.append(num)
            stack.append(idx)

        for idx , num in enumerate(ans):
            if num ==float('inf'):
                for val in temp:
                    if val > nums[idx]:
                        ans[idx] = val
                        break
                else:
                    ans[idx] = -1

        return ans


from __future__ import print_function, division, absolute_import
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.utils.model_zoo as model_zoo
import os
import sys
from util.logs import get_logger
from . import MODEL_REGISTRY

__all__ = ['InceptionV4', 'inceptionv4']
logger = get_logger('inception')

pretrained_settings = {
    'inceptionv4': {
        'imagenet': {
            'url': 'http://data.lip6.fr/cadene/pretrainedmodels/inceptionv4-8e4777a0.pth',
            'input_space': 'RGB',
            'input_size': [3, 299, 299],
            'input_range': [0, 1],
            'mean': [0.5, 0.5, 0.5],
            'std': [0.5, 0.5, 0.5],
            'num_classes': 1000
        },
        'imagenet+background': {
            'url': 'http://data.lip6.fr/cadene/pretrainedmodels/inceptionv4-8e4777a0.pth',
            'input_space': 'RGB',
            'input_size': [3, 299, 299],
            'input_range': [0, 1],
            'mean': [0.5, 0.5, 0.5],
            'std': [0.5, 0.5, 0.5],
            'num_classes': 1001
        }
    }
}

class BasicConv2d(nn.Module):

    def __init__(self, in_planes, out_planes, kernel_size, stride, padding=0):
        super(BasicConv2d, self).__init__()
        self.conv = nn.Conv2d(in_planes, out_planes,
                              kernel_size=kernel_size, stride=stride,
                              padding=padding, bias=False) # verify bias false
        self.bn = nn.BatchNorm2d(out_planes,
                                 eps=0.001, # value found in tensorflow
                                 momentum=0.1, # default pytorch value
                                 affine=True)
        self.relu = nn.ReLU(inplace=True)

    def forward(self, x):
        x = self.conv(x)
        x = self.bn(x)
        x = self.relu(x)
        return x

class Mixed_3a(nn.Module):

    def __init__(self):
        super(Mixed_3a, self).__init__()
        self.maxpool = nn.MaxPool2d(3, stride=2)
        self.conv = BasicConv2d(64, 96, kernel_size=3, stride=2)

    def forward(self, x):
        x0 = self.maxpool(x)
        x1 = self.conv(x)
        out = torch.cat((x0, x1), 1)
        return out

class Mixed_4a(nn.Module):

    def __init__(self):
        super(Mixed_4a, self).__init__()

        self.branch0 = nn.Sequential(
            BasicConv2d(160, 64, kernel_size=1, stride=1),
            BasicConv2d(64, 96, kernel_size=3, stride=1)
        )

        self.branch1 = nn.Sequential(
            BasicConv2d(160, 64, kernel_size=1, stride=1),
            BasicConv2d(64, 64, kernel_size=(1,7), stride=1, padding=(0,3)),
            BasicConv2d(64, 64, kernel_size=(7,1), stride=1, padding=(3,0)),
            BasicConv2d(64, 96, kernel_size=(3,3), stride=1)
        )

    def forward(self, x):
        x0 = self.branch0(x)
        x1 = self.branch1(x)
        out = torch.cat((x0, x1), 1)
        return out

class Mixed_5a(nn.Module):

    def __init__(self):
        super(Mixed_5a, self).__init__()
        self.conv = BasicConv2d(192, 192, kernel_size=3, stride=2)
        self.maxpool = nn.MaxPool2d(3, stride=2)

    def forward(self, x):
        x0 = self.conv(x)
        x1 = self.maxpool(x)
        out = torch.cat((x0, x1), 1)
        return out

class Inception_A(nn.Module):

    def __init__(self):
        super(Inception_A, self).__init__()
        self.branch0 = BasicConv2d(384, 96, kernel_size=1, stride=1)

        self.branch1 = nn.Sequential(
            BasicConv2d(384, 64, kernel_size=1, stride=1),
            BasicConv2d(64, 96, kernel_size=3, stride=1, padding=1)
        )

        self.branch2 = nn.Sequential(
            BasicConv2d(384, 64, kernel_size=1, stride=1),
            BasicConv2d(64, 96, kernel_size=3, stride=1, padding=1),
            BasicConv2d(96, 96, kernel_size=3, stride=1, padding=1)
        )

        self.branch3 = nn.Sequential(
            nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False),
            BasicConv2d(384, 96, kernel_size=1, stride=1)
        )

    def forward(self, x):
        x0 = self.branch0(x)
        x1 = self.branch1(x)
        x2 = self.branch2(x)
        x3 = self.branch3(x)
        out = torch.cat((x0, x1, x2, x3), 1)
        return out

class Reduction_A(nn.Module):

    def __init__(self):
        super(Reduction_A, self).__init__()
        self.branch0 = BasicConv2d(384, 384, kernel_size=3, stride=2)

        self.branch1 = nn.Sequential(
            BasicConv2d(384, 192, kernel_size=1, stride=1),
            BasicConv2d(192, 224, kernel_size=3, stride=1, padding=1),
            BasicConv2d(224, 256, kernel_size=3, stride=2)
        )

        self.branch2 = nn.MaxPool2d(3, stride=2)

    def forward(self, x):
        x0 = self.branch0(x)
        x1 = self.branch1(x)
        x2 = self.branch2(x)
        out = torch.cat((x0, x1, x2), 1)
        return out

class Inception_B(nn.Module):

    def __init__(self):
        super(Inception_B, self).__init__()
        self.branch0 = BasicConv2d(1024, 384, kernel_size=1, stride=1)

        self.branch1 = nn.Sequential(
            BasicConv2d(1024, 192, kernel_size=1, stride=1),
            BasicConv2d(192, 224, kernel_size=(1,7), stride=1, padding=(0,3)),
            BasicConv2d(224, 256, kernel_size=(7,1), stride=1, padding=(3,0))
        )

        self.branch2 = nn.Sequential(
            BasicConv2d(1024, 192, kernel_size=1, stride=1),
            BasicConv2d(192, 192, kernel_size=(7,1), stride=1, padding=(3,0)),
            BasicConv2d(192, 224, kernel_size=(1,7), stride=1, padding=(0,3)),
            BasicConv2d(224, 224, kernel_size=(7,1), stride=1, padding=(3,0)),
            BasicConv2d(224, 256, kernel_size=(1,7), stride=1, padding=(0,3))
        )

        self.branch3 = nn.Sequential(
            nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False),
            BasicConv2d(1024, 128, kernel_size=1, stride=1)
        )

    def forward(self, x):
        x0 = self.branch0(x)
        x1 = self.branch1(x)
        x2 = self.branch2(x)
        x3 = self.branch3(x)
        out = torch.cat((x0, x1, x2, x3), 1)
        return out

class Reduction_B(nn.Module):

    def __init__(self):
        super(Reduction_B, self).__init__()

        self.branch0 = nn.Sequential(
            BasicConv2d(1024, 192, kernel_size=1, stride=1),
            BasicConv2d(192, 192, kernel_size=3, stride=2)
        )

        self.branch1 = nn.Sequential(
            BasicConv2d(1024, 256, kernel_size=1, stride=1),
            BasicConv2d(256, 256, kernel_size=(1,7), stride=1, padding=(0,3)),
            BasicConv2d(256, 320, kernel_size=(7,1), stride=1, padding=(3,0)),
            BasicConv2d(320, 320, kernel_size=3, stride=2)
        )

        self.branch2 = nn.MaxPool2d(3, stride=2)

    def forward(self, x):
        x0 = self.branch0(x)
        x1 = self.branch1(x)
        x2 = self.branch2(x)
        out = torch.cat((x0, x1, x2), 1)
        return out

class Inception_C(nn.Module):

    def __init__(self):
        super(Inception_C, self).__init__()

        self.branch0 = BasicConv2d(1536, 256, kernel_size=1, stride=1)

        self.branch1_0 = BasicConv2d(1536, 384, kernel_size=1, stride=1)
        self.branch1_1a = BasicConv2d(384, 256, kernel_size=(1,3), stride=1, padding=(0,1))
        self.branch1_1b = BasicConv2d(384, 256, kernel_size=(3,1), stride=1, padding=(1,0))

        self.branch2_0 = BasicConv2d(1536, 384, kernel_size=1, stride=1)
        self.branch2_1 = BasicConv2d(384, 448, kernel_size=(3,1), stride=1, padding=(1,0))
        self.branch2_2 = BasicConv2d(448, 512, kernel_size=(1,3), stride=1, padding=(0,1))
        self.branch2_3a = BasicConv2d(512, 256, kernel_size=(1,3), stride=1, padding=(0,1))
        self.branch2_3b = BasicConv2d(512, 256, kernel_size=(3,1), stride=1, padding=(1,0))

        self.branch3 = nn.Sequential(
            nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False),
            BasicConv2d(1536, 256, kernel_size=1, stride=1)
        )

    def forward(self, x):
        x0 = self.branch0(x)

        x1_0 = self.branch1_0(x)
        x1_1a = self.branch1_1a(x1_0)
        x1_1b = self.branch1_1b(x1_0)
        x1 = torch.cat((x1_1a, x1_1b), 1)

        x2_0 = self.branch2_0(x)
        x2_1 = self.branch2_1(x2_0)
        x2_2 = self.branch2_2(x2_1)
        x2_3a = self.branch2_3a(x2_2)
        x2_3b = self.branch2_3b(x2_2)
        x2 = torch.cat((x2_3a, x2_3b), 1)

        x3 = self.branch3(x)

        out = torch.cat((x0, x1, x2, x3), 1)
        return out

# class ProjectorBlock(nn.Module):

#     def __init__(self, in_features, out_features):
#         super(ProjectorBlock, self).__init__()
#         self.op = nn.Conv2d(in_channels=in_features, out_channels=out_features, kernel_size=1, padding=0, bias=False)

#     def forward(self, inputs):
#         return self.op(inputs)

class LinearAttentionBlock(nn.Module):

    def __init__(self, in_features, normalize_attn=True, out_features = 512):
        super(LinearAttentionBlock, self).__init__()
        self.normalize_attn = normalize_attn
        self.op = nn.Conv2d(in_channels=in_features, out_channels=1, kernel_size=1, padding=0, bias=False)
        self.project = nn.Linear(in_features, out_features)

    def forward(self, l, g=None):
        N, C, W, H = l.size()
        if g is None:
            c = self.op(l)
        else:
            c = self.op(l+g) # batch_sizex1xWxH
        if self.normalize_attn:
            a = F.softmax(c.view(N,1,-1), dim=2).view(N,1,W,H)
        else:
            a = torch.sigmoid(c)
        g = torch.mul(a.expand_as(l), l)
        if self.normalize_attn:
            g = g.view(N,C,-1).sum(dim=2) # batch_sizexC
        else:
            g = F.adaptive_avg_pool2d(g, (1,1)).view(N,C)
        g = self.project(g)
        return c.view(N,1,W,H), g

@MODEL_REGISTRY.register()
class InceptionV4(nn.Module):

    def __init__(self, num_classes=1001, input_channel=3, attention=True):
        super(InceptionV4, self).__init__()
        # Special attributs
        self.input_space = None
        self.input_size = (299, 299, 3)
        self.mean = None
        self.std = None
        self.attention = attention
        # Modules
        self.feature1 = nn.Sequential(
            BasicConv2d(input_channel, 32, kernel_size=3, stride=2),
            BasicConv2d(32, 32, kernel_size=3, stride=1),
            BasicConv2d(32, 64, kernel_size=3, stride=1, padding=1),
            Mixed_3a(),
            Mixed_4a(),
            Mixed_5a(), #5
            nn.Dropout(0.2),
        )
        self.feature2 = nn.Sequential(
            Inception_A(),
            Inception_A(),
            Inception_A(),
            Inception_A(),
            Reduction_A(), # Mixed_6a 10
            nn.Dropout(0.2),
        )
        self.feature3 = nn.Sequential(
            Inception_B(), # 11
            Inception_B(),
            Inception_B(),
            Inception_B(),
            Inception_B(),
            Inception_B(),
            Inception_B(),
            Reduction_B(), # Mixed_7a
            Inception_C(),
            Inception_C(),
            Inception_C(),
            nn.Dropout(0.2),
        )
        if self.attention:
            self.attn1 = LinearAttentionBlock(384)
            self.attn2 = LinearAttentionBlock(1024)
            self.attn3 = LinearAttentionBlock(1536)

    def logits(self, features):
        # Allows image of any size to be processed
        adaptiveAvgPoolWidth = features.shape[2]
        x = F.avg_pool2d(features, kernel_size=adaptiveAvgPoolWidth)
        x = x.view(x.size(0), -1)
        # x = self.last_linear(x)
        return x

    def forward(self, input):
        f1 = self.feature1(input)
        f2 = self.feature2(f1)
        f3 = self.feature3(f2)
        # logger.info(f1.shape)
        # logger.info(f2.shape)
        # logger.info(f3.shape)
        if self.attention:
            c1, g1 = self.attn1(f1)
            c2, g2 = self.attn2(f2)
            c3, g3 = self.attn3(f3)
            gg = torch.cat((g1, g2, g3), dim=1)
            # logger.info(gg.shape)
        else:
            gg = self.logits(f3)
        return dict(feature=gg)

# def inceptionv4(num_classes=1000, pretrained='imagenet'):
#     if pretrained:
#         settings = pretrained_settings['inceptionv4'][pretrained]
#         assert num_classes == settings['num_classes'], \
#             "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes)

#         # both 'imagenet'&'imagenet+background' are loaded from same parameters
#         model = InceptionV4(num_classes=1001)
#         model.load_state_dict(model_zoo.load_url(settings['url']))

#         if pretrained == 'imagenet':
#             new_last_linear = nn.Linear(1536, 1000)
#             new_last_linear.weight.data = model.last_linear.weight.data[1:]
#             new_last_linear.bias.data = model.last_linear.bias.data[1:]
#             model.last_linear = new_last_linear

#         model.input_space = settings['input_space']
#         model.input_size = settings['input_size']
#         model.input_range = settings['input_range']
#         model.mean = settings['mean']
#         model.std = settings['std']
#     else:
#         model = InceptionV4(num_classes=num_classes)
#     return model

'''
TEST
Run this code with:
```
cd $HOME/pretrained-models.pytorch
python -m pretrainedmodels.inceptionv4
```
'''
if __name__ == '__main__':

    assert inceptionv4(num_classes=10, pretrained=None)
    print('success')
    assert inceptionv4(num_classes=1000, pretrained='imagenet')
    print('success')
    assert inceptionv4(num_classes=1001, pretrained='imagenet+background')
    print('success')

    # fail
    assert inceptionv4(num_classes=1001, pretrained='imagenet')


# https://www.hackerrank.com/challenges/s10-quartiles/problem?isFullScreen=true

def median(lst):
    lst.sort()
    mid = len(lst) // 2
    if len(lst) % 2 != 0:
        return lst[mid]
    else:
        return (lst[mid] + lst[mid -1])/2

def quartiles(arr):
    q2 = median(arr)

    n = len(arr)
    mid = len(arr) // 2

    if n % 2 != 0:
        q1 = median(arr[0:mid])
        q3 = median(arr[(mid + 1):n])
    else:
        q1 = median(arr[0:mid])
        q3 = median(arr[mid:n])
    return [int(x) for x in [q1, q2, q3]]


import csv

import pickle as pk
import numpy as np
import tensorflow as tf

def main():

    f = open('splitted dataset.pickle', 'rb')
    x_train, x_test, y_train, y_test = pk.load(f)

    csvfile = open('ai types.csv', newline='')
    reader = csv.reader(csvfile)

    n_conv_n_poll = [int(x) for x in next(reader)[1:]]
    n_filters = [int(x) for x in next(reader)[1:]]
    kernel_sizes = [int(x) for x in next(reader)[1:]]
    pool_sizes = [int(x) for x in next(reader)[1:]]
    activations = next(reader)[1:]
    losses = next(reader)[1:]
    optmizers = next(reader)[1:]
    n_layers = [int(x) for x in next(reader)[1:]]
    layers_sizes = [int(x) for x in next(reader)[1:]]
    dropout_values = [float(x) for x in next(reader)[1:]]

    model = get_model(activations, losses, optmizers)

def get_models(activations, losses, optmizers):

    for function in activations:
        for loss in losses:
            for optmizer in optmizers:
                model = tf.keras.models.Sequential([
                    tf.keras.layers.Dense()
                ])

    return model

if __name__ == "__main__":
    main()


from calendar import calendar
from importlib.resources import path
import os
import json
from re import S
from urllib import request
from datetime import datetime,date

from django.shortcuts import redirect ,  render
from django.shortcuts import get_object_or_404
from django.views.generic import TemplateView

from main import urls

from . import models
from main.models import Calendar,Event,GlobalEvent
from django.views.decorators.csrf import csrf_exempt
from rest_framework.views import APIView
from rest_framework import generics, filters
from rest_framework.response import Response
from rest_framework.status import (
    HTTP_200_OK as ST_200,
    HTTP_201_CREATED as ST_201,
    HTTP_204_NO_CONTENT as ST_204,
    HTTP_400_BAD_REQUEST as ST_400,
    HTTP_401_UNAUTHORIZED as ST_401,
    HTTP_404_NOT_FOUND as ST_404,
)
from rest_framework.permissions import AllowAny, IsAuthenticated
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi
from django.shortcuts import get_object_or_404
from django_filters.rest_framework import DjangoFilterBackend
from .serializers import    (CreateCalendarSerializer, CalendarIdSerializer, UserSerializer,
                            SwaggerUserSerializer, CreateEventSerializer,
                            SwaggerEventSerializer ,EventSerializer, PutEventSerializer,
                            GlobalEventSerializer, GetGlobalEventSerializer)
from django.contrib.auth.models import User
from .services import (get_weather, get_global_events, post_global_event,delete_global_events, get_global_events_id)

#Class to define Calendar methods
class CalendarView(APIView):
    permission_classes= (AllowAny,)

    def returnErrors(self,dic):
        err={}
        keys=dic.keys()
        for k in keys:
            if k == 'password':
                x= dic[k][0].split(".")
                title=x[0]+'.'+x[1]+'.'
                err[k]= title
            else:
                err[k]= dic[k][0].capitalize()
        return err

    #Below appears the code to generate the body in Swagger documentation
    @swagger_auto_schema(request_body=UserSerializer,responses={201: "Calendar successfully created",400: "Bad request (This status code gives more information of the request error)"})
    @csrf_exempt
    def post(self, request):
        data = request.data.copy()
        serializer= CreateCalendarSerializer(data=data, context={'request':request})
        if serializer.is_valid():
            serializer.save()
            return Response({"message": "Calendar successfully created", "user": serializer.data},status=ST_201)
        else:
            err= self.returnErrors(serializer.errors)
            return Response({"error": err},status=ST_400)

    @swagger_auto_schema(request_body=UserSerializer,responses={204: "No Content (Calendar successfully updated)",401: "Unauthorized (You need the JWT token to change your calendar information)"})
    def put(self,request):
        #If an user is not authenticated, throw the 401 error.
        if request.user.is_anonymous:
            return Response({"Error":"You must authenticate to update your user"},status=ST_401)
        serializer = UserSerializer(request.user, data=request.data, partial=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response({"User succesfully updated":serializer.data["username"]}, status=ST_204)

    @swagger_auto_schema(responses={204: "No Content (Successfully deleted)",401: "Unauthorized (You need the JWT token to delete your calendar information)"})
    def delete(self, request):
        #If an user is not authenticated, throw the 401 error.
        if request.user.is_anonymous:
            return Response({"Error":"You must authenticate to delete your calendar and user"},status=ST_401)

        #Now we delete the calendar and the user without using id , just using the JSON Web token
        calendar = Calendar.objects.get(user=request.user)
        calendar.delete()
        pk = request.user.id
        user=get_object_or_404(User,pk=pk)
        user.delete()
        return Response(status=ST_204)

#Class to define Events methods
class EventView(APIView):
    permission_classes= (IsAuthenticated,)
    filter_backends = (DjangoFilterBackend,filters.OrderingFilter,filters.SearchFilter,)

    queryset =Event.objects.all()
    serializer_class = EventSerializer

    search_fields = ('eventName','weather',)
    filterset_fields = ('eventName','weather','completed')
    ordering_fields = ('eventName','date')

    def filter_queryset(self, queryset):
        for backend in list(self.filter_backends):
            queryset = backend().filter_queryset(self.request, queryset, self)
        return queryset

    paramConfig = openapi.Parameter('eventName',in_=openapi.IN_QUERY,description='Event name filter',type=openapi.TYPE_STRING)
    paramConfig2 = openapi.Parameter('weather',in_=openapi.IN_QUERY,description='Weather filter',type=openapi.TYPE_STRING)
    paramConfig3 = openapi.Parameter('ordering',in_=openapi.IN_QUERY,description='You can order by eventName and date (Include "-" for reversed order)',type=openapi.TYPE_STRING)
    paramConfig4 = openapi.Parameter('search',in_=openapi.IN_QUERY,description='You can search for eventName or weather (If it contains the word)',type=openapi.TYPE_STRING)
    paramConfig5 = openapi.Parameter('limit',in_=openapi.IN_QUERY,description='Responses number',type=openapi.TYPE_NUMBER)
    paramConfig6 = openapi.Parameter('offset',in_=openapi.IN_QUERY,description='Index number',type=openapi.TYPE_NUMBER)
    paramConfig7 = openapi.Parameter('completed',in_=openapi.IN_QUERY,description='Completed events filter',type=openapi.TYPE_BOOLEAN)
    getResponse= openapi.Response('Event structure below', CreateEventSerializer(many=True))

    @swagger_auto_schema(manual_parameters=[paramConfig,paramConfig2,paramConfig5,paramConfig6,paramConfig3,paramConfig4,paramConfig7], responses={200: getResponse,404: "No events found"}) #paramConfig5,paramConfig6
    def get(self, request):
        limit= request.GET.get('limit')
        offset= request.GET.get('offset')
        calendarId = Calendar.objects.get(user=request.user)
        if (limit is None) and (offset is not None):
            events = self.filter_queryset(self.queryset).filter(calendar=calendarId)[int(offset):]
        elif (offset is None) and (limit is not None):
            events = self.filter_queryset(self.queryset).filter(calendar=calendarId)[:int(limit)]
        elif (limit is None) and (offset is None):
            events = self.filter_queryset(self.queryset).filter(calendar=calendarId)
        else:
            events = self.filter_queryset(self.queryset).filter(calendar=calendarId)[int(offset):(int(offset)+int(limit))]

        serializer_class = CreateEventSerializer(events, many=True)
        if len(events) > 0:
            return Response(serializer_class.data,status=ST_200)
        else:
            res = {"message": "No events found"}
            return Response(res, status=ST_404)

    def returnErrors(self,dic):
        err={}
        keys=dic.keys()
        for k in keys:
                err[k]= dic[k][0].capitalize()
        return err

    @swagger_auto_schema(request_body=EventSerializer,responses={201: "Event successfully created",400: "Bad request (This status code gives more information of the request error)"})
    @csrf_exempt
    def post(self, request):
        data = request.data.copy()
        calendar = Calendar.objects.get(user=request.user)
        data['calendar'] = calendar.id

        date = data['date']
        date = datetime.strptime(date, "%Y-%m-%d")
        today = datetime.combine(datetime.today(), datetime.min.time())
        days_diff = (date-today).days

        if ('city' in request.data) and ('time' in request.data):
            if  0 <= days_diff <= 4:
                data['weather'] = get_weather(data['city'], data['date'], data['time'])
            else:
                data['weather'] = "Weather is only available within the next 5 days"
            message="Event successfully created"
        else:
            data['weather']='Undefined'
            message="Event successfully created. If you want to get the weather, time and city are required"
        data['completed']=False

        serializer= CreateEventSerializer(data=data, context={'request':request})
        if serializer.is_valid():
            serializer.save()
            return Response({"message": message, "event": serializer.data},status=ST_201)
        else:
            err= self.returnErrors(serializer.errors)
            return Response({"Error":err},status=ST_400)

class EventIdView(APIView):
    permission_classes = [IsAuthenticated]

    def get_object(self,pk):
        try:
            return Event.objects.get(id=pk)
        except Event.DoesNotExist:
            return Response(ST_404)

    @swagger_auto_schema(request_body=PutEventSerializer,responses={204: "No Content (Event successfully updated)",400: "Bad request (This status code gives more information of the request error)"})
    def put(self, request , pk):
        event = self.get_object(pk)
        calendarId = Calendar.objects.get(user=request.user)
        if event.calendar != calendarId:
            return Response("You can't edit another user's event", status=ST_401)
        else:
            data = request.data.copy()
            data["calendar"]=calendarId.id
            if "eventName" not in data:
                data["eventName"]= event.eventName
            if "date" not in data:
                data["date"]= event.date
            if "time" not in data:
                data["time"]= event.time
            if "city" not in data:
                data["city"]= event.city
            if "completed" not in data:
                data["completed"]= event.completed

            date = str(data['date'])
            date = datetime.strptime(date, "%Y-%m-%d")
            today = datetime.combine(datetime.today(), datetime.min.time())
            days_diff = (date-today).days

            if (data["city"]=='' and data["time"] is None):
                data['weather']='Undefined'
                #message="Event successfully updated. If you want to get the weather, time and city are required"
            elif data["city"]=='':
                data['weather']='Undefined'
                #message="Event successfully updated. If you want to get the weather, city is required"
            elif data["time"] is None:
                data['weather']='Undefined'
                #message="Event successfully updated. If you want to get the weather, time is required"
            else:
                if  0 <= days_diff <= 4:
                    data['weather'] = get_weather(data['city'], str(data['date']), str(data['time']))
                else:
                    data['weather'] = "Weather is only available within the next 5 days"
                #message="Event successfully updated"

            serializer= CreateEventSerializer(event,data=data)
            if serializer.is_valid():
                serializer.save()
                return Response(status=ST_204)#{"message": message, "event": serializer.data} 204 dont have response body
            return Response(serializer.errors, status=ST_400)

    @swagger_auto_schema(responses={204: "No Content (Event successfully deleted",404: "Event not found in your calendar or deleted yet"})
    @csrf_exempt
    def delete(self, request , pk):
        event = self.get_object(pk)
        calendarId = Calendar.objects.get(user=request.user)
        eventList =  []
        eventList.append(event)
        if event in Event.objects.filter(calendar=calendarId):
            event.delete()
            res= {"message" : "Event successfully deleted"}
            return Response(res , status=ST_204)
        else:
            res= {"message" : "You can only delete events that exist on your calendar"}
            return Response(res , status=ST_404)

class GlobalEventsView(APIView):

    def returnErrors(self,dic):
        err={}
        keys=dic.keys()
        for k in keys:
                err[k]= dic[k][0].capitalize()
        return err

    @swagger_auto_schema(responses={200: "Search results with matching criteria",400: "Bad Request"})
    def get(self,request):
        globalEvents= get_global_events()
        serializer_class = GetGlobalEventSerializer(globalEvents, many=True)

        if len(globalEvents) > 0:
            return Response(serializer_class.data)
        else:
            res = {"Message": "There are no events created yet"}
            return Response(res, status=ST_404)

    @swagger_auto_schema(request_body=GlobalEventSerializer,responses={201: "Global event correctly created",400: "Bad Request"})
    def post(self,request):
        data = request.data.copy()
        name=data["name"]
        description=data["description"]
        organizer=data["organizer"]
        category=data["category"]
        location=data["location"]
        date=data["date"]
        (eventCode,eventResponse) = post_global_event(name,description,organizer,category,location,date)
        id=eventResponse["id"]
        data["id"] = id
        serializer= GetGlobalEventSerializer(data=data, context={'request':request})
        if serializer.is_valid():
            serializer.save()
            return Response({eventCode:"Global Event successfully created", "Event": eventResponse},status=ST_201)
        else:
            err= self.returnErrors(serializer.errors)
            return Response({"Error":err},status=ST_400)

class GlobalEventsIdView(APIView):
    @swagger_auto_schema(responses={204: "No Content (Global event deleted)",401:"You can only delete global events created from EventsAPI",404: "Global event not found"})
    def delete(self, request, pk):
        try:
            globalEventInDB = GlobalEvent.objects.get(id=pk)
            code = delete_global_events(pk)
            if code == 204:
                globalEventInDB.delete()
                res= {"message" : "Global event successfully deleted"}
                return Response(res, status=ST_204)
            else:
                res= {"message" : "Global event not found"}
                return Response(res, status=ST_404)
        except GlobalEvent.DoesNotExist:
            res= {"message" : "You can only delete global events created from EventsAPI"}
            return Response(res, status=ST_401)


"""
MeetUp 013 - Beginners Python Support Sessions 29-May-2019

Learning objectives:
    Part 1: Web application forms - see https://github.com/timcu/bpss-prime-minister.git
    Part 2: Reading Excel files and inserting into sqlite database

@author D Tim Cummings

The following challenge continues on from MeetUp 011 which read several excel worksheets of bank transactions
and combined them into a single pandas dataframe.
It uses the example excel workbook bank_accounts.xlsx

Challenge: Insert the data from the combined dataframe into an sqlite database

requirements.txt
xlrd
pandas

"""

import pandas as pd
import sqlite3

dct_accounts = pd.read_excel("bank_accounts.xlsx", sheet_name=None, skiprows=0)
for sheet_name, df in dct_accounts.items():
    if len(df) > 0:
        if 'liability' in sheet_name:
            df.Amount *= -1
            df.Balance *= -1
balance = 0
for sheet_name, df in dct_accounts.items():
    if df.shape[0] > 0:
        balance += df.at[0, 'Balance']
        balance -= df.at[0, 'Amount']
    df['Account'] = sheet_name
    df['Amount'] = df['Amount'].round(2)
    # sqlite3 can't save pandas.Timestamp so convert to datetime.date
    df['date_transaction'] = df['Date'].apply(lambda ts: ts.date())

df_combined = pd.concat(dct_accounts.values(), ignore_index=True).sort_values(by="Date")
for index, row in df_combined.iterrows():
    balance += row['Amount']
    df_combined.at[index, 'Balance'] = balance

# Store results in sqlite database

# Connection to database is to a file in the current working directory called db_transactions.sqlite
# PARSE_DECLTYPES tells python to use declared types for converting data, especially declared type 'date'
# which doesn't exist in sqlite3 but python converts dates to text when inserting data and text to dates
# when selecting data for a 'date' field
db = sqlite3.connect(
    database='db_transactions.sqlite',
    detect_types=sqlite3.PARSE_DECLTYPES
)
# By default sqlite3 returns tuples from sql 'select'.
# sqlite3.Row manufactures dict type objects so fields can be referred by name
db.row_factory = sqlite3.Row
# cursor is a database concept common to all databases. While it is possible in sqlite3 to use db.execute() rather
# than db.cursor().execute(), we will use cursors in this example to demonstrate how most databases work.
cursor = db.cursor()
# We are about to create table in the database. This will throw an error if it already exists so drop it first
cursor.execute("drop table if exists tbl_transaction")
# The following sql creates a table and defines its data structure. Unusually sqlite3 doesn't require datatypes
# but we are providing them to be consistent with other databases. Python uses the 'date' datatype to convert dates
cursor.execute("""create table tbl_transaction (
    id integer primary key,
    date_transaction date,
    num_amount numeric,
    num_balance numeric,
    vc_account varchar,
    vc_description varchar
)""")

# sqlite3 can use named bindings (eg :id, :Amount) or unnamed bindings (eg ?, ?). This example uses named bindings
# We use the same sql string for each row of data that is inserted
sql = """insert into tbl_transaction (id, date_transaction, num_amount, num_balance, vc_account, vc_description)
values (:id, :date_transaction, :Amount, :Balance, :Account, :Description)"""

# create a variable for our unique primary key
pk = 0
# loop through each row in chronological order
for index, row in df_combined.iterrows():
    # convert to dict so can add an extra key,value pair for primary key
    dct = dict(row)
    dct['id'] = pk
    # insert data in database using named bindings and a dict
    cursor.execute(sql, dct)
    # increment primary key
    pk += 1
    print(dct)

# we need to commit our transaction or else none of the data will be saved
db.commit()

# check that data is inserted by retrieving the first 20 records
sql = "select * from tbl_transaction limit 20"
records = cursor.execute(sql).fetchall()
for record in records:
    print(dict(record))


class Solution:
    """
    You are installing a billboard and want it to have the largest height. The
    billboard will have two steel supports, one on each side. Each steel support
    must be an equal height.

    You are given a collection of rods that can be welded together. For example,
    if you have rods of lengths 1, 2, and 3, you can weld them together to make
    a support of length 6.

    Return the largest possible height of your billboard installation. If you
    cannot support the billboard, return 0.

    Constraints:
    - 1 <= rods.length <= 20
    - 1 <= rods[i] <= 1000
    - sum(rods[i]) <= 5000
    """

    def tallestBillboard(self, rods: list[int]) -> int:
        return self.tallestBillboard_original(rods)

    def tallestBillboard_original(self, rods: list[int]) -> int:
        """Iterate over entire search space.
        n := len(rods), m := sum(rods)
        O(n * m) / O(m)     time / space complexity
        """
        # balances[i] = maximum height of right pole, with the right pole being i units higher than the left
        #   note: could analogously interpreted from perspective of the left pole
        balances = {0: 0}
        for r in rods:
            for balance, length in tuple(balances.items()):
                balance_add_left = balance - r
                balance_add_right = balance + r

                balances[balance_add_left] = max(
                    balances.get(balance_add_left, 0), length
                )
                balances[balance_add_right] = max(
                    balances.get(balance_add_right, 0), length + r
                )

        # maximum height of poles when they have the exact same height
        return balances[0]

    def tallestBillboard_half_half(self, rods: list[int]) -> int:
        """
        Create uneven pole pairs of each half of rods, and then put them together,
        if they have the same height difference.
        E.g. rods = [1, 3, 2, 4]:
                                                            |o|      |o|
                                           |o|              |o|      |o|
                 |x|                       |o|              |o|      |x|
                 |x|      +        |o|     |o|      =       |o|      |x|
        |x|      |x|               |o|     |o|              |x|      |x|

        Rods are marked with 'x' and 'o' to visualize how they fit together.
        """

        def helper(rods: list[int]) -> dict[int, int]:
            balances = {0: 0}
            for r in rods:
                for balance, length in tuple(balances.items()):
                    sub_ = balance - r
                    add_ = balance + r

                    balances[sub_] = max(balances.get(sub_, 0), length)
                    balances[add_] = max(balances.get(add_, 0), length + r)
            return balances

        half_len = len(rods) // 2
        rodsl = helper(rods[:half_len])
        rodsr = helper(rods[half_len:])
        return max(
            (length + rodsr[diff] - diff)
            for diff, length in rodsl.items()
            if diff in rodsr
        )


import requests

from configuration import SERVICE_URL

resp = requests.get(url=SERVICE_URL)

print(resp.json())

z = {
    'meta':
         {
             'pagination':
              {
                  'total': 2879,
                  'pages': 288,
                  'page': 1,
                  'limit': 10,
                  'links':
                    {
                        'previous': None,
                        'current': 'https://gorest.co.in/public/v1/users?page = 1',
                        'next': 'https://gorest.co.in/public/v1/users?page = 2'
                    }
               }
          },
     'data': [
         {
             'id': 4400595,
             'name': 'TrilokeshMenonJr.',
             'email': 'jr_trilokesh_menon @morissette - kunde.test',
             'gender': 'male',
             'status': 'active'
         },
         {
             'id': 4400593,
             'name': 'VedangaVarrier',
             'email': 'vedanga_varrier@donnelly.example',
             'gender': 'male',
             'status': 'active'
         },
         {
             'id': 4400592,
             'name': 'Gandharv Mukhopadhyay',
             'email': 'gandharv_mukhopadhyay@weber-vonrueden.test',
             'gender': 'female',
             'status': 'inactive'
         },
         {
             'id': 4400591,
             'name': 'Apsara Iyer',
             'email': 'apsara_iyer@bauch-botsford.example',
             'gender': 'female',
             'status': 'active'
         },
         {
             'id': 4400590,
             'name': 'Mr.Gopi Khatri',
             'email': 'khatri_mr_gopi@lubowitz.example',
             'gender': 'female',
             'status': 'inactive'
         },
         {
             'id': 4400589,
             'name': 'Deepankar Achari I',
             'email': 'deepankar_achari_i@krajcik.test',
             'gender': 'male',
             'status': 'inactive'
        },
        {
            'id': 4400588,
            'name': 'HimaniDwivedi',
            'email': 'dwivedihimani@schmitt.example',
            'gender': 'female',
            'status': 'active'
        },
        {
            'id': 4400587,
            'name': 'RohanaMishra',
            'email': 'mishra_rohana@mckenzie.example',
            'gender': 'female',
            'status': 'inactive'
        },
        {
            'id': 4400586,
            'name': 'Rep.Hiranya Adiga',
            'email': 'adiga_rep_hiranya @ nicolas.example',
            'gender': 'male',
            'status': 'inactive'
        },
        {
            'id': 4400585,
            'name': 'Sen. Devagya Embranthiri',
            'email': 'devagya_sen_embranthiri@cartwright.example',
            'gender': 'male',
            'status': 'active'
        }]
    }


'''
3. На языке Python реализовать функцию, которая быстрее всего (по процессорным тикам) отсортирует данный ей массив чисел. Массив может быть любого размера со случайным порядком чисел (в том числе и отсортированным). Объяснить почему вы считаете, что функция соответствует заданным критериям.
'''

def my_sort(numbers):
    while True:
        flag = False
        for i in range(0, len(numbers)-1):
            if numbers[i] > numbers[i+1]:
                numbers[i], numbers[i+1] = numbers[i+1], numbers[i]
                flag = True
        if flag == False:
            break

'''
Заранее извиняюсь за это решение. Понимаю, что алгоритм очень долгий и примитивный.
Зато написал я его сам, и он работает.
Мог бы скопировать из интернета достойное решение, но это не соответствовало бы моим реальным навыкам.
Но если мне приходится копировать чужой код, и разбираться как он работает, я это делаю.
'''

if __name__ == '__main__':
    from random import randint

    numbers = [randint(1, 100) for _ in range(100)]
    print(numbers)
    print('='*50)
    my_sort(numbers)
    print('='*50)
    print(numbers)


from collections import Counter
class Solution:
    def dfs(self, nums, sums, index, target):
        if index == len(nums):
            if sums[0] == target and sums[1] == target and sums[2] == target:
                return True
            else:
                return False
        for i in range(4):
            if sums[i] + nums[index] > target: continue
            sums[i] += nums[index]
            if (self.dfs(nums, sums, index + 1, target)): return True
            sums[i] -= nums[index]
        return False

    def makesquare(self, nums) -> bool:
        s = []
        if sum(nums) % 4: return False
        t = int(sum(nums) / 4)
        nums.sort(reverse=True)
        if self.dfs(nums, [0] * 4, 0, t): return True
        return False

s = Solution()
print(s.makesquare([3,3,3,3,4]))


#!/usr/bin/python

from openpyxl.reader.excel import load_workbook

from Readers import *
from Behavior import *
from Student import *
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab

behav_read = BehaviorReader('data/DPCHS_BehaviorData.xlsx')
behaviors = []
while behav_read.next_sheet():
    behaviors += behav_read.get_data()

labels = ('3 Demerits','Auto Dt','Uniform','Send Out')
values = [0,0,0,0]

dates = {}

i = 0
for b in behaviors:
    if b.date not in dates.keys():
        dates[b.date] = {}

    if b.student not in dates[b.date].keys():
        dates[b.date][b.student] = [0,0,0,0]# [ nDemerits, nAutoDetentions, nUniforms, nSendouts]

    i += 1
    #if i>100: break
    if b.behaviorType == 'Demerit':
        dates[b.date][b.student][0] += 1
    elif b.behaviorType == 'AutoDetention':
        dates[b.date][b.student][1] += 1
        #values[1] += 1
    elif b.behaviorType == 'Uniform':
        dates[b.date][b.student][2] += 1
        #values[2] += 1
    elif b.behaviorType == 'SendOut':
        dates[b.date][b.student][3] += 1
        #values[3] += 1

n6demerits = 0
for d in dates.keys():

    for s in dates[d].keys():
        if dates[d][s][0] > 5:
            n6demerits += 1
        elif dates[d][s][0] > 2:
            values[0] += 1
        elif dates[d][s][1] > 0:
            values[1] += 1
        elif dates[d][s][2] > 0:
            values[2] += 1
        elif dates[d][s][3] > 0:
            values[3] += 1

width = 0.35
ind = np.arange(len(values))

fig = plt.figure(facecolor='w')
ax = fig.add_subplot(111)

temp = values[2:4]
values[2:4] = [0,0]
bars = ax.bar(ind+width, tuple(values), width, color='r')
barstop = ax.bar(ind+width, tuple([n6demerits,0]+temp), width, bottom=tuple(values),color='#1943BF')

ax.set_ylabel('Detentions')
ax.set_title('Detentions by Type')
ax.set_xticks(ind+width)
ax.set_xticklabels( labels )

def autolabel(rects):
    # attach some text labels
    for rect in rects:
        height = rect.get_height()
        ax.text(rect.get_x()+rect.get_width()/2., 1.05*height, '%d'%int(height),
                ha='center', va='bottom')

#autolabel(bars)

plt.show()

blah = raw_input("waiting...")


# Question 1.
def calculate(min, max, step):
    sum = 0
    for i in range(min,max+1,step):
        sum += i
    print(sum)

calculate(1, 3, 1) # 你的程式要能夠計算 1+2+3，最後印出 6
calculate(4, 8, 2) # 你的程式要能夠計算 4+6+8，最後印出 18
calculate(-1, 2, 2) # 你的程式要能夠計算 -1+1，最後印出 0

#=============================================================
# Question 2.
def avg(data):
    length = len(data["employees"])
    num = 0
    total = 0

    for i in range(0,length):
        if(data["employees"][i]["manager"] == False):
            total += data["employees"][i]["salary"]
            num += 1
    print(total/num)

avg({
    "employees":[
        {
            "name":"John",
            "salary":30000,
            "manager":False
        },
        {
            "name":"Bob",
            "salary":60000,
            "manager":True
        },
        {
            "name":"Jenny",
            "salary":50000,
            "manager":False
        },
        {
            "name":"Tony",
            "salary":40000,
            "manager":False
        }
    ]
}) # 呼叫 avg 函式

#=============================================================
# Question 3.
def func(a):
    def mult(b,c):
        print(a + (b*c))
    return mult

func(2)(3, 4) # 你補完的函式能印出 2+(3*4) 的結果 14
func(5)(1, -5) # 你補完的函式能印出 5+(1*-5) 的結果 0
func(-3)(2, 9) # 你補完的函式能印出 -3+(2*9) 的結果 15
# 一般形式為 func(a)(b, c) 要印出 a+(b*c) 的結果

#=============================================================
# Question 4.
def maxProduct(nums):
    inf = float('Inf')
    maxlist = [-inf,-inf]       # maxlist = [-inf,max(nums)]
    minlist = [inf,inf]         # minlist = [min(nums),inf]

    for i in range(0,len(nums)):
        #找最大兩個值
        if(maxlist[1] <= nums[i]):        # 比最大的大
            maxlist.pop(0)
            maxlist.append(nums[i])
        elif(maxlist[0] < nums[i]):       # 比第二大的大,但比最大的小
            maxlist.pop(0)
            maxlist.insert(0,nums[i])

        #找最小兩個值
        if(nums[i] <= minlist[0]):        # 比最小的小
            minlist.pop()
            minlist.insert(0,nums[i])
        elif(nums[i] < minlist[1]):       # 比第二小的小,但比最小的大
            minlist.pop()
            minlist.append(nums[i])

    prod1 = maxlist[0] * maxlist[1]
    prod2 = minlist[0] * minlist[1]
    if (prod1 > prod2):
        print(prod1)
    else:
        print(prod2)

maxProduct([5, 20, 2, 6]) # 得到 120
maxProduct([10, -20, 0, 3]) # 得到 30
maxProduct([10, -20, 0, -3]) # 得到 60
maxProduct([-1, 2]) # 得到 -2
maxProduct([-1, 0, 2]) # 得到 0
maxProduct([5,-1, -2, 0]) # 得到 2
maxProduct([-5, -2]) # 得到 10

#=============================================================
# Question 5.
def twoSum(nums, target):
    solve = []
    length = len(nums)

    for i in range(0,length):
        diff = target - nums[i]
        if(diff in nums):                       # 搜尋 list會增加時間複雜度 → list 一個坑一個蘿蔔
            solve.extend([i,nums.index(diff)])
            return solve

result=twoSum([2, 11, 7, 15], 9)
print(result) # show [0, 2] because nums[0]+nums[2] is 9

#--------------------------------------------------------------
# Questuin 5.改
def twoSum(nums,target):
    solve = {nums[0]:0}
    length = len(nums)

    for i in range(1,length):
        diff = target - nums[i]
        if(diff in solve):              # 用dict搜尋可降低時間複雜度
            return [solve[diff],i]
        else:
            solve[nums[i]] = i

result=twoSum([2, 11, 7, 15], 9)
print(result) # show [0, 2] because nums[0]+nums[2] is 9

#=============================================================
# Question 6.
def maxZeros(nums):
    cnt = 0
    length = len(nums)
    cntList = []

    for i in range(0,length):
        if (nums[i] == 0):
            cnt += 1
            cntList.append(cnt)
        else:
            cnt = 0
            cntList.append(cnt)

    print(max(cntList))         # 用 max會在搜尋一次 cntList此列表中的元素，增加時間複雜度
#     print(cntList)

maxZeros([0, 1, 0, 0]) # 得到 2
maxZeros([1, 0, 0, 0, 0, 1, 0, 1, 0, 0]) # 得到 4
maxZeros([1, 1, 1, 1, 1]) # 得到 0
maxZeros([0, 0, 0, 1, 1]) # 得到 3

#--------------------------------------------------------------
# Question 6. 改
def maxZeros(nums):
    cnt = 0
    cntMax = 0                #設一個跟cnt比大小的值，來儲存cnt最大值的時候
    length = len(nums)

    for i in range(0,length):
        if(nums[i] == 0):
            cnt += 1
            if(cnt > cntMax):
                cntMax = cnt
        else:
            cnt = 0

    print(cntMax)

maxZeros([0, 1, 0, 0]) # 得到 2
maxZeros([1, 0, 0, 0, 0, 1, 0, 1, 0, 0]) # 得到 4
maxZeros([1, 1, 1, 1, 1]) # 得到 0
maxZeros([0, 0, 0, 1, 1]) # 得到 3


#%%
import os
from PIL import Image
#%%
def lst_resize(lst, directory, w, h):
    for i in lst:
        pth=os.path.join(directory,i)
        img=Image.open(pth)
        if img.size!=(w,h):
            img=img.resize((w,h))
            img.save(pth)
# %%
fi='/home/h/Desktop/data/2/t_label'
lst_i=os.listdir(fi)
lst_i.sort()
print(lst_i)
#%%
lst_resize(lst_i, fi, 512, 512)
#%%
# import os
# from importlib.resources import path
# import shutil
# import random
# from glob import glob
# #%%
# dir_input=glob('/home/h/Desktop/data*/m_label*')
# dir_label=glob('/home/h/Desktop/data*/t_label*')

# lst_input=sorted(os.listdir(dir_input))
# lst_label=sorted(os.listdir(dir_label))

# print(dir_input)
# print(dir_label)
# img_cnts = len(os.listdir(dir_label))


import math
import random
import pygame
import config
import requests
import json
from center import PokeCenter
from mart import PokeMart
from trainer import Trainer
from mon import Pokemon
from player import Player, PlayerOri
from game_state import GameState

class Game(object):
    def __init__(self, screen):
        self.screen = screen
        self.objects = []
        self.game_state = GameState.NONE
        self.map = []
        self.poke_centers = []
        self.poke_marts = []
        self.poke_trainers = []
        self.camera = [0, 0]

    def set_up(self):
        self.load_map("01")
        self.player = Player(24, 19)
        self.objects.append(self.player)
        self.pokemons = self.request_pokemons()
        self.load_assets()
        print("Gotta catch'em all !!")
        self.game_state = GameState.RUNNING

    def update(self, human_player = False):
        self.screen.fill(config.BLACK)

        if(human_player == True):
            self.handle_events()

        self.render_map(self.screen)

        for object in self.objects:
            object.render(self.screen, self.camera)

    def handle_events(self):
        for event in pygame.event.get():
            # HANDLE QUIT EVENT
            if event.type == pygame.QUIT:
                self.game_state = GameState.ENDED
            # HANDLE KEY EVENT
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    self.game_state = GameState.ENDED
                elif event.key == pygame.K_w:  # WALK FORWARD
                    self.player.walk_forward(self.map, self.index_map)
                elif event.key == pygame.K_d:  # TURN RIGHT
                    self.player.change_orientation(PlayerOri.TURN_RIGHT)
                elif event.key == pygame.K_a:  # TURN LEFT
                    self.player.change_orientation(PlayerOri.TURN_LEFT)
                elif event.key == pygame.K_z:  # INTERACT
                    self.player.interact(self.index_map, self.objects)
                    # if(len(self.player.captured_pokemons) == 150):
                    #     self.game_state = GameState.WIN # TODO: Implement winning screen

    def load_map(self, file_name):
        with open('maps/' + file_name + ".txt") as map_file:
            for line in map_file:
                tiles = []
                for i in range(0, len(line) - 1, 2):
                    tiles.append(line[i])
                self.map.append(tiles)

    def load_assets(self):
        print("Loading Assets...")
        centers = 20
        marts = 15
        trainers = 50
        mons = 150

        rows, cols = 42, 42
        self.index_map = []
        for i in range(0, rows):
            self.index_map.append([])
            for j in range(0, cols):
                self.index_map[i].append([])

#        self.index_map[self.player.position[1]][self.player.position[0]].append(self.player)

        poke_list = list(self.pokemons.values()).copy()
        random.shuffle(poke_list)

        # TODO: Improve spawning rules (e.g: No water pokemons, trainers, centers or marts on lava, no fire pokemons on water)
        while(centers + marts + trainers + mons > 0):
            i = random.randint(0, 41)
            j = random.randint(0, 41)
            if(self.index_map[i][j] == []):
                dice = random.randint(0, 3)

                if(dice == 0 and centers > 0):
                    self.poke_centers.append(PokeCenter(j, i))
                    self.objects.append(self.poke_centers[-1])
                    centers -= 1
                    self.index_map[i][j].append(self.poke_centers[-1])
                    if(i+1 <= 41):
                        self.index_map[i+1][j].append('smell')
                    if(i-1 >= 0):
                        self.index_map[i-1][j].append('smell')
                    if(j+1 <= 41):
                        self.index_map[i][j+1].append('smell')
                    if(j-1 >= 0):
                        self.index_map[i][j-1].append('smell')
                elif(dice == 1 and marts > 0):
                    self.poke_marts.append(PokeMart(j, i))
                    self.objects.append(self.poke_marts[-1])
                    marts -= 1
                    self.index_map[i][j].append(self.poke_marts[-1])
                    if(i+1 <= 41):
                        self.index_map[i+1][j].append('vendingShout')
                    if(i-1 >= 0):
                        self.index_map[i-1][j].append('vendingShout')
                    if(j+1 <= 41):
                        self.index_map[i][j+1].append('vendingShout')
                    if(j-1 >= 0):
                        self.index_map[i][j-1].append('vendingShout')
                elif(dice == 2 and trainers > 0):
                    self.poke_trainers.append(Trainer(j, i))
                    self.objects.append(self.poke_trainers[-1])
                    trainers -= 1
                    self.index_map[i][j].append(self.poke_trainers[-1])
                    if(i+1 <= 41):
                        self.index_map[i+1][j].append('battleShout')
                    if(i-1 >= 0):
                        self.index_map[i-1][j].append('battleShout')
                    if(j+1 <= 41):
                        self.index_map[i][j+1].append('battleShout')
                    if(j-1 >= 0):
                        self.index_map[i][j-1].append('battleShout')
                elif(dice == 3 and mons > 0):
                    poke_name = poke_list[mons-1].name
                    self.pokemons[poke_name].set_pos(j, i)
                    self.objects.append(self.pokemons[poke_name])
                    mons -= 1
                    self.index_map[i][j].append(self.pokemons[poke_name])
                    if(i+1 <= 41):
                        self.index_map[i+1][j].append('dexWarning')
                    if(i-1 >= 0):
                        self.index_map[i-1][j].append('dexWarning')
                    if(j+1 <= 41):
                        self.index_map[i][j+1].append('dexWarning')
                    if(j-1 >= 0):
                        self.index_map[i][j-1].append('dexWarning')

        if(centers == marts == trainers == mons == 0):
            print("NO MISSING ASSETS!!")
        print("Assets Loaded!")

    def render_map(self, screen):
        self.determine_camera()

        y_pos = 0
        for line in self.map:
            x_pos = 0
            for tile in line:
                image = map_tile_image[tile]
                rect = pygame.Rect(x_pos * config.SCALE - (self.camera[0] * config.SCALE), y_pos * config.SCALE - (
                    self.camera[1] * config.SCALE), config.SCALE, config.SCALE)
                screen.blit(image, rect)
                x_pos = x_pos + 1

            y_pos = y_pos + 1

    def request_pokemons(self):
        print("Loading Pokemons...")
        poke_dict = {}
        #self.poke_data = {}
        for i in range(1, 151):

            ''' # REQUESTS POKEMON DETAILS FROM API AND SAVES BOTH SIMPLIFIED JSON AND SPRITES
                # UNCOMMENT THIS IF RUNNING FOR THE FIRTS TIME
            pj = self.get_api_json('https://pokeapi.co/api/v2/pokemon/' + str(i))
            self.save_poke_json(pj, self.poke_data, i)
            self.download_pokemon_sprite(pj, name)
            '''

            # READ FROM JSON FOLDER
            name, poke_types = self.read_poke_json(
                'jsons/names_and_types.json', i)
            sprite_file = 'sprites/pokemon/' + name + ".png"

            poke_dict[name] = Pokemon(name, poke_types, sprite_file)
            #print("Pokemon: {} created!".format(name))

        print("Pokemons Loaded!")

        return poke_dict

    def get_api_json(self, url):
        poke_details = url
        poke_res = requests.get(poke_details)
        pj = poke_res.json()
        return pj

    def save_poke_json(self, poke_json, poke_data, index):
        poke_data[index] = {'name': poke_json['name']}
        poke_data[index].update({'types': [x['type']['name']
                                for x in poke_json['types']]})
        # TODO: This could be optimized. As of now it re-writes the whole file on every loop.
        with open('jsons/names_and_types.json', 'w') as f:
            json.dump(poke_data, f)
        #print("Json Saved: {}".format(poke_data))

    def read_poke_json(self, json_file, index):
        with open(json_file, 'r') as f:
            poke_data = json.load(f)
            name = poke_data[str(index)]['name']
            types = poke_data[str(index)]['types'].copy()
            return name, types

    def download_pokemon_sprite(self, json, pokemon):
        sprite_url = json['sprites']['front_default']
        img_data = requests.get(sprite_url).content
        with open('sprites/pokemon/' + pokemon + ".png", 'wb') as handler:
            handler.write(img_data)

    def determine_camera(self):
        # DETERMINE Y POSITION
        max_y_position = len(self.map) - config.SCREEN_HEIGHT / config.SCALE
        y_position = self.player.position[1] - \
            math.ceil(round(config.SCREEN_HEIGHT / config.SCALE / 2))

        if(y_position <= max_y_position and y_position >= 0):
            self.camera[1] = y_position
        elif(y_position < 0):
            self.camera[1] = 0
        else:
            self.camera[1] = max_y_position

        # DETERMINE X POSITION
        max_x_position = len(self.map[0]) - config.SCREEN_WIDTH / config.SCALE
        x_position = self.player.position[0] - \
            math.ceil(round(config.SCREEN_WIDTH / config.SCALE / 2))

        if(x_position <= max_x_position and x_position >= 0):
            self.camera[0] = x_position
        elif(x_position < 0):
            self.camera[0] = 0
        else:
            self.camera[0] = max_x_position

map_tile_image = {
    "G": pygame.transform.scale(pygame.image.load("sprites/grass.png"), (config.SCALE, config.SCALE)),
    "W": pygame.transform.scale(pygame.image.load("sprites/water.png"), (config.SCALE, config.SCALE)),
    "M": pygame.transform.scale(pygame.image.load("sprites/mountain.png"), (config.SCALE, config.SCALE)),
    "L": pygame.transform.scale(pygame.image.load("sprites/lava.png"), (config.SCALE, config.SCALE)),
    "C": pygame.transform.scale(pygame.image.load("sprites/cave.png"), (config.SCALE, config.SCALE))
}