from flask import Flask, request, Response, render_template
from flask_mail import Mail, Message
from flask_cors import CORS
from threading import Thread
import time
import random
import re
import os
import json

app = Flask(__name__)

app.config['MAIL_SERVER']='smtp.gmail.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USERNAME'] = os.environ.get('MAIL_USERNAME')
app.config['MAIL_PASSWORD'] = os.environ.get('MAIL_PASSWORD')
app.config['MAIL_USE_TLS'] = False
app.config['MAIL_USE_SSL'] = True

mail = Mail(app)

env = os.environ.get('env')

emailArray = []

CORS(app)
cors = CORS(app, resource={
    r"/*": {
        "origins": "*"
    }
})

@app.errorhandler(500)
def internal_server_error(error):
    print(error)
    return Response(status=500, mimetype='application/json')

@app.route("/")
def index():
    return render_template('base.html')

@app.route("/post-email",  methods=["POST"])
def post_email():
    emailToSend = request.get_json(force=True).get('email')

    #check that email is valid
    isValid = validate_email(emailToSend)
    if not isValid:
        response_obj = {
            "message": "Not a valid email",
        }
        return Response(json.dumps(response_obj), status=400, mimetype='application/json')

    #check that email is not in list
    if emailToSend in emailArray:
        response_obj = {
            "message": "Email already in use",
        }
        return Response(json.dumps(response_obj), status=400, mimetype='application/json')

    emailArray.append(emailToSend)

    #send emails to each element in emailArray
    for idx, email in enumerate(emailArray):

        t = Thread(target=send_email, args=(email,))
        t.start()

        del emailArray[idx]

    response_obj = {
        "email": emailToSend,
    }

    return Response(json.dumps(response_obj), status=200, mimetype='application/json')

def send_email(email):
    sentEmails = 0
    sender = os.environ.get('MAIL_USERNAME')

    messageDict = {"1":"Apples are Red", "2": "Bananas are yellow", "3":"Carrots are orange", "4": "Dogs are canines", "5": "Elephants travel in packs", "6": "Flask is a python framework", "7": "Grapes grow on vines", "8": "Have a good day!", "9": "I have chosen each first character in this list to be different.", "10" : "Just in time"}

    #while sentEmails is less than 10, send new email with unique message
    with app.app_context():
        while(sentEmails < 10):
            message = random.choice(list(messageDict.items()))

            msg = Message(f'Email from {sender}', sender = sender, recipients = [email])
            msg.body = message[1]
            mail.send(msg)

            # remove message from dictionary
            del messageDict[message[0]]

            sentEmails = sentEmails + 1
            time.sleep(60)
    return

# validating email string with regex
def validate_email(email):
    pat = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
    return re.match(pat,email)

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


"""
exercises.py

Python exercises and examples.
author: luisalbertogh@hotmail.com
"""

# Math module
import math;

class Exercises:
	# Caculate fibonacci serie.
	# - iter - Number of iterations to calculate
	def fib(self, iter):
		"""
		Calculate fibonacci serie. 0, 1, 1, 2, 3, 5, 8, 13, etc
		"""
		total = 0;
		temp = 0;
		for index in range(0, iter + 1):
			if(index == 1 or index == 2):
				total = 1;
			else:
				total += temp;
			temp = total;

		return total;

	def isPrime(self, num):
		sqrN = int(math.sqrt(num));
		for index in range(sqrN, 0, -1):
			if((num % index) == 0 and index != num and index != 1):
				return False;

		return True;

# Main method
def main():
	exer = Exercises();
	print("Fibonacci for {0} is {1}".format(120, exer.fib(120)));
	print("Number {0} is prime? {1}".format(13, exer.isPrime(13)));

# Invoke main method
if __name__ == "__main__":
	main();


import os
import re
import time
import random
import datetime
import configparser
from sys import platform
import yaml
from ruamel.yaml import RoundTripDumper

class XiaoMaUtils(object):
    # 定义源文件夹的根路径
    # ROOT_PATH = 'D:\\codes\\python_2020\\xiaoma_ui_automation_base_357_music\\'

    @staticmethod
    def read_config(config_file):
        """读取配置文件, 返回一个元组类型"""
        config = configparser.ConfigParser()
        config.read('config/' + config_file, encoding="utf-8-sig")
        project_name = config.get('config', 'project_name')
        app_name = config.get('config', 'app_name')
        app_version = config.get('config', 'app_version')

        return project_name, app_name, app_version

    @staticmethod
    def yml_path(yml_name):
        '''
        返回配置文件的路径
        :param yml_name: 文件名
        :return:
        '''
        # os.path.realpath(__file__)   E:\pycharm\project\UiTestCode\DataProcessing\YamlProcessing.py
        # os.path.dirname(os.path.realpath(__file__))   E:\pycharm\project\UiTestCode\DataProcessing

        os_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..')
        if 'darwin' in platform.lower():
            path = os_path + "/Config/" + yml_name
        else:
            path = os_path + "\\Config\\" + yml_name
        return path

    @staticmethod
    def write_yaml_file(yaml_name, yaml_data):
        '''
        向yaml文件中写入数据
        :param yaml_name:文件名
        :param yaml_data:写入的数据，可以是任何的Python对象
        :return:
        '''
        yaml_path = XiaoMaUtils.yml_path(yaml_name)
        with open(yaml_path, "w", encoding="utf-8") as f:
            yaml.dump(yaml_data, f, encoding="utf-8", Dumper=yaml.RoundTripDumper)

    @staticmethod
    def update_yaml_file(yaml_name, **data):
        """
        更新yaml中字典对象的值
        :param yaml_name:
        :param data:
        :return:
        """
        data1 = XiaoMaUtils.read_yaml_file(yaml_name)
        if data1 is None:
            data1 = {}
        for key in data:
            data1[key] = data[key]
        XiaoMaUtils.write_yaml_file(yaml_name, data1)

    @staticmethod
    def read_yaml_file(yaml_name):
        """
        读取yaml文件的内容并返回
        :param yaml_name: 文件名
        :return:
        """
        yaml_path = XiaoMaUtils.yml_path(yaml_name)
        if os.path.exists(yaml_path):
            reader_yaml = open(yaml_path, 'rb')
            data_yaml = yaml.load(reader_yaml.read(), Loader=yaml.Loader)
            reader_yaml.close()
            return data_yaml
        else:
            return None

    @staticmethod
    def get_current_time():
        """获取系统当前时间, 返回字符串数据类型"""
        current_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())

        return current_time

    @staticmethod
    def convert_str_to_time(time_str):
        """ 把 00:00:45 这种形式的字符串转化为时间 """
        time_list = time_str.split(":")

        # 判断是否有小时位, 若有则封装为变量, 没有则封装为0
        if len(time_list) > 2:
            hour, minute, second = time_list
            res_time = datetime.time(int(hour), int(minute), int(second))
        else:
            minute, second = time_list
            res_time = datetime.time(0, int(minute), int(second))

        return res_time

    """
    去掉该方法, 使用字符串解析替换
    """

    # @staticmethod
    # def add_index_to_loc(loc, index=1, direction="left"):
    #     """
    #     在元素的表达形式中加入索引值
    #
    #     :param loc: 元素的表达形式, 以元祖形式传递, eg. (By.ID,ID属性值)
    #     :param index: 索引值, 默认取1
    #     :param direction: 查找"["的方向, 默认取left. left: 从左查找, 从右查找
    #     :return: 加入索引的元素表达形式
    #     """
    #     temp_str = loc[1]
    #
    #     # 查找元素表达式中要插入索引的位置
    #     flag_index = 0
    #     if direction == 'left':
    #         flag_index = temp_str.find('[')
    #     if direction == 'right':
    #         flag_index = temp_str.rfind('[')
    #     # 把索引插入到元素表达式中, 返回新的元素表达式
    #     left_str = temp_str[:flag_index + 1]
    #     right_str = temp_str[flag_index + 1:]
    #     full_str = left_str + str(index) + right_str
    #     new_loc = (loc[0], full_str)
    #     return new_loc

    @staticmethod
    def close_app(package_name):
        """
        关闭小马应用

        :param package_name: 应用名包名, 不带前缀'com.xiaoma.'
        :return:
        """
        command = 'adb shell am force-stop com.xiaoma.' + package_name
        os.system(command)

    @staticmethod
    def clear_data(package_name):
        """
        清理应用数据

        :param package_name: 应用名包名, 不带前缀'com.xiaoma.'
        :return:
        """
        command = 'adb shell pm clear com.xiaoma.' + package_name
        os.system(command)

    @staticmethod
    def get_random_int(start, end):
        """
        返回任意范围的整数, 包括左右边界
        :param start: 区间左边数
        :param end: 区间右边数
        :return: int
        """
        return random.randint(start, end)

    @staticmethod
    def convert_bounds_to_location(location):
        """
        把元素边界转哈成坐标, eg. '[x1,y1][x2,y1]' -> [x1,y1,x2,y2]

        :param location: 元素的边界, 字符串形式
        :return: 元素坐标点的列表
        """
        pattern = re.compile(r'\d+')  # 查找数字
        return pattern.findall(location)

    @staticmethod
    def get_screencap(png_name="screen.png"):
        os.system('adb shell screencap -p /sdcard/' + png_name)
        command = 'adb pull /sdcard/' + png_name + " " + os.getcwd() + '\\Image\\' + png_name
        os.system(command)

if __name__ == '__main__':
    # pass
    XiaoMaUtils.get_screencap(png_name="testcase12_collection_toast.png")


# Creating a Reusable Function
message = input("> ")

def emoji_converter(message):
    output = ""
    words = message.split(' ')
    emojis = {
        ":)" : "ðŸ˜€",
        ":(" : "ðŸ˜ž"
    }
    for word in words:
        output += emojis.get(word, word) + " "
    return output

result = emoji_converter(message)
print(result)
# I hath just learned it is better to have two lines seperating code from a function

01 - First Attempt at Python/CreatingAReusableFunction.py


# %%
import requests, re
import pandas as pd
import numpy as np

class WordleSolver:

    def __init__(self, word_length:int = 5) -> None:

        #Retrieve the list of k-letter words through the method get_words()
        self.word_length                    = word_length
        self.words                          = self.get_words()
        self.last_guess                     = None
        self.last_guess_index               = None
        self.set_statistics()

    def get_words(self) -> pd.DataFrame:
        """Retrieves a list of words and creates a dataframe with them.

        Returns:
            pd.DataFrame: A dataframe with the words
        """
        #Retrieve the list of words from the website below
        url         = 'https://raw.githubusercontent.com/dwyl/english-words/master/words_alpha.txt'
        response    = requests.get(url)

        #Split the words into a list, and clean the list by removing non-alphabetical characters
        words       = response.text.split('\n')
        words       = [re.sub(r"[^a-zA-Z]", "", word) for word in words]

        #Filter the list to only include words with 5 letters, and split each word into a list of letters
        words       = [list(word) for word in words if len(word) == self.word_length]

        #Turn the word list into a dataframe where each letter is a column
        word_df    = pd.DataFrame(words)
        return word_df

    def set_statistics(self) -> None:
        """Calculates and sets the statistics for the puzzle based on the current state of the puzzle
        """
        #Generate the statistics for the new list of words
        letter_counts, letter_by_columns    = WordleSolver.generate_statistics(self.words)
        self.letter_counts                  = letter_counts
        self.letter_by_columns              = letter_by_columns

    @staticmethod
    def generate_statistics(word_df:pd.DataFrame) -> tuple[dict[str, int], pd.DataFrame]:
        """Generates the statistics for the given list of words

        Args:
            word_df (pd.DataFrame): The list of words

        Returns:
            tuple[dict[str, int], pd.DataFrame]: A tuple containing the letter counts and the letter by columns dataframe
        """

        #Generate a dictionary of the number of times a letter appears in a word
        letter_counts = {
            char: np.any((word_df.values == char), axis=1).sum()
            for char
            in 'abcdefghijklmnopqrstuvwxyz'
        }

        #Generate a dataframe containing the letter counts on a per-column basis
        word_values = {}
        for col in word_df.columns:
            word_values[col] = word_df[col].value_counts()

        word_values_df = pd.DataFrame(word_values)
        return letter_counts, word_values_df

    def find_best_word(self) -> pd.Series:
        """Finds the word with the highest likelihood of some letter being correct. Ranks every letter in every position, and returns the word with the lowest rank.

        Returns:
            pd.Series: The word with the highest likelihood of some letter being correct
        """

        #Find the word that has the lowest "rank" across all columns
        word_rank_df = self.letter_by_columns.rank(ascending=False)

        #Replace each letter with its rank in the dataframe
        words = self.words.copy()
        for col in words.columns:
            words.loc[:, col] = words.loc[:, col].replace(word_rank_df[col])

        #Find the word that has the lowest rank across all columns
        words["sum"]    = words.sum(axis=1)
        best_word_index = words.sort_values(by="sum").iloc[0].name
        return self.words.loc[best_word_index]

    def not_in_word_list(self, word:str = None) -> str:
        """Removes the last guess from the list of words and returns the next best guess

        Args:
            word (str, optional): The word to remove from the list of words. If None, the last guess is removed. Defaults to None.

        Returns:
            str: The next best guess
        """
        word        = word if word is not None else ''.join(self.last_guess)
        word_list   = self.words.apply(lambda x: ''.join(x), axis=1)
        words       = self.words.loc[word_list != word]
        self.words  = words
        self.set_statistics()
        return self.guess_word()

    def guess_word(self) -> str:
        """Generates the best guess given the puzzle's current state by finding the word with the highest likelihood of some letter being correct

        Returns:
            str: The best guess
        """
        #Find the best word and return it
        self.last_guess         = self.find_best_word()
        self.last_guess_index   = self.last_guess.name
        return ''.join(self.last_guess)

    def solve(self, results:list[int] = None, input_word:str = None) -> str:
        """Solver for the Wordle puzzle. Each instance of the solve method will return a word that fits the results

        Args:
            results (list[int], optional): A list containing the different positional results of the puzzle. 0 is a miss, 1 is correct letter in wrong position, 2 is correct letter in correct position. Defaults to None.
            input_word (str, optional): If provided, the solver will use this word instead of the previous best guess. Defaults to None.

        Raises:
            ValueError: If the results list is not provided, or if the results list is not the correct length.

        Returns:
            str: The next best guess for the puzzle.
        """
        #Filter the list of words based on the results.
        #0 means that the letter is not in the word, 1 means that the letter is in the word but not in the correct position
        #2 means that the letter is in the word and in the correct position
        if input_word is not None:
            guess = input_word
        else:
            guess = self.last_guess
        if guess is None:
            return self.guess_word()
        elif (results is None) or len(results) != self.word_length:
            raise ValueError("Results must be provided on subsequent guesses")

        guess = list(guess)

        words = self.words.copy()

        #Go through the results and generate a minimum number of matches for each letter
        letter_counts = {}
        for i, letter in enumerate(guess):
            #Count the number of positive results for each letter
            res = 0 if results[i] == 0 else 1
            if letter not in letter_counts:
                letter_counts[letter] = res
            else:
                letter_counts[letter] += res

        #Remove all words that have more than the number of correct letters
        for letter, value in letter_counts.items():
            if value == 0:
                #Remove all words that contain a letter that did not match at all
                mask = (words == letter).sum(axis=1) == 0
            elif value < guess.count(letter):
                #This is a special case where the amount of matches is less than the amount of letters in the guess
                #This mask removes all words that do not contain exactly the amount of matches
                mask = (words == letter).sum(axis=1) == value
            else:
                #Otherwise, remove all words that contain less than the amount of matches
                mask = (words == letter).sum(axis=1) >= value
            words = words[mask]

        #Go through the results that have correct position and filter accordingly
        for i, result in enumerate(results):
            if result == 1:
                mask   = (words[i] != guess[i])
                words   = words[mask]
            elif result == 2:
                mask    = (words[i] == guess[i])
                words   = words[mask]

        #Set the new list of words
        self.words = words
        self.set_statistics()
        return self.guess_word()

# class WordleSolution:
#     def __init__(self, solution_word:str):
#         self.solution_word = solution_word
#         self.letter_counts = {letter: list(solution_word).count(letter) for letter in 'abcdefghijklmnopqrstuvwxyz'}

#     def verify_guess(self, guess:str) -> list[int]:
#         return_list = [0] * len(guess)
#         letter_counts = {**self.letter_counts}
#         for i, letter in enumerate(guess):
#             if letter == self.solution_word[i]:
#                 return_list[i] = 2
#                 letter_counts[letter] -= 1

#         for i, letter in enumerate(guess):
#             #If the letter is in the guess more times than in the solution, only count the first letter as a match
#             if (letter_counts[letter] > 0) and (return_list[i] == 0):
#                 return_list[i] = 1
#                 letter_counts[letter] -= 1

#         return return_list
# # %%
# from tqdm import tqdm
# #Testing
# wordle          = WordleSolver()
# word_list       = wordle.words.apply(lambda x: ''.join(x), axis=1)
# attempt_list    = []
# for solution in tqdm(word_list.sample(100)):
#     wordle          = WordleSolver()
#     wordle_solution = WordleSolution(solution)
#     attempts = 1
#     guess = wordle.solve()
#     res = wordle_solution.verify_guess(guess)
#     results = [(guess, res)]
#     while res != [2, 2, 2, 2, 2]:
#         try:
#             guess = wordle.solve(res)
#         except IndexError as e:
#             print(f"Solution: {solution}")
#             for row in results:
#                 print(f"Guess: {row[0]}, Result: {row[1]}")
#             raise IndexError(e)
#         res = wordle_solution.verify_guess(guess)
#         attempts += 1
#         results += [(guess, res)]

#     attempt_list += [(solution, attempts)]

# # %%
# wordle = WordleSolver()
# ws = WordleSolution('enmew')
# ws.verify_guess('sores')
# %%


from pydoc import plain
import numpy as np
from math import sqrt
import matplotlib.pyplot as plt
from scipy.signal import convolve2d
from dog_bandpass import get_guassian_kernel, get_guassian_blur, get_difference_of_guassians
import os

def dog_visualize(image):
    """
    Input : A RGB image
    Output: A RGB image with the difference of guassians with different sigmas.
    """
    # Case 1:
    # Small sigma 1
    # sigma1 << sigma2

    sigma1 = 1
    sigma2 = sigma1 * 2.5
    kernel_size = int(np.ceil(6 * sigma2))

    _, _, dog = get_difference_of_guassians(image, kernel_size, sigma1, sigma2)

    plt.figure(1)
    plt.subplot(2,2,1)
    plt.imshow(image)
    plt.title('Original Image')
    plt.subplot(2,2,2)
    plt.imshow(dog)
    plt.title(f'Case 1: sigma_1: {sigma1} and sigma_2: {sigma2:.2f}, Window Size: {kernel_size}')

    # Case 2:
    # Large sigma 1 and Large sigma 2
    # sigma1 ~= sigam2

    sigma1 = 5
    sigma2 = sigma1 * 1.1
    kernel_size = int(np.ceil(6 * sigma2))

    _, _, dog = get_difference_of_guassians(image, kernel_size, sigma1, sigma2)

    plt.subplot(2,2,3)
    plt.imshow(dog)
    plt.title(f'Case 2: sigma_1: {sigma1} and sigma_2: {sigma2:.2f}, Window Size: {kernel_size}')

    # Case 3:
    # Small sigma 1 and Small sigma 2
    # sigma1 ~= sigam2

    sigma1 = 1
    sigma2 = sigma1 * 1.1
    kernel_size = int(np.ceil(6 * sigma2))

    _, _, dog = get_difference_of_guassians(image, kernel_size, sigma1, sigma2)

    plt.subplot(2,2,4)
    plt.imshow(dog)
    plt.title(f'Case 3: sigma_1: {sigma1} and sigma_2: {sigma2:.2f}, Window Size: {kernel_size}')
    plt.show()

for image in os.listdir('3images'):
    image_path = os.path.join('3images', image)
    image = plt.imread(image_path)
    dog_visualize(image)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Jun 23 19:22:26 2018

@author: pt
"""

from skimage.io import imread
from skimage.transform import resize
import numpy as np
import os
import pandas as pd
import keras
import cv2
from keras.preprocessing.sequence import TimeseriesGenerator

# Here, `input_data_set` is list of path to the images
# and `labels_set` are the associated classes.

class DataGenerator(keras.preprocessing.sequence.TimeseriesGenerator):
    id_list = []
    imagename_list = []

    def __init__(self, input_data_set, labels_set, length=100, sampling_rate=1, stride=1, start_index=0, end_index=None, shuffle=False, reverse=False, batch_size=16, image_dimention = (160,320), n_channels = 3):
        self.input_data_set = input_data_set
        self.labels_set = labels_set

        self.image_dimention = image_dimention
        self.n_channels = n_channels
        self.batch_size=16

#The following have not been implemented
        self.length=100
        self.sampling_rate=1
        self.stride=1
        self.start_index=0
        self.end_index=None
        self.shuffle=False
        self.reverse=False

    def __len__(self):
        return int(np.ceil(len(self.input_data_set) / float(self.batch_size)))

    def __getitem__(self, idx):
        if self.length == 0:
            batch_input_data_image_array = np.empty((self.batch_size, *self.image_dimention, self.n_channels))

            batch_input_data = self.input_data_set[idx * self.batch_size:(idx + 1) * self.batch_size]
            batch_label_data = self.labels_set[idx * self.batch_size:(idx + 1) * self.batch_size]

            for i, file_name in enumerate(batch_input_data):
                print(file_name)
                batch_input_data_image_array[i] = cv2.imread(file_name)
            return batch_input_data_image_array, np.array(batch_label_data)

'''
    def on_epoch_end(self):
        'Updates indexes after each epoch'
        self.indexes = np.arange(len(self.input_data_set))
        if self.shuffle == True:
            np.random.shuffle(self.indexes)
'''

        #return np.array([resize(imread(file_name), (160, 320)) for file_name in self.batch_input_data]), np.array(batch_label_data)

def strip_filenames(old_path):
    old_path = old_path.split("\\") #handles windows generated files
    *directory, filename = old_path
    directory, filename = os.path.split(filename) #handles linux generated files
    return("/" + filename)

def update_driving_log(data_dir):
    driving_log_csv = data_dir + '/' + 'driving_log.csv'
    new_image_path = data_dir + '/IMG'
    driving_log_pd = pd.read_csv(driving_log_csv)
    driving_log_pd_temp = driving_log_pd.iloc[:,0:3]
    driving_log_pd_temp = driving_log_pd_temp.applymap(strip_filenames)
    driving_log_pd_temp = new_image_path + driving_log_pd_temp.astype(str)
    driving_log_pd.iloc[:,0:3] = driving_log_pd_temp

    driving_log_pd.columns = ['center','left', 'right', 'x','y','z','steering']

    driving_log_pd.to_csv(driving_log_csv, index = False, header = False)

    return driving_log_pd

data_dir = '/home/pt/Desktop/data'

driving_log = update_driving_log(data_dir)

batch_size = 5

params = {
          'image_dimention': (160,320),
          'batch_size': 16,
          'n_channels': 3,
          'shuffle': True,
         }

test = DataGenerator(driving_log['center'], driving_log['steering'], **params) #why **
test.on_epoch_end()

iterator = test.__iter__()

batch = next(iterator)

#batch = test.__getitem__(5)

'''
from matplotlib import pyplot as plt

for i in range(0,batch_size):
    plt.imshow(batch[0][i], interpolation='nearest')

    plt.show()

'''


# Standard libraries
from abc import ABC, abstractmethod
from typing import Protocol, Iterable, Callable, Coroutine, Any

# Third party libraries
from aiohttp import ClientSession

# Code
from sdk.lib.numbers import LongShortNumbers, Number
from sdk.base.readers.structs import PositionsDict

GetPricesFunction = Callable[[PositionsDict], Coroutine[Any, Any, dict[str, Number]]]

class IPriceResolver(Protocol):
    """
    Forward-declared interface for the price resolver.
    """

    def update_positions(self, positions: PositionsDict) -> None:
        ...

    async def resolve_price(self, symbol: str, session: ClientSession) -> Number:
        ...

    async def resolve_prices(
        self, symbols: Iterable[str], session: ClientSession
    ) -> dict[str, Number]:
        ...

class IPriceReader(ABC):
    """
    Interface for the price reader.
    """

    id: str

    @abstractmethod
    async def get_price(
        self,
        symbol: str,
        position: LongShortNumbers,
        resolver: IPriceResolver,
        session: ClientSession,
    ) -> Number:
        """
        Price readers should implement the method to get the price for a symbol.
        """


class Solution:
    def findRepeatedDnaSequences(self, s: str) -> List[str]:
        if len(s) <= 10: return []
        uniques, repeated, repeatedSet = set(), [], set()
        que = deque([None,s[0],s[1],s[2],s[3],s[4],s[5],s[6],s[7],s[8]])

        for i in range(9,len(s)):
            que.popleft()
            que.append(s[i])
            temp = ""
            for j in range(10):
                temp+=str(ord(que[j]))

            temp = int(temp)
            if temp not in uniques:
                uniques.add(temp)
            elif temp not in repeatedSet:
                repeatedSet.add(temp)
                temp = str(temp)
                sequence = ""
                for i in range(0, len(temp), 2):
                    char = temp[i] + temp[i+1]
                    sequence += chr(int(char))
                repeated.append(sequence)

        return repeated


from housing.logger import logging
from housing.exception import housing_exception
from housing.entity.config_entity import Data_Validation_Config
from housing.entity.artifact_entity import DataIngestionArtifact, DataValidationArtifact
import os,sys
import pandas  as pd
from evidently.model_profile import Profile
from evidently.model_profile.sections import DataDriftProfileSection
from evidently.dashboard import Dashboard
from evidently.dashboard.tabs import DataDriftTab
import json
from housing.util.util import read_yaml_file
from housing.constant import *

class DataValidation:

    def __init__(self, data_validation_config:Data_Validation_Config,
        data_ingestion_artifact:DataIngestionArtifact):
        try:
            logging.info(f"{'>>'*30}Data Valdaition log started.{'<<'*30} \n\n")
            self.data_validation_config = data_validation_config
            self.data_ingestion_artifact = data_ingestion_artifact
        except Exception as e:
            raise housing_exception(e,sys) from e

    def get_train_and_test_df(self):
        try:
            train_df = pd.read_csv(self.data_ingestion_artifact.train_file_path)
            test_df = pd.read_csv(self.data_ingestion_artifact.test_file_path)
            return train_df,test_df
        except Exception as e:
            raise housing_exception(e,sys) from e

    def is_train_test_file_exists(self)->bool:
        try:
            logging.info("Checking if training and test file is available")
            is_train_file_exist = False
            is_test_file_exist = False

            train_file_path = self.data_ingestion_artifact.train_file_path
            test_file_path = self.data_ingestion_artifact.test_file_path

            is_train_file_exist = os.path.exists(train_file_path)
            is_test_file_exist = os.path.exists(test_file_path)

            is_available =  is_train_file_exist and is_test_file_exist

            logging.info(f"Is train and test file exists?-> {is_available}")

            if not is_available:
                training_file = self.data_ingestion_artifact.train_file_path
                testing_file = self.data_ingestion_artifact.test_file_path
                message=f"Training file: {training_file} or Testing file: {testing_file}" \
                    "is not present"
                raise Exception(message)

            return is_available
        except Exception as e:
            raise housing_exception(e,sys) from e

    def validate_dataset_schema(self)->bool:#,schema_file_path,file_path)->bool:
        try:
            # validation_status = True#
            # column_count_equal= False#
            # column_names_same= False#

            #Assigment validate training and testing dataset using schema file
            #1. Number of Column
            #2. Check the value of ocean proximity
            # acceptable values     <1H OCEAN
            # INLAND
            # ISLAND
            # NEAR BAY
            # NEAR OCEAN
            #3. Check column names

            # we dont mmodify any data(thats done in the feature engineering stage) here we just check the above steps

            # dataset_schema=read_yaml_file(schema_file_path)#
            # schema=dataset_schema[DATASET_SCHEMA_COLUMNS_KEY]#

            # df=pd.read_csv(file_path=file_path)#

# checking column numbers in the schema file and dataset of the column same or not

            # if len(list(schema.keys()))==len(df.columns):#
            #     column_count_equal=True#

# checking columns name in the schema file and dataset same or not

            # for col in df.columns:
            #     if col in list(schema.keys()):
            #         df[col].astype(schema[col])
            #         column_names_same=True
            #     else:
            #         column_names_same=False

            # if column_count_equal and column_names_same:
            #     validation_status=True

            validation_status = True
            return validation_status
        except Exception as e:
            raise housing_exception(e,sys) from e

    def get_and_save_data_drift_report(self):
        try:
            profile = Profile(sections=[DataDriftProfileSection()])

            train_df,test_df = self.get_train_and_test_df()

            profile.calculate(train_df,test_df)

            report = json.loads(profile.json())

            # profile.json is a string which is from json file we need
            # json.loads loads the string format into the json file format

            report_file_path = self.data_validation_config.report_file_path
            report_dir = os.path.dirname(report_file_path)
            os.makedirs(report_dir,exist_ok=True)

            with open(report_file_path,"w") as report_file:
                json.dump(report, report_file, indent=6)
            return report
        except Exception as e:
            raise housing_exception(e,sys) from e

    def save_data_drift_report_page(self):
        try:
            dashboard = Dashboard(tabs=[DataDriftTab()])
            train_df,test_df = self.get_train_and_test_df()
            dashboard.calculate(train_df,test_df)

            report_page_file_path = self.data_validation_config.report_page_file_path
            report_page_dir = os.path.dirname(report_page_file_path)
            os.makedirs(report_page_dir,exist_ok=True)

            dashboard.save(report_page_file_path)
        except Exception as e:
            raise housing_exception(e,sys) from e

    def is_data_drift_found(self)->bool:
        try:
            report = self.get_and_save_data_drift_report()
            self.save_data_drift_report_page()
            return True
        except Exception as e:
            raise housing_exception(e,sys) from e

    def initiate_data_validation(self)->DataValidationArtifact :
        try:
            self.is_train_test_file_exists()
            self.validate_dataset_schema()
            self.is_data_drift_found()

            data_validation_artifact = DataValidationArtifact(
                schema_file_path=self.data_validation_config.schema_file_path,
                report_file_path=self.data_validation_config.report_file_path,
                report_page_file_path=self.data_validation_config.report_page_file_path,
                is_validated=True,
                message="Data Validation performed successully."
            )
            logging.info(f"Data validation artifact: {data_validation_artifact}")
            return data_validation_artifact
        except Exception as e:
            raise housing_exception(e,sys) from e

    def __del__(self):
        logging.info(f"{'>>'*30}Data Validation log completed.{'<<'*30} \n\n")


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('timetable', '0004_auto_20150926_2224'),
    ]

    operations = [
        migrations.AddField(
            model_name='chat',
            name='teachers_id',
            field=models.IntegerField(default=0),
        ),
        migrations.AlterField(
            model_name='chat',
            name='group',
            field=models.CharField(max_length=16, default=''),
        ),
    ]


name = 'HDF'
server = 'ftp://ftp.hdfgroup.org/HDF/prev-releases'

def get( version = None, **kwds ):
    if version is None: version = "4.2r1"
    identifier = '%s%s' % (name, version)
    cmds = [
         #we don't need fortran library, right?
        'LDFLAGS=-lm ./configure --prefix=$PREF  --with-jpeg=$PREF --with-szip=$PREF --with-zlib=$PREF --enable-fortran=no',
        'make',
        'make install',
        ]
    def _():
        install( name, version,
                 identifier = identifier, server = server,
                 install_commands = cmds,
                 **kwds )
        import os
        os.environ['HDF4_DIR'] = install_path
        return
    return _

from utils.installers.src import install, install_path


# Meteorographica example script

# Set up the figure and add the continents as background
# (don't actually plot any weather).

import Meteorographica as mg

import matplotlib
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
import cartopy
import cartopy.crs as ccrs

# Define the figure (page size, background color, resolution, ...
aspect=16/9.0
fig=Figure(figsize=(22,22/aspect),              # Width, Height (inches)
           dpi=100,
           facecolor=(0.88,0.88,0.88,1),
           edgecolor=None,
           linewidth=0.0,
           frameon=False,                # Don't draw a frame
           subplotpars=None,
           tight_layout=None)
# Attach a canvas
canvas=FigureCanvas(fig)

# All mg plots use Rotated Pole, in this case just use the standard
#  pole location.
projection=ccrs.RotatedPole(pole_longitude=180.0, pole_latitude=90.0)

# Define an axes to contain the plot. In this case our axes covers
#  the whole figure
ax = fig.add_axes([0,0,1,1],projection=projection)
ax.set_axis_off() # Don't want surrounding x and y axis
# Set the axes background colour
ax.background_patch.set_facecolor((0.88,0.88,0.88,1))

# Lat and lon range (in rotated-pole coordinates) for plot
extent=[-180.0,180.0,-90.0,90.0]
ax.set_extent(extent, crs=projection)
# Lat:Lon aspect does not match the plot aspect, ignore this and
#  fill the figure with the plot.
matplotlib.rc('image',aspect='auto')

# Draw a lat:lon grid
mg.background.add_grid(ax,
                       sep_major=5,
                       sep_minor=2.5,
                       color=(0,0.3,0,0.2))

# Add the land
land_img=ax.background_img(name='GreyT', resolution='low')

# Render the figure as a png
fig.savefig('background.png')


import numpy as np
from numpy import ndarray
from pkgutil import get_data

def normalize_and_add_one(_x: ndarray) -> ndarray:
    x_max = np.array([[np.amax(_x[:, column_id])
                       for column_id in range(_x.shape[1])]
                      for _ in range(_x.shape[0])])
    x_min = np.array([[np.amin(_x[:, column_id])
                       for column_id in range(_x.shape[1])]
                      for _ in range(_x.shape[0])])
    x_normalized = (_x - x_min) / (x_max - x_min)
    one_column = np.array([[1] for _ in range(_x.shape[0])])

    return np.column_stack((one_column, x_normalized))

class RidgeRegression:
    def __init__(self):
        return

    def fit(self, _x_train: ndarray, _y_train: ndarray, _lambda: float) -> ndarray:
        # compute the matrix w with ridge session_1:
        # w = (XT.X + lambda.I).inv.X.Y
        return np.linalg.inv(_x_train.transpose().dot(_x_train) + _lambda * np.identity(_x_train.shape[1])) \
            .dot(_x_train.transpose()).dot(_y_train)

    def predict(self, _w: ndarray, _x_new: ndarray) -> ndarray:
        # compute the predicted value
        # y_predict = x_new * w
        return _x_new.dot(_w)

    def compute_rss(self, _y_new, _y_predicted):
        # rss = (1/n).sum(_y_new - y_predicted) ** 2)
        loss = 1. / (_y_new.shape[0]) * np.sum((_y_new - _y_predicted) ** 2)
        return loss

    def fit_gradient_descent(self, _x_train: ndarray, _y_train: ndarray,
                             _lambda: float, _learning_rate: float, _max_num_epoch=100, _batch_size=128):
        # loop to achieve the minimum loss
        _w = np.random.randn(_x_train.shape[1])  # initialize random w
        _last_loss = 10e8
        for ep in range(_max_num_epoch):
            _arr = np.array(range(_x_train.shape[0]))  # _arr = [0, 1, 2,..., N-1]
            np.random.shuffle(_arr)  # random shuffle the _arr array
            _x_train = _x_train[_arr]  # shuffle _x_train according to _arr
            _y_train = _y_train[_arr]  # shuffle _y_train according to _arr
            _total_minibatch = int(np.ceil(_x_train.shape[0] / _batch_size))
            for i in range(_total_minibatch):  # separate train data to some minibatch
                _index = i * _batch_size
                _x_train_sub: ndarray = _x_train[_index: _index + _batch_size]
                _y_train_sub: ndarray = _y_train[_index: _index + _batch_size]
                _grad = _x_train_sub.T.dot(_x_train_sub.dot(_w) - _y_train_sub) \
                        + _lambda * _w  # grad = XT.(Xw - y) + lamda.w
                _w = _w - _learning_rate * _grad  # update w
            _new_loss = self.compute_rss(_y_train, self.predict(_w, _x_train))
            if np.abs(_new_loss - _last_loss) < 1e-5:
                break
            _last_loss = _new_loss  # update new loss
        return _w

    def get_the_best_lambda(self, _x_train, _y_train):
        # do cross validation with potential lambda
        def cross_validation(_num_folds, _lambda):
            _row_ids = np.array(range(_x_train.shape[0]))
            # split row_ids to _num_folds part, test_ids[i] is used for test i
            _test_ids = np.split(_row_ids[:len(_row_ids) - len(_row_ids) % _num_folds],
                                 _num_folds)
            _test_ids[-1] = np.append(_test_ids[-1], _row_ids[len(_row_ids) - len(_row_ids) % _num_folds:])
            _train_ids = [[k for k in _row_ids if k not in _test_ids[i]]
                          for i in range(_num_folds)]  # train_ids[i] does not contain test_ids[i], is used for train i
            _sum_rss = 0
            for i in range(_num_folds):
                _test_parts = {'X': _x_train[_test_ids[i]], 'Y': _y_train[_test_ids[i]]}
                _train_parts = {'X': _x_train[_train_ids[i]], 'Y': _y_train[_train_ids[i]]}
                _w = self.fit(_train_parts['X'], _train_parts['Y'], _lambda)
                _y_predicted = self.predict(_w, _test_parts['X'])
                _sum_rss += self.compute_rss(_test_parts['Y'], _y_predicted)
            return _sum_rss / _num_folds

        # choose the best lambda with the minimun rss in lambda_values
        def range_scan(_best_lambda: float, _minimum_rss: float, _lambda_values):
            for _current_lambda in _lambda_values:
                average_rss = cross_validation(5, _current_lambda)
                if average_rss < _minimum_rss:
                    _best_lambda = _current_lambda
                    _minimum_rss = average_rss
                return _best_lambda, _minimum_rss

        _best_lambda, _minimum_rss = range_scan(0, 1000000, range(50))  # find best_lambda int
        print(_best_lambda)
        _lambda_values = [k * 1. / 1000 for k in range(
            max(0, (_best_lambda - 1) * 1000), (_best_lambda + 1) * 1000
        )]  # range from (best_lambda - 1) or 0 to (best_lambda + 1) with step 0.001
        _best_lambda, _minimum_rss = range_scan(_best_lambda, _minimum_rss, _lambda_values)
        return _best_lambda

def get_data(path):
    with open(path) as f:
        _data = f.readlines()[72:]
        _temp = []
        for _line in _data:
            _line = _line.strip()
            _row = [float(i) for i in (_line.split())]
            _temp.append(_row)
    _res = np.array(_temp)
    return _res[:, 1:-1], _res[:, -1]

if __name__ == '__main__':
    x, y = get_data("../datasets/x28.txt")
    x = normalize_and_add_one(x)
    x_train, y_train = x[:50], y[:50]
    x_test, y_test = x[50:], y[50:]

    ridge_regression = RidgeRegression()
    best_lambda = ridge_regression.get_the_best_lambda(x_train, y_train)
    print("Best LAMBDA: ", best_lambda)
    w_learned = ridge_regression.fit(x_train, y_train, best_lambda)
    y_predicted = ridge_regression.predict(w_learned, x_test)
    print("RSS: ", ridge_regression.compute_rss(y_test, y_predicted))


import unittest
from cogent.sip.sipsim import (SipPhenom,
                               PartSplineReconstruct)
from datetime import datetime, timedelta
from tests.test_sip_phenom import my_total_seconds

class TestSipSpline(unittest.TestCase):
    """ test sipsim.PartSplineReconstruct """
    def test1(self):
        """ sequence 4 is missed, so we should have straight line
        interpolation between 3 and 5.
        """
        tvd = [(0, 1, 0, 1),
               (3, 2, 1./4, 2),
               (7, 3, -1./13, 3),
               (20, 3, 1./13, 5),  # missed seq 4
               (24, 1, 0, 9)]  # missed 6,7,8
        data = []
        now = datetime(2001, 1, 1)
        for (t, v, d, s) in tvd:
            data.append((now + timedelta(minutes=1*t), v, d, s))

        result = list(PartSplineReconstruct
                     (src=SipPhenom(src=data,
                                    interval=timedelta(minutes=1)),
                      threshold=0.1))
        for ptup in result:
            self.assertTrue(ptup.dashed is not None)
            intvl = int(my_total_seconds((ptup.dt - now)) /
                        my_total_seconds(timedelta(minutes=1)))
            if intvl >= 7 and intvl <= 20:
                self.assertEquals(ptup.sp, 3)
            if intvl > 20 and intvl <= 25:
                self.assertEquals(ptup.sp, (intvl - 20) * (1.-3.)/(24-20) + 3)

        for i, ptup in enumerate(result):
            intvl = int(my_total_seconds((ptup.dt - now)) /
                        my_total_seconds(timedelta(minutes=1)))
            self.assertEquals(i, intvl)


from django.contrib import admin
from django.urls import path, include

from order_manager import views

app_name = 'order_manager'
urlpatterns = [
    path('index/', views.index, name='index'),
    path('index/getOrderData/', views.getOrderData, name='getOrderData'),
    path('index/deleteOrderData/', views.deleteOrderData, name='deleteOrderData'),
    path('index/addOrderData/', views.addOrderData, name='addOrderData'),
    # path('index/getOrderNo/', views.getOrderNo, name='getOrderNo'),
    path('index/getOrderNo/', views.GetOrderNum.as_view(), name='getOrderNo'),

    path('index/updateOrderData/', views.updateOrderData, name='updateOrderData'),

]


from actrmodel import ACTRModel
from chunkCog import Chunk
import temporal
import time as tm
import pandas as pd
import numpy as np
from os import path

# The cognitive part of the game's model

class CognitiveModel(ACTRModel):
    def __init__(self):
        super().__init__()
        self.rt = -2.0
        # initialise memory
        self._init_memory()
        self.learned_memory = []
        self.mem_index = 0

    # Initialise declarative memory with gap facts and pulse durations
    def _init_memory(self):
        self._add_gap_facts()
        self._add_wait_facts()
        # add variable include_learned=False if you don't want learned memories
        # added to the model's memory
        self.load_learned_memory()

    # add gap, pulses from the init_memory file
    def _add_wait_facts(self):
        # Get initial times to wait from timing_data csv
        data = pd.read_csv('../data/init_memory.csv', usecols=['Gap', 'Pulses'])
        array = data.to_numpy()  # data is type numpy.int64 (compatible with int)
        for gap, time in array:
            self.add_wait_fact(gap, time)

    # add gap, pulses from learned_memory file
    def load_learned_memory(self, include_learned=True):
        if not path.isfile('../data/learned_memory.csv'):
            return
        data = pd.read_csv('../data/learned_memory.csv', usecols=['Gap', 'Pulses'])
        array = data.to_numpy()
        self.learned_memory = [(gap, pulses) for [gap, pulses] in array]
        self.mem_index = len(self.learned_memory)
        if include_learned:
            for gap, time in array:
                self.add_wait_fact(gap, time)
        print("loaded learned memory")

    # Generate chunks for the gap facts and add them to memory
    def _add_gap_facts(self):
        for n1 in range(0, 10):
            for n2 in range(0, 10):
                chunk_name = "gf-" + str(n1) + str(n2)
                gap_fact = Chunk(name=chunk_name, slots={"type": "gap-fact",
                                                         "num1": n1, "num2": n2, "gap": (n1 - n2)}, blc=10)
                self.add_encounter(gap_fact)

    # Takes gap and time in pulses as arguments then creates a new wait fact in memory
    def add_wait_fact(self, gap, time, add_to_csv=False):
        if gap is not None and time is not None:
            chunk_name = "g" + str(gap) + "-w" + str(time)
            wait_fact = Chunk(name=chunk_name, slots={"type": "wait-fact",
                                                      "gap": gap, "wait": time}, blc=5)
            # add new fact to memory (or add encounter to already existing memory)
            self.add_encounter(wait_fact)
            if add_to_csv and (gap, time) not in self.learned_memory:
                self.learned_memory.append((gap, time))

    # append the learned_memory csv
    def append_learned_memory(self):
        if len(self.learned_memory) <= self.mem_index:
            print("No new memories to add.")
            return
        print("Adding new memories to the learned memories data file.")
        # only add the memories that weren't in csv yet
        for i, new_memory in enumerate(self.learned_memory, self.mem_index):
            gap, pulses = new_memory
            seconds = temporal.pulses_to_time(pulses)
            # initialise new row for csv
            row = [gap, round(seconds, 3), int(pulses)]
            # Create DataFrame of new row
            df = pd.DataFrame(row).transpose()
            df.columns = ['Gap', 'Time (s)', "Pulses"]
            # add new df to csv
            with open('../data/learned_memory.csv', 'a') as f:
                df.to_csv(f, mode='a', header=f.tell() == 0, index=False)
        added = len(self.learned_memory) - self.mem_index
        print(f"I added {added} new memories.")
        # update the memory index so that the newly-added memories will only be added once
        self.mem_index = len(self.learned_memory)

    # generates time for the model to perform a movement + randomness
    # t can be generated with Fitt's Law but is set as 0.1 as minimum-time, n = 3 by default
    def get_movement_time(self, t=0.1, n=3):
        low = t * ((n - 1) / n)
        high = t * ((n + 1) / n)
        # time the actual movement takes
        mt = np.random.uniform(low, high)
        # time for initiation, preparation, and execution of movement
        mt += 0.15
        self.time += mt
        return mt

    # model retrieves how long it has to wait with a given gap
    def get_wait_time(self, gap):
        blend_pattern = Chunk(name="blend-pattern", slots={"type": "wait-fact", "gap": gap})
        tm.sleep(0.05)
        wait_time, latency = self.retrieve_blended_trace(blend_pattern, "wait")
        tm.sleep(latency)
        # add time for retrieval request
        self.time += 0.05 + latency
        # if model has seen this gap before, return wait time
        if wait_time is not None:
            return wait_time
        # if model has not seen this gap before, return wait time of most similar gap
        else:
            partial_pattern = Chunk(name="partial-pattern", slots={"type": "wait-fact", "gap": gap})
            tm.sleep(0.05)
            wait_fact, latency = self.retrieve_partial(partial_pattern)
            tm.sleep(latency)
            # add time for second retrieval request
            self.time += 0.05 + latency
            wait_time = wait_fact.slots["wait"]
            if wait_time is None:
                raise LookupError("I couldn't figure out how long to wait.")
            return wait_time

    # separate a number into tens and ones
    @staticmethod
    def sep_number(n):
        tens = int(n / 10)
        ones = n % 10
        return tens, ones

    # model calculates the difference between hand and pile
    def determine_gap(self, hand, pile):
        if hand == 100:
            # treat 100 as a gap of 1 (play "instantly")
            return 1

        # model hasn't started gap calculation yet
        if self.imaginal is None:
            tens_hand, ones_hand = self.sep_number(hand)
            tens_pile, ones_pile = self.sep_number(pile)
            calc_gap = Chunk(name="calc-gap",
                             slots={"ones1": ones_hand, "ones2": ones_pile, "tens1": tens_hand, "tens2": tens_pile,
                                    "gap-tens": None, "gap-ones": None, "gap-tot": None})
            tm.sleep(0.2)
            self.imaginal = calc_gap
            # imaginal request takes 200 ms
            self.time += 0.2
            self.determine_gap(hand, pile)

        if self.imaginal.slots["gap-tens"] is None and (hand >= 10 or pile >= 10):
            # time for production firing
            tm.sleep(0.05)
            self.time += 0.05
            tens_hand = self.imaginal.slots["tens1"]
            tens_pile = self.imaginal.slots["tens2"]
            # get gap fact for tens
            pattern = Chunk(name="retrieve", slots={"type": "gap-fact", "num1": tens_hand, "num2": tens_pile})
            tm.sleep(0.05)
            chunk, latency = self.retrieve(pattern)
            tm.sleep(latency)
            # add time for retrieval request and time it takes to get chunk
            self.time += 0.05 + latency
            tm.sleep(0.2)
            self.imaginal.slots["gap-tens"] = chunk.slots["gap"]
            # modifying imaginal buffer takes time
            self.time += 0.2
            self.determine_gap(hand, pile)

        if self.imaginal.slots["gap-ones"] is None:
            # time for production firing
            tm.sleep(0.05)
            self.time += 0.05
            ones_hand = self.imaginal.slots["ones1"]
            ones_pile = self.imaginal.slots["ones2"]
            pattern = Chunk(name="retrieve", slots={"type": "gap-fact", "num1": ones_hand, "num2": ones_pile})
            tm.sleep(0.05)
            chunk, latency = self.retrieve(pattern)
            tm.sleep(latency)
            # add time for retrieval request and time it takes to get chunk
            self.time += 0.05 + latency
            tm.sleep(0.2)
            self.imaginal.slots["gap-ones"] = chunk.slots["gap"]
            # modifying imaginal buffer takes time
            self.time += 0.2
            self.determine_gap(hand, pile)

        if self.imaginal.slots["gap-tot"] is None:
            # time for production firing
            tm.sleep(0.05)
            self.time += 0.05
            if self.imaginal.slots["gap-tens"] is not None:
                gap_tens = self.imaginal.slots["gap-tens"]
            else:
                gap_tens = 0
            gap_ones = self.imaginal.slots["gap-ones"]
            gap_tot = gap_tens * 10 + gap_ones
            tm.sleep(0.2)
            self.imaginal.slots["gap_tot"] = gap_tot
            # modifying imaginal buffer takes time
            self.time += 0.2
            return gap_tot

        return None

    # add goal to model's goal buffer
    def _add_goal(self):
        goal_0 = Chunk(name="goal", slots={"type": "game-state", "hand": None, "pile": 0,
                                           "gap": None, "wait": None, "success": None})
        tm.sleep(0.05)
        self.goal = goal_0
        # setting a goal takes 50 ms
        self.time += 0.05

    # process change in pile in goal buffer
    def set_pile(self, top_card):
        self.check_goal()
        tm.sleep(0.05)
        self.goal.slots["pile"] = top_card
        self.time += 0.05

    # process change in hand in goal buffer
    def set_hand(self, lowest_card):
        self.check_goal()
        tm.sleep(0.05)
        self.goal.slots["hand"] = lowest_card
        self.time += 0.05

    # check goal is not None
    def check_goal(self):
        if self.goal is None:
            raise ValueError("I've lost track of the game-state.")

    # reset goal entirely or partially
    def reset_goal(self, partial=False):
        print("model goal reset")
        # If goal has already been created, reset its slots
        if self.goal is not None:
            tm.sleep(0.05)
            # also reset the hand and pile
            if not partial:
                self.goal.slots["hand"] = None
                self.goal.slots["pile"] = 0
            self.goal.slots["gap"] = None
            self.goal.slots["wait"] = None
            self.goal.slots["success"] = None
            self.time += 0.05
        else:
            # if goal chunk does not yet exist, create it
            self._add_goal()

    # reset imaginal buffer
    def reset_imaginal(self):
        if self.imaginal is not None:
            self.imaginal = None


# 题目：列表转换为字典。
#!/usr/bin/python
# -*- coding: UTF-8 -*-

i = ['a', 'b']
l = [1, 2]
print(dict([i,l]))

#!/usr/bin/python3
# -*- coding: UTF-8 -*-

# 从列表创建字典
i = ['a','b','c']
l = [1,2,3]
#  zip() 函数用于将可迭代的对象作为参数,
# 将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表
b=dict(zip(i,l))
print(b)


"""Module to set fabric names and labels manually"""

import numpy as np
import pandas as pd

import utilities.module_execution as meop

def manual_fabrics_labeling(fabricshow_summary_df, fabricshow_summary_automatic_df, info_labels):
    """Function to manual change Fabric Name and Fabric Label."""
    # copy of initial fabricshow_summary DataFrame
    # to be able to reset all changes
    fabricshow_summary_default_df = fabricshow_summary_df.copy()
    # convert DataFrame indexes to string versions
    fabric_indexes_str_lst = [str(i) for i in fabricshow_summary_df.index]
    # DataFrame operation options (save, reset, exit)
    opeartion_options_lst = ['s', 'r', 'v', 'x', 'a']
    # aggregated list of available operations
    full_options_lst = fabric_indexes_str_lst + opeartion_options_lst
    # parameters to change
    rename_options_dct = {'NAME': 'Fabric_name', 'LABEL': 'Fabric_label'}

    # user input from full_options_lst
    # initial value is None to enter while
    input_option = None
    # work with DataFrame until it is saved or exit without saving
    while not input_option in ['s', 'x']:

        fabricshow_summary_df.sort_values(by=['Fabric_name', 'Fabric_label', 'Principal_switch_name', 'Domain_IDs'],
                                                inplace=True, ignore_index=True)
        # no need to print fabric info after verification
        if input_option != 'v':
            # printing actual fabricshow_summary DataFrame
            print('\nCurrent fabric labeling\n')
            print(fabricshow_summary_df.loc[:, info_labels])

        # printing menu options to choose to work with DataFrame
        # save, reset, exit or fabric index number to change
        print('\nS/s - Save changes in labeling\nA/a - Atomatic labeling\nR/r - Reset to default labeling\nV/v - Veriify labeling\nX/x - Exit without saving')
        print(f"{', '.join(fabric_indexes_str_lst)} - Choose fabric index to change labeling\n")
        # reset input_option value after each iteration to enter while loop
        input_option = meop.reply_request("Choose option: ", reply_options = full_options_lst, show_reply = True)

        # user input is fabric index to change labeling
        if input_option in fabric_indexes_str_lst:
            print('\n')
            # make copy of actual fabricshow_summary DataFrame
            # to be able to reset current iteration changes
            fabricshow_summary_before_df = fabricshow_summary_df.copy()

            # convert user input fabric number to integer
            fabric_num = int(input_option)
            # printing information for current fabric
            print(fabricshow_summary_df.iloc[fabric_num])
            print('\n')

            # list to save user input
            reply_lst = []
            # initial user input to check if nan is entered
            value = 'empty'
            # ask user to change labels and names by looping over rename_options_dct
            for option_name, option_column in rename_options_dct.items():
                if value:
                    reply = meop.reply_request(f'Do you want to change Fabric {option_name}? (y)es/(n)o: ')
                    # save user input to the list
                    reply_lst.append(reply)
                    # if user want to change name or label ask to enter new value
                    if reply == 'y':
                        current_value = fabricshow_summary_df.loc[fabric_num, rename_options_dct[option_name]]
                        value = input(f'\nEnter new Fabric {option_name}. 0 or None will remove fabric from assessment. Current value is {current_value}: ')
                        value = value.strip()
                        # 0 or None means no labeling
                        if value.lower() in ['0', 'none']:
                            value = None
                            fabricshow_summary_df.loc[fabric_num, ['Fabric_name', 'Fabric_label']] = [np.nan, np.nan]
                        elif len(value) == 0:
                            value = current_value
                            print(f'Fabric {option_name} was not changed')
                        else:
                            # change values in fabricshow_summary DataFrame
                            fabricshow_summary_df.loc[fabric_num, option_column] = value
            # if user didn't reply "no" two times
            if reply_lst != ['n']*2:
                print('\n')
                # print current fabric information after change
                print(fabricshow_summary_df.iloc[fabric_num])
                print('\n')
                # verify if Fabric names or label is NaN and ask input
                label_name_uniformity = fabricshow_summary_df.loc[fabric_num, rename_options_dct.values()].isna().nunique() == 1
                if not label_name_uniformity:
                    print('Fabric NAME and Fabric LABEL fields BOTH must have values')
                    # verify which label have Nan value
                    nan_option_name, = [key for key, value in rename_options_dct.items() if pd.isna(fabricshow_summary_df.loc[fabric_num, value])]
                    while True:
                        current_value = fabricshow_summary_df.loc[fabric_num, rename_options_dct[nan_option_name]]
                        value = input(f'\nEnter new Fabric {nan_option_name}. Current value is {current_value}: ')
                        value = value.strip()
                        # 0, None or '' means no labeling
                        if value in ['0', 'None', '', 'none']:
                            print(f"Fabric {nan_option_name} must have value.")
                            continue
                        else:
                            fabricshow_summary_df.loc[fabric_num, rename_options_dct[nan_option_name]] = value
                            print('\n')
                            # print current fabric information after change
                            print(fabricshow_summary_df.iloc[fabric_num])
                            print('\n')
                            break

                reply = meop.reply_request('Do you want to keep changes? (y)es/(n)o: ')
                # when user doesn't want to keep data fabricshow_summary DataFrame
                # returns to the state saved bedore current iteration
                if reply == 'n':
                    fabricshow_summary_df = fabricshow_summary_before_df.copy()
        # user input is verify fabric labeling
        elif input_option == 'v':
            count_labels_df = verify_fabric_labels(fabricshow_summary_df)
            print('\n', count_labels_df, '\n')
        # user input is save current labeling configuration and exit
        elif input_option == 's':
            count_labels_df = verify_fabric_labels(fabricshow_summary_df)
            print('\n', count_labels_df, '\n')
            # check for errors in fabric labeling
            if (count_labels_df['Verification'] == 'ERROR').any():
                print('There is an error in fabric labeling. Please re-label fabrics.')
                input_option = None
            else:
                # if fabric labeling is ok request to save
                reply = meop.reply_request('Do you want to save changes and exit? (y)es/(n)o: ')
                # for save option do nothing and while loop stops on next condition check
                if reply == 'y':
                    print('\nSaved fabric labeling\n')
                else:
                    input_option = None
        # user input is reset current labeling configuration and start labeling from scratch
        elif input_option == 'r':
            reply = meop.reply_request('Do you want to reset fabric labeling to original values? (y)es/(n)o: ')
            # for reset option actual fabricshow_summary DataFrame returns back
            # to initial DataFrame version and while loop don't stop
            if reply == 'y':
                fabricshow_summary_df = fabricshow_summary_default_df.copy()
                print('\nFabric labeling has been reset to original version\n')
        # user input is automatic re-labeling
        elif input_option == 'a':
            reply = meop.reply_request('Do you want to perform automatic fabric labeling? (y)es/(n)o: ')
            # for reset option actual fabricshow_summary DataFrame returns back
            # to initial DataFrame version and while loop don't stop
            if reply == 'y':
                fabricshow_summary_df = fabricshow_summary_automatic_df.copy()
                print('\nAutomatic fabric labeling has been performed\n')
        # user input is exit without saving
        elif input_option == 'x':
            reply = meop.reply_request('Do you want to leave without saving? (y)es/(n)o: ')
            # for exit option DataFrame returns back to initial version
            # and while loop stops
            if reply == 'y':
                fabricshow_summary_df = fabricshow_summary_default_df.copy()
                print('\nKeeping original labeling version\n')
            else:
                input_option = None
    else:
        # show actual version of DataFrame after user inputs save or exit
        print(fabricshow_summary_df.loc[:, info_labels])
        print('\n')
    return fabricshow_summary_df

def verify_fabric_labels(fabricshow_summary_df):
    """Function to count fabric_labels in each fabric to avoid label duplicates causing errors"""

    # count fabric labels for each fabric name
    count_labels_df = pd.crosstab(fabricshow_summary_df.Fabric_name, fabricshow_summary_df.Fabric_label)
    columns = count_labels_df.columns.tolist()
    count_labels_df['Verification'] = np.nan
    # put 'error' tag for fabric_name if number of any label is exceed 1
    count_labels_df['Verification'] = np.where(count_labels_df[columns].gt(1).any(axis=1), 'ERROR', count_labels_df['Verification'])
    # put 'warning' tag if some labels are absent
    count_labels_df['Verification'] = \
        np.where((count_labels_df[columns] == 0).any(axis=1) & count_labels_df[columns].lt(2).all(axis=1), 'WARNING', count_labels_df['Verification'])
    # put 'ok' tag if each label used once
    count_labels_df['Verification'] = np.where((count_labels_df[columns] == 1).all(axis=1), 'OK', count_labels_df['Verification'])
    return count_labels_df


"""
https://quera.org/problemset/44072/
Author: https://github.com/smh997/
"""
v = int(input())
li = []
for i in range(1, v+1):
    if v % i == 0:
        li.append(i)
mx = 1000000000
for a in li:
    for b in li:
        if v % (a * b) == 0:
            c = v // (a * b)
            mx = min(2 * (a * b) + 2 * (b * c) + 2 * (a * c), mx)
print(mx)


#!/usr/bin/env python3
##############################################################################
###
### This file is part of the BBS software (Bioconductor Build System).
###
### Author: Hervé Pagès <hpages.on.github@gmail.com>
### Last modification: Sep 3, 2020
###
### bbs.rdir module
###

import sys
import os
import urllib.request

sys.path.insert(0, os.path.dirname(__file__))
import fileutils
import jobs

def set_readable_flag(path, verbose=False):
    if sys.platform == "win32" and \
       os.path.exists(path) and \
       os.path.isfile(path):
        #os.chmod(path, 0644)  # this doesn't work
        # This works better but requires Cygwin:
        cmd = "chmod +r " + path
        jobs.runJob(cmd, None, 60.0, verbose)
    return

### Expected bandwidth (in kilobits/s) for transferring data back and forth
### between the central and the secondary build nodes.
### Notes:
###   - This is used for triggering timeouts so in doubt estimate low.
###   - Right now it's only used for transferring data back from the secondary
###     nodes to the central node.
bandwidth_in_kbps = 800.0  # 100 kilobytes per sec
bandwidth_in_bytes_per_sec = bandwidth_in_kbps * 1000.0 / 8.0

class WOpenError(Exception):
    def __init__(self, file):
        self.file = file
    def __str__(self):
        return "Unable to open file %s" % self.file

class RemoteDir:

    # When passed None to the 'host' arg, then degrades to a local dir (and
    # then the 'rsh_cmd' arg. is ignored).
    # When passed None to the 'path' arg, then degrades to a web-based only
    # remote dir (located at the URL specified by 'url'). In that case all
    # the remaining args are ignored and the remote dir can only be accessed
    # in read-only mode (via the WOpen method).
    def __init__(self, label, url,
                 path=None, host=None, user=None, rsh_cmd=None,
                 rsync_cmd=None, rsync_rsh_cmd=None, rsync_options=None):
        self.label = label
        self.url = url
        self.path = path
        self.host = host
        self.user = user
        self.rsh_cmd = rsh_cmd
        self.rsync_cmd = rsync_cmd
        self.rsync_rsh_cmd = rsync_rsh_cmd
        self.rsync_options = rsync_options
        return

    def subdir(self, subdir):
        url = self.url
        if url != None:
            url += '/' + subdir
        path = self.path
        if path != None:
            path += '/' + subdir
        return RemoteDir(self.label + '/' + subdir, url,
                         path, self.host, self.user, self.rsh_cmd,
                         self.rsync_cmd, self.rsync_rsh_cmd, self.rsync_options)

    # Open local or remote file in binary mode.
    def WOpen(self, file, return_None_on_error=False):
        if self.host == None or self.host == 'localhost':
            # self is a local dir
            filepath = os.path.join(self.path, file)
            try:
                # urllib.request.urlopen() below opens the URL in binary mode
                # so we do the same here.
                f = open(filepath, 'rb')
            except IOError:
                if return_None_on_error:
                    return None
                raise WOpenError(filepath)
        else:
            # self is a remote dir accessible via HTTP
            fileurl = self.url + '/' + file
            try:
                f = urllib.request.urlopen(fileurl)
            except urllib.error.HTTPError:
                if return_None_on_error:
                    return None
                raise WOpenError(fileurl)
        return f

    def get_full_remote_path(self):
        if self.host == None or self.host == 'localhost':
            # self is a local dir
            return self.path
        # self is a remote dir
        if self.user == None:
            return "%s:%s" % (self.host, self.path)
        return "%s@%s:%s" % (self.user, self.host, self.path)

    # 'src_path' is relative to 'self'
    # 'dest_path' is a local path that can be absolute or relative to the
    # current dir
    def Get(self, src_path, dest_path=".", verbose=False):
        if self.path == None:
            # 'self' is a web-based only remote dir. 'src_path' must be
            # pointing to a remote file accessible thru HTTP. 'dest_path'
            # must be pointing to a local folder into which the remote file
            # will be downloaded (replacing any existing file).
            src_file = self.WOpen(src_path)
            dest_path = os.path.join(dest_path, src_path)
            dest_file = open(dest_path, 'w')
            for line in src_file:
                dest_file.write(line)
            dest_file.close()
            src_file.close()
            return
        if self.host == None or self.host == 'localhost':
            # self is a local dir
            src_path = os.path.join(self.path, src_path)
            cmd = "%s %s %s %s" % \
                (self.rsync_cmd, self.rsync_options, src_path, dest_path)
        else:
            # self is a remote dir
            src_path = "%s/%s" % (self.get_full_remote_path(), src_path)
            cmd = "%s %s %s %s" % \
                (self.rsync_rsh_cmd, self.rsync_options, src_path, dest_path)
        jobs.tryHardToRunJob(cmd, 5, None, 60.0, 20.0, True, verbose)
        return

    def _Call(self, remote_cmd):
        if self.host == None or self.host == 'localhost':
            # self is a local dir => local execution
            cmd = remote_cmd
        else:
            # self is a remote dir => remote execution
            if self.user != None:
                cmd = self.rsh_cmd + " " + self.user + "@" + self.host + " '" + remote_cmd + "'"
            else:
                cmd = self.rsh_cmd + " " + self.host + " '" + remote_cmd + "'"
        return jobs.call(cmd)

    def MakeMe(self, verbose=False):
        if verbose:
            print("BBS>   mkdir %s/..." % self.label, end=" ")
        remote_cmd = 'mkdir -p ' + self.path
        retcode = self._Call(remote_cmd)
        if retcode != 0:
            if not verbose:
                print("BBS>   mkdir %s/..." % self.label, end=" ")
            sys.exit("ERROR! (retcode: %d)" % retcode)
        if verbose:
            print("OK")
        return

    def RemoveMe(self, verbose=False):
        if verbose:
            print("BBS>   rm -rf %s/..." % self.label, end=" ")
        remote_cmd = 'rm -rf ' + self.path
        retcode = self._Call(remote_cmd)
        if retcode != 0:
            if not verbose:
                print("BBS>   rm -rf %s/..." % self.label, end=" ")
            sys.exit("ERROR! (retcode: %d)" % retcode)
        if verbose:
            print("OK")
        return

    def RemakeMe(self, verbose=False):
        if verbose:
            print("BBS>   (Re)make %s/..." % self.label, end=" ")
        self.RemoveMe()
        self.MakeMe()
        if verbose:
            print("OK")
        return

    def Call(self, remote_cmd):
        remote_cmd = 'cd ' + self.path + ' && (' + remote_cmd + ')'
        return self._Call(remote_cmd)

    def List(self):
        remote_cmd = 'ls'
        # IMPLEMENT ME
        sys.exit("IMPLEMENT ME")
        rdir_files = []
        return rdir_files

    def Del(self, path, verbose=False):
        if verbose:
            print("BBS>   Delete %s/%s..." % (self.label, path), end=" ")
        remote_cmd = 'rm -rf ' + path
        retcode = self.Call(remote_cmd)
        if retcode != 0:
            if not verbose:
                print("BBS>   Delete %s/%s..." % (self.label, path), end=" ")
            sys.exit("ERROR! (retcode: %d)" % retcode)
        if verbose:
            print("OK")
        return

    # 'src_path' is a local path that can be absolute or relative to the
    # current dir
    def Put(self, src_path, failure_is_fatal=True, verbose=False):
        set_readable_flag(src_path, verbose)
        if self.host == None or self.host == 'localhost':
            # self is a local dir
            cmd = "%s %s %s %s" % \
                (self.rsync_cmd, self.rsync_options, src_path, self.path)
        else:
            # self is a remote dir
            cmd = "%s %s %s %s" % \
                (self.rsync_rsh_cmd, self.rsync_options, src_path,
                 self.get_full_remote_path())
        maxtime = 120.0 + fileutils.total_size(src_path) / bandwidth_in_bytes_per_sec
        if verbose:
            if self.host == None or self.host == 'localhost':
                action = "Copying"
            else:
                action = "Sending"
            print("BBS>   %s %s to %s/:" % (action, src_path, self.label))
        jobs.tryHardToRunJob(cmd, 5, None, maxtime, 30.0, failure_is_fatal, verbose)
        return

    def Mput(self, paths, failure_is_fatal=True, verbose=False):
        for path in paths:
            self.Put(path, failure_is_fatal, verbose)
        return

    def syncLocalDir(self, local_dir, verbose=False):
        if os.path.exists(local_dir):
            if not os.path.isdir(local_dir):
                sys.exit("'%s' already exists but is not a directory => EXIT." % local_dir)
        else:
            os.mkdir(local_dir)
        oldcwd = os.getcwd()
        os.chdir(local_dir)
        if self.host == None or self.host == 'localhost':
            # self is a local dir too
            rsync_cmd = self.rsync_cmd
            src = self.path
        else:
            # self is a remote dir
            rsync_cmd = self.rsync_rsh_cmd
            src = self.get_full_remote_path()
        rsync_options = self.rsync_options
        if sys.platform == "win32":
            # Transform symlink into referent file/dir (-L)
            rsync_options += ' -rLptz'
        else:
            # Copy symlinks as symlinks (-l)
            rsync_options += ' -rlptz'
        cmd = "%s %s %s/ %s" % (rsync_cmd, rsync_options, src, '.')
        if verbose:
            print("BBS>   Syncing local '%s' with %s" % (local_dir, self.label))
        ## This can take a veeeeeeeeery long time on Windows!
        jobs.tryHardToRunJob(cmd, 3, None, 2400.0, 30.0, True, verbose)
        ## Workaround a strange problem observed so far on Windows Server
        ## 2008 R2 Enterprise (64-bit) only. After running rsync (from Cygwin)
        ## on this machine to sync a local folder, the local filesystem seems
        ## to be left in a state that confuses the 'tar' command (from Cygwin
        ## or Rtools) i.e. 'tar zcvf ...' fails when trying to store all or
        ## part of the local folder into a tarball complaining that for some
        ## subfolders "file changed as we read it".
        ## Traversing the entire local folder, with e.g. a call to
        ## 'chmod a+r . -R', seems to "fix" the state of the filesystem and
        ## to make 'tar' work again on it.
        if sys.platform == "win32":
            cmd = "chmod a+r . -R"  # from Cygwin (or Rtools)
            ## This can time out on Azure VMs palomino or palomino2 when
            ## syncing the local meat folder with central MEAT0 if 'maxtime'
            ## is set to 5 min so now we allow 10 min.
            jobs.runJob(cmd, None, 600.0, verbose)
        os.chdir(oldcwd)
        return

if __name__ == "__main__":
    sys.exit("ERROR: this Python module can't be used as a standalone script yet")


import pyautogui as py
from time import sleep
import subprocess

comando = "google-chrome --start-maximized"
subprocess.Popen(comando, shell=True )

sleep(4)
py.press('esc')
sleep(1)
py.doubleClick(228, 83)
sleep(1)
py.hotkey('ctrl', 'a')
sleep(1)
py.press('backspace')
sleep(1)
py.typewrite('outlook.com', interval=.2)
sleep(2)
py.press('enter')

sleep(6)

emails = {'ptrk2511@gmail.com':['ENVIO DE EMAIL AUTOMATICO 1' , 'email automatico em python com pyautogui.'],
     'patrickrodriguez8620@gmail.com':['ENVIO DE EMAIL AUTOMATICO 2', 'email automatico em python com pyautogui.']}

t1 = 2
t2 = 5

for key, value in emails.items():

    py.click(108,217)
    sleep(t1 + 1)
    py.click(599, 308)
    sleep(t1)
    py.typewrite(key, interval=.1)

    py.click(535,349)
    py.typewrite(value[0], interval=.2)

    py.click(847,446)
    sleep(t1)
    py.typewrite(value[1], interval=.2)

    py.click(547,264)
    sleep(5)

py.hotkey('ctrl', 'w')


import os
import sys
import glob
import re

import pickle as pkl

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.backends.backend_pdf import PdfPages

import numpy as np
from scipy.spatial.distance import cdist

# from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score

from scipy.spatial import Voronoi, voronoi_plot_2d
from voronoi_2d import voronoi_finite_polygons_2d

if len(sys.argv) < 2 or '-s' not in sys.argv:
	from imageio import imread

	import tensorflow as tf
	from keras.models import load_model
	from keras import backend as K

	import nnFactory as Factory

# silence tf compile warnings
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

ACTIONS = 3
STATE_DIMENSIONS = (40, 40, 3)

NUM_SLICES = 10

PLOT_WIDTH = 0.25
FILENAME_PATTERN = 'actor_trial_'

IMAGE_TYPES =  ['left', 'right', 'forward']

num_images = 0

COLORMAP = ['tab:blue', 'tab:orange', 'tab:green', 'tab:red', 'tab:purple', 'tab:brown', 'tab:pink', 'tab:gray', 'tab:olive', 'tab:cyan']
MARKERMAP = ['o', 's', '^', '*', 'X', 'H']

# populate image lists so we can test these images later
# image lists must all have the same number of images
image_type_list = []
image_file_list = []
image_dict = {}
for image_type in IMAGE_TYPES:
	image_dict[image_type] = []
	num_images = 0
	for image_filename in glob.iglob('camera/' + image_type + '/*.png'):
			image_type_list.append(image_type)
			image_file_list.append(image_filename)
			image_dict[image_type].append(image_filename)
			num_images += 1

def setup_matplotlib():
	font = {'family' : 'League Spartan',
		'weight' : 'bold',
		'size' : '24'}
	plt.rc('font', **font)
	from matplotlib import rcParams
	rcParams.update({'figure.autolayout': True})
	plt.tight_layout()

# given a model, actually compute the actions for each image
def test_network(model, imagefiles_list):
	action_list = []
	for image_filename in imagefiles_list:

		img = imread(image_filename, as_gray=False, pilmode="RGB")
		img = img / np.max(img)

		graph = tf.get_default_graph()

		with graph.as_default():
				model._make_predict_function()
				K.set_learning_phase(0)

				action = np.reshape(model.predict(np.expand_dims(img, axis=0)), ACTIONS)

		if np.any(np.isnan(action)):
				raise ValueError("Net is broken!")

		# Actions:
		# Forward, Left (lateral), Left Rotation
		# x0.03, x0.03, x90*

		action_list.append(action)

	return action_list

def get_masks(original_weights):
	mask_list = []

	# for each group of neurons, create a mask dropping out that group
	SLICE_SIZE = 100 // NUM_SLICES
	for n in range(NUM_SLICES):
		mask_ = []
		for layer in original_weights:
			if layer.shape == (200, 100):
				# set weights to zero
				layer = np.ones_like(layer)
				n_ = n*SLICE_SIZE
				layer[:, n_:(n_ + SLICE_SIZE)] = 0
				mask_.append(layer)
			elif layer.shape == (100,):
				# set biases to zero
				layer = np.ones_like(layer)
				n_ = n*SLICE_SIZE
				layer[n_:(n_ + SLICE_SIZE)] = 0
				mask_.append(layer)
			else:
				mask_.append(np.ones_like(layer))
		mask_list.append(mask_)

	return mask_list

def num_to_color(arr):
	new_arr = []
	for item in arr.tolist():
		if item == 0:
			new_arr.append((0, 1, 0))
		else:
			new_arr.append((item, 0, 1 - item))
	return new_arr

def plot_actions(pdf, actions, action_max, title, colors=None, zero_index=True, y_label="Output"):
	font = {'family' : 'League Spartan',
		'weight' : 'bold'}
	plt.rc('font', **font)

	ind = np.arange(len(actions))
	if not zero_index:
		actions = np.delete(actions, (0), axis=0)
		if colors is not None:
			colors = np.delete(colors, (0), axis=0)
		ind = np.arange(len(actions)) + 1

	if colors is None:
		color_0 = ['#ea4626'] * len(actions)
		color_1 = ['#0060ff'] * len(actions)
	else:
		color_0 = num_to_color( np.abs(colors[:, 0] / action_max) )
		color_1 = num_to_color( np.abs(colors[:, 1] / action_max) )

	ax = plt.subplot(111)

	# use subplots2grid to add the images

	# plt.figure().imshow(plt.imread(image_filename), extent=[-0.5, 0.5, np.max(old_action) + PLOT_WIDTH, np.max(old_action) + 4*PLOT_WIDTH])

	ax.grid(color='#bbbbbb', linestyle='solid', linewidth=1)
	ax.set_axisbelow(True)

	ax.bar(ind - (PLOT_WIDTH / 2), actions[:, 0], width=PLOT_WIDTH, align='center', color=color_0)
	ax.bar(ind + (PLOT_WIDTH / 2), actions[:, 1], width=PLOT_WIDTH, align='center', color=color_1)

	ax.set_xlabel('Ablation Group')
	ax.set_ylabel(y_label)
	ax.set_xticks(range(1, 11))

	# ax2 = plt.figure().add_axes([0, 0.9, 0.1, 0.1])
	# ax2.imshow(plt.imread(image_filename))

	plt.title(title)
	pdf.savefig()
	plt.clf()

def test_network_knife(model, network_file_path, imagefiles_list, imagetypes_list):

	imagefiles_list = np.array(imagefiles_list)
	imagetypes_list = np.array(imagetypes_list)

	model.load_weights(network_file_path)

	original_weights = np.copy(model.get_weights())

	# test the network on the unmodified model as a baseline for comparison
	orig_actions = test_network(model, imagefiles_list)

	# for each group of neurons, create a mask dropping out that group
	mask_list = get_masks(original_weights)

	# calculate the actions for each mask
	# create a list with an inner list for each image
	new_action_array = [] # actions for each mask after it's applied
	for image_idx in range(len(orig_actions)):
				new_action_array.append([])

	all_differences = []
	trial_results = []
	# calculate each new action, then save in the arrays
	for mask_num, mask in enumerate(mask_list):
		trial_results.append([])

		new_weights = np.copy(original_weights)
		new_weights *= mask

		model.set_weights(new_weights)

		for imgtype_num, image_type in enumerate(IMAGE_TYPES):
			local_imagefiles = imagefiles_list[imagetypes_list == image_type]
			trial_results[mask_num].append([])

			new_actions = test_network(model, local_imagefiles)

			differences = []
			for image_idx, new in enumerate(new_actions):
				new_action_array[image_idx + imgtype_num * num_images].append(new.tolist())
				differences.append(new.tolist() - orig_actions[image_idx])

			# remove the 'forward' action, just focusing on the turns
			differences = np.array(differences)[:, 1:]
			# calculate the mean across all the images (in the group)
			# trial_results[mask_num][imgtype_num] = np.mean(differences, axis=0).tolist()
			trial_results[mask_num][imgtype_num] = np.array(new_actions)[:, 1:].tolist()
			all_differences.append(differences)

	action_max = np.max(np.abs(np.array(all_differences)))

	# visualize the new actions compared to the old
	# with PdfPages(re.sub('\..+', '.pdf', network_file_path)) as pdf:
	# 	for image_idx, image_filename in enumerate(image_file_list):

	# 		old_action = orig_actions[image_idx]
	# 		new_actions = new_action_array[image_idx]

	# 		# calculate the norm between each new action and the old action for coloring
	# 		differences = [[0, 0, 0]]
	# 		for new in new_actions:
	# 			differences.append(new - old_action)

	# 		actions = np.delete(np.array([old_action] + new_actions), 0, axis=1)
	# 		differences =  np.delete(np.array(differences), 0, axis=1)

	# 		plot_actions(pdf, actions, action_max, "Image " + str(image_idx + 1) + " (" + imagetypes_list[image_idx] + ")", colors=differences)
	# 		plot_actions(pdf, differences, action_max, "Image " + str(image_idx + 1), zero_index=False, y_label='Output Change (Action Space)')

	# for the entire trial, we've calculated the differences between the unmodified network and each network with different parts cut out.
	return (np.array(trial_results), np.array(orig_actions))

def get_colors(labels):
	colors = []
	for i in range(len(labels)):
		colors.append(COLORMAP[(int(labels[i]))])
	return colors

def get_markers(labels):
	# print(labels)
	markers = []
	for i in range(len(labels)):
		markers.append(MARKERMAP[(int(labels[i]))])
	# print(markers)
	return markers

def plot_3_2d(x, colors):
	fig = plt.figure(figsize=plt.figaspect(1/3))
	ax = fig.add_subplot(1, 3, 1)
	ax.scatter(x[:, 0], x[:, 1], c=colors)
	ax.set_xlabel('left')
	ax.set_ylabel('left_rotation')
	ax.set_title(IMAGE_TYPES[0])
	ax = fig.add_subplot(1, 3, 2)
	ax.scatter(x[:, 2], x[:, 3], c=colors)
	ax.set_xlabel('left')
	ax.set_ylabel('left_rotation')
	ax.set_title(IMAGE_TYPES[1])
	ax = fig.add_subplot(1, 3, 3)
	ax.scatter(x[:, 4], x[:, 5], c=colors)
	ax.set_xlabel('left')
	ax.set_ylabel('left_rotation')
	ax.set_title(IMAGE_TYPES[2])

	plt.show()

def save_plot_2d(filename, x, colors, size=100, markers=None, title='', cluster_centers=None, xlabel=None, ylabel=None):

	setup_matplotlib()
	fig = plt.figure(figsize=(1024/128, 1024/128), dpi=128)

	if len(x[0]) > 2: # use pca to remove extra dims
		pca = PCA(n_components=2)
		x = pca.fit_transform(x)
		xlabel = 'First Principal Component'
		ylabel = 'Second Principal Component'

	colors = np.array(colors)

	ax = fig.add_subplot(1, 1, 1)
	if markers is None:
		ax.scatter(x[:, 0], x[:, 1], c=colors, s=size)
	else:
		for m in np.unique(markers):
			this_trial = [m == mark for mark in markers]
			ax.scatter(x[this_trial, 0], x[this_trial, 1], c=colors[this_trial], marker=m, s=size)

	ax.set_xlabel(xlabel)
	ax.set_ylabel(ylabel)
	ax.set_title(title)

	if cluster_centers is not None:
		xlim = ax.get_xlim()
		ylim = ax.get_ylim()

		cluster_centers = pca.transform(cluster_centers)

		vor = Voronoi(cluster_centers)
		regions, vertices = voronoi_finite_polygons_2d(vor, 10)

		for region in regions:
			polygon = vertices[region]
			plt.fill(*zip(*polygon), alpha=0.15)

		plt.xlim(xlim)
		plt.ylim(ylim)

	plt.savefig(filename, dpi=128)

def plot_3d(x_list, c_list, t_list, use_pca):
	if len(x_list) != len(c_list) or len(c_list) != len(t_list):
		print('plot_3d: Length of x, color, and title lists must be the same')

	if len(x_list) > 1:
		fig = plt.figure(figsize=plt.figaspect(1 / len(x_list)))
	else:
		fig = plt.figure(figsize=(1024, 1024))

	for i, (x, colors, title) in enumerate(zip(x_list, c_list, t_list)):
		ax = fig.add_subplot(1, len(x_list), i+1, projection='3d')
		ax.scatter(x[:, 0], x[:, 1], x[:, 2], c=colors)
		if not use_pca:
			ax.set_xlabel(IMAGE_TYPES[0])
			ax.set_ylabel(IMAGE_TYPES[1])
			ax.set_zlabel(IMAGE_TYPES[2])
		ax.set_title(title)

	plt.show()

def plot_results(x, cluster_labels, trial_labels, cluster_centers=None, use_pca=True):
	setup_matplotlib()

	cluster_colors = get_colors(cluster_labels)
	trial_colors = get_colors(trial_labels)
	trial_markers = get_markers(trial_labels)

	if use_pca:
		pca = PCA(n_components=3)
		x_pca = pca.fit_transform(x)
		# print(pca.explained_variance_ratio_.cumsum())
		# print(pca.components_)
	else:
		x = np.mean(x.reshape(len(trial_colors), 6, num_images), axis=2)

	if use_pca:
		x_list = [x_pca, x_pca]
		c_list = [cluster_colors, trial_colors]
		t_list = ['cluster labels', 'trial labels']
	else:
		# plot_3_2d(x, cluster_colors)
		# plot_3_2d(x, trial_colors)

		x_list = [x[:, :3], x[:, :3], x[:, 3:], x[:, 3:]]
		c_list = [cluster_colors, trial_colors, cluster_colors, trial_colors]
		t_list = ['cluster labels, x 0-2', 'trial labels, x 0-2', 'cluster labels, x 3-6', 'trial labels, x 3-6']

	# plot_3d(x_list, c_list, t_list, use_pca)
	save_plot_2d('graphs/network_knife_ours.png', x, cluster_colors, markers=trial_markers, cluster_centers=cluster_centers)

def match_data(trial_results_arr, orig_actions_arr, trials):
	# print(np.array(trial_results_arr).shape)
	NUM_TRIALS = len(trials)
	# num_clusters = 6 # value of 6 always gets the highest silhouette score

	trial_labels = np.zeros((NUM_TRIALS, NUM_SLICES))
	for i in range(NUM_TRIALS):
		trial_labels[i, :] = i
	trial_labels = trial_labels.reshape(NUM_TRIALS * NUM_SLICES,)

	trial_results_arr = np.array(trial_results_arr).reshape(NUM_TRIALS * NUM_SLICES, 6 * num_images)
	trial_results_scaled = np.copy(trial_results_arr)

	for trial_num in range(NUM_TRIALS):
		trial_results_scaled[trial_labels == trial_num] -= np.mean(trial_results_scaled[trial_labels == trial_num], axis=0)
		# trial_results_scaled is now centered around the mean
		trial_results_scaled[trial_labels == trial_num] /= np.max(np.abs(trial_results_scaled[trial_labels == trial_num]), axis=0)
		# trial_results_scaled is now between 1 and -1

	# print("silhouette scoring")
	import random
	clusters_to_check = range(2, 20)
	sh_scores = []
	i = 0
	for random_num in random.sample(range(1, 99999), 10):
		sh_scores.append([])
		for num_clusters in clusters_to_check:
			kmeans = KMeans(n_clusters=num_clusters, random_state=random_num).fit(trial_results_scaled)
			sh = silhouette_score(trial_results_scaled, kmeans.labels_)
			sh_scores[i].append(sh)
		i += 1
	sh_scores = np.mean(np.array(sh_scores), axis=0)
	# print(sh_scores)
	max_score = np.max(sh_scores)
	num_clusters = clusters_to_check[sh_scores.tolist().index(max_score)]
	# print(max_score, num_clusters)

	kmeans = KMeans(n_clusters=num_clusters, random_state=23588).fit(trial_results_scaled)
	cluster_labels = kmeans.labels_
	cluster_centers = kmeans.cluster_centers_

	# print(np.column_stack((trial_labels, cluster_labels)))

	plot_results(trial_results_scaled, cluster_labels, trial_labels, cluster_centers=cluster_centers, use_pca=True)

	# calculate stats for each cluster
	# print("Scaled:", trial_results_scaled.shape)
	x = []
	for i in range(num_clusters):
		cluster_data = trial_results_scaled[
			(cluster_labels == i)
		 	# & (trial_labels  == 0)
		 ]
		if len(cluster_data) > 0:
			avg = np.mean(cluster_data, axis=0).reshape(3, num_images, 2)
			avg = np.mean(avg, axis=(0, 1))
			x.append(avg)
			# print('cluster', i)
			# print(avg)
		else:
			print('cluster', i, 'empty')
	x = np.stack(x)
	# print(x)
	save_plot_2d('graphs/network_knife_clusters.png', x, get_colors(range(num_clusters)),
		size=200, xlabel='Lateral Action', ylabel='Rotational Action')

if __name__ == "__main__":

	trial_results_arr = []
	orig_actions_arr = []
	trials = []

	if len(sys.argv) < 2 or '-s' not in sys.argv:

		K.set_learning_phase(0)
		actor_model = Factory.actor_network(STATE_DIMENSIONS)

		for network_file_path in glob.iglob('test_networks/' + FILENAME_PATTERN + '*.h5'):
			# extract the trial number from the filename
			trial_num = int(re.search(r'\d+', re.sub('.*(\\\/)', '', network_file_path)).group(0))

			# test the network!
			trial_results, orig_actions = test_network_knife(actor_model, network_file_path, image_file_list, image_type_list)

			trial_results_arr.append(trial_results)
			orig_actions_arr.append(orig_actions)

			trials.append(trial_num)

		with open("trial_results.p", "wb") as tr:
			pkl.dump((trial_results_arr, orig_actions_arr, trials), tr, protocol=pkl.HIGHEST_PROTOCOL)

		K.clear_session()

	else:
		with open("trial_results.p", "rb") as tr:
			trial_results_arr, orig_actions_arr, trials = pkl.load(tr)

	match_data(trial_results_arr, orig_actions_arr, trials)


import datetime
import pandas as pd
import matplotlib.pyplot as plt
import io
import openpyxl
import scatter

import matplotlib

plt.rcParams['font.family'] = "MS Gothic"

times = ("00:00:00", "03:00:00", "03:00:01", "09:00:15", "02:59:12", "23:59:59")
data1 = [[datetime.datetime.fromisoformat(f"2021-04-20 {t}.000000"), i] for i, t in enumerate(times)]
df1 = pd.DataFrame(data1, columns=['date', 'value'])

times = ("09:12:03", "02:14:50", "20:00:01", "22:33:15")
data2 = [[datetime.datetime.fromisoformat(f"2021-04-20 {t}.000000"), i+3] for i, t in enumerate(times)]
df2 = pd.DataFrame(data2, columns=['date', 'value'])

#fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(9, 6))

fig = plt.figure()
ax = fig.add_subplot(111, xlabel='時刻', ylabel='値')

scatter.init(ax)

scatter.ax_scatter(ax, df1['date'].to_list(), df1['value'].to_list(), "a")
scatter.ax_scatter(ax, df2['date'].to_list(), df2['value'].to_list(), "b")

#scatter.df_scatter(df1, ax, 'date', 'value', "a")
#scatter.df_scatter(df2, ax, 'date', 'value', "b")

wb = openpyxl.Workbook()
ws = wb.active

img_data = io.BytesIO()
fig.savefig(img_data, format='png')
img = openpyxl.drawing.image.Image(img_data)
ws.add_image(img, 'A1')

#plt.show()
wb.save("out.xlsx")