import matplotlib.pyplot as plt
import numpy as np

class Car:
    def __init__(self, preferred_speed, init_node, preferred_gap, init_speed, acceleration, delay, lane, start_time):
        self.preferred_speed = preferred_speed
        self.location = init_node
        self.preferred_gap = preferred_gap
        self.speed = init_speed
        self.acceleration = acceleration
        self.decision_delay = delay
        self.current_lane = lane
        self.start_time = start_time
        self.decision_time = 0
        self.want_to_change_lanes = 0
        self.location_history = []
        self.speed_history = []

    def next_speed(self, time_step, next_car):
        next_location = next_car.location if (next_car and next_car.location) else np.inf
        next_speed = next_car.speed if next_car else np.inf
        speed_to_test = self.speed + (self.preferred_speed - self.speed) * self.acceleration * time_step
        next_speed_to_test = self.speed + (next_speed - self.speed) * self.acceleration * time_step
        if self.location is not None:
            if self.location + speed_to_test * time_step + self.preferred_gap < next_location:
                speed = speed_to_test
            elif self.location + next_speed_to_test * time_step + self.preferred_gap < next_location:
                speed = next_speed_to_test
            elif self.location + self.preferred_gap > next_location:
                speed = 0
            else:
                speed = (next_location - self.location - self.preferred_gap) / time_step
            if np.random.rand() < 0.05:
                speed = int(0.9*speed)
            self.speed_history.append(speed)
            self.speed = speed
        else:
            self.speed = 0

    def next_location(self, time_step, length, car_ahead, car_behind, max_lanes):
        if self.location is not None:
            if (max_lanes > 1) and self.want_to_change_lanes != 0:
                if self.decision_time < self.decision_delay:
                    self.decision_time += time_step
                    next_location = self.location + time_step * self.speed
                    if next_location < length:
                        self.location = next_location
                    else:
                        self.location = None
                else:
                    self.current_lane += self.want_to_change_lanes
                    self.want_to_change_lanes = 0
                    next_location = self.location
            elif max_lanes > 1:
                self.decide_to_change_lanes(car_ahead, car_behind, max_lanes)
                next_location = self.location + time_step * self.speed
                if next_location < length:
                    self.location = next_location
                else:
                    self.location = None
            else:
                self.want_to_change_lanes = 0
                next_location = self.location + time_step * self.speed
                if next_location < length:
                    self.location = next_location
                else:
                    self.location = None
            self.location_history.append(next_location)
        else:
            self.location = None

    def decide_to_change_lanes(self, car_ahead, car_behind, max_lanes):
        if car_ahead and (max_lanes > self.current_lane + 1) and (car_ahead.speed < self.preferred_speed):
            self.want_to_change_lanes = 1
            self.decision_time = 0
        elif car_behind and (car_behind.location + self.preferred_gap > self.location) and (self.current_lane > 0):
            self.want_to_change_lanes = -1
            self.decision_time = 0
        else:
            self.want_to_change_lanes = 0

    def change_lanes(self, road):
        pass

    def __str__(self):
        return "location: "+str(self.location)+", speed: "+str(self.speed)

    def __repr__(self):
        return "car at "+str(self.location)+" going "+str(self.speed)

class Road:
    def __init__(self, length, number_of_cells, max_speed, num_of_lanes):
        self.length = length
        self.number_of_cells = number_of_cells
        self.max_speed = max_speed
        self.num_of_lanes = num_of_lanes
        self.cell_size = length / number_of_cells

    def get_number_of_cells(self):
        return self.number_of_cells

    def get_max_speed(self):
        return self.max_speed

    def get_cell_by_location(self, location):
        return self.cell_size % location

    def get_max_lanes(self):
        return self.num_of_lanes

class Simulation:
    def __init__(self, road_length, arrival_rate, average_speed, average_gap, average_init_speed, average_acceleration, average_delay):
        """
        :param road_length: road length in "location" or "speed/time" units
        :param arrival_rate: fraction of iterations duting which a new car is added (i.e. 0.5=~every second step)
        :param average_speed: The center of car speed distribution
        :param average_gap: The center of preferred gap distribution
        :param average_init_speed: The average speed with which a car enters the game
        :param average_acceleration: The center of acceleration distribution
        :param average_delay:
        """
        self.road_length = road_length
        self.arrival_rate = arrival_rate
        self.average_speed = average_speed
        self.average_gap = average_gap
        self.average_init_speed = average_init_speed
        self.average_acceleration = average_acceleration
        self.average_delay = average_delay

    @staticmethod
    def update_speeds(cars, time_step):
        for num, car in enumerate(cars):
            if (len(cars) >= 1) and (num > 0):
                next_car = cars[num-1]
            else:
                next_car = None
            car.next_speed(time_step, next_car)

    @staticmethod
    def determine_cars_around(num, cars):
        if (len(cars) > 2) and (num > 0) and (num < (len(cars)-1)):
            car_ahead = cars[-num]
            car_behind = cars[-num - 2]
        elif (len(cars) > 2) and (num > 0) and (num == (len(cars)-1)):
            car_ahead = cars[-num]
            car_behind = None
        elif (len(cars) > 2) and (num == 0):
            car_ahead = None
            car_behind = cars[-num - 2]
        elif len(cars) == 2 and num == 1:
            car_ahead = None
            car_behind = cars[0]
        elif len(cars) == 2 and num == 0:
            car_ahead = cars[1]
            car_behind = None
        else:
            car_ahead = None
            car_behind = None
        return car_ahead, car_behind

    def move(self, cars, time_step, length, max_lanes, moving_lane):
        cars_to_move = []
        for num, car in enumerate(cars[moving_lane][::-1]):
            if car.location is not None:
                car_ahead, car_behind = self.find_car_by_location(cars[moving_lane], car.location)
                old_lane = car.current_lane
                car.next_location(time_step, length, car_ahead, car_behind, max_lanes)
                new_lane = car.current_lane
                if old_lane != new_lane:
                    cars_to_move.append(cars[moving_lane].index(car))
        for c2m in cars_to_move:
            car_to_be_moved = cars[moving_lane].pop(c2m)
            new_lane = car_to_be_moved.current_lane
            car_ahead, _ = self.find_car_by_location(cars[new_lane], car_to_be_moved.location)
            if car_ahead:
                new_index = cars[new_lane].index(car_ahead)
                cars[new_lane].insert(new_index,car_to_be_moved)
            else:
                cars[new_lane].append(car_to_be_moved)

    @staticmethod
    def new_car_init(average_preferred_speed, average_gap, avergage_init_speed, average_acceleration,average_delay):
        preferred_speed = max(1, np.random.poisson(average_preferred_speed))
        preferred_gap = np.random.poisson(average_gap)
        init_speed = max(1, np.random.poisson(avergage_init_speed))
        acceleration = max(1, np.random.poisson(average_acceleration))
        delay = np.random.normal(loc=average_delay, scale=0.1)
        if delay < 0.1:
            delay = 0.1
        return preferred_speed, preferred_gap, init_speed, acceleration, delay

    @staticmethod
    def find_car_by_location(cars, location):
        if len(cars) < 2:
            closest_in_front = None
            closest_behind = None
        else:
            distances = [car.location - location if ((location is not None) and (car.location is not None)) else np.inf for car in cars]
            abs_distances = [abs(i) for i in distances]
            min_abs_val = min(abs_distances)
            idx_val = distances.index(min_abs_val) if min_abs_val in distances else distances.index(-min_abs_val)
            min_val = distances[idx_val]
            if (idx_val == 0) and min_val <= 0:
                closest_behind = cars[idx_val+1]
                closest_in_front = None
            elif (idx_val == len(cars) - 1) and (min_val >= 0):
                closest_in_front = cars[idx_val - 1]
                closest_behind = None
            elif min_val > 0:
                closest_in_front = cars[idx_val]
                closest_behind = cars[idx_val+1]
            elif min_val < 0:
                closest_in_front = cars[idx_val-1]
                closest_behind = cars[idx_val]
            else:
                closest_in_front = cars[idx_val - 1]
                closest_behind = cars[idx_val + 1]
        return closest_in_front, closest_behind

    def run(self, number_of_steps, number_of_cells, max_allowed_speed, number_of_lanes, time_step):
        cars = [[] for i in range(number_of_lanes)]
        offsets = []
        time_step = time_step
        arrival_rate = self.arrival_rate
        rd = Road(self.road_length, number_of_cells, max_allowed_speed, number_of_lanes)  # lane = [0]*2000#[Car(2, 0, 0, 0, 1), 0, 0, 0, 0, Car(1, 5, 0, 0, 1), 0, 0, 0]
        # lanes = rd.construct_lane()
        for i in range(number_of_steps):

            if (np.random.rand() < arrival_rate) and (((len(cars[0])) and cars[0][-1].location) or not len(cars[0])):
                preferred_speed, preferred_gap, init_speed, acceleration, delay = self.new_car_init(
                    average_preferred_speed=self.average_speed,
                    average_gap=self.average_gap,
                    avergage_init_speed=self.average_init_speed,
                    average_acceleration=self.average_acceleration,
                    average_delay=self.average_delay)
                new_car = Car(preferred_speed, 0, preferred_gap, init_speed, acceleration, delay, 0, i)
                cars[0].append(new_car)
                # offsets.append(i)
            for j in range(number_of_lanes):
                self.update_speeds(cars[j], time_step)
                self.move(cars, time_step, rd.length, rd.get_max_lanes(), j)
        for j in range(number_of_lanes):
            fig = plt.figure()
            for num, car in enumerate(cars[j]):
                plt.plot(range(car.start_time, car.start_time + len(car.location_history)), car.location_history)
        plt.show()
        print('done')

def define_length(edge, distribution):
    pass

def define_capacity(edge, distribution):
    pass

def setup_network(size, kind, degree_distribution=None):
    pass

def calculate_path(source, target, network):
    pass

def calculate_edge_travel_time(source, target):
    pass

def pick_source(network):
    pass

def pick_destination(network):
    pass

if __name__ == "__main__":
    sim = Simulation(road_length=2000,
                     arrival_rate=0.55,
                     average_speed=15,
                     average_gap=2,
                     average_init_speed=10,
                     average_acceleration=0.5,
                     average_delay=0.5)
    sim.run(number_of_steps=5000, number_of_cells=100, max_allowed_speed=6, number_of_lanes=1, time_step=0.1)


from functions import *
from findError import find_collection_error
import matplotlib.pyplot as plt
from utils import human_format

while True:
    option_input = ''
    print("Choose a function type:")
    options = [
        ['linear', linear],
        ['exponential', exponential],
        ['sinusoidal', sinusoidal],
        ['absolute', absolute],
        ['ellipse', ellipse],
        ['upside down normal', upside_normal],
        ['quadratic', quadratic]
    ]
    for i, option in enumerate(options):
        print(f'{i}: {option[0]}')
    option_input = input()
    try:
        function_name = options[int(option_input)][0]
        chosen_function = options[int(option_input)][1]
        break
    except:
        print('try again.')

number_of_samples = int(input('Number of samples to be generated: '))

single_or_multiple = int(input('Single trial or series? (S: 0, M: 1): '))
if single_or_multiple == 0: # single trial
    sample_size = int(input('Sample size: '))
    find_collection_error(
        chosen_function,
        sample_size,
        number_of_samples,
        plot_graph=True)

else: # mutliple trials
    upper_limit = int(input('Upper limit n: '))+1
    list_of_err = []

    for i in range(1, upper_limit):
        list_of_err.append(
            find_collection_error(
                chosen_function,
                i,
                number_of_samples)
        )

        print(f'{i}/{upper_limit-1} completed...')

    for i, err in enumerate(list_of_err):
        print(f'n={i+1}: P={round(err * 100, 2)}%')

    x = [i for i in range(1,upper_limit)]
    y = [100 * j for j in list_of_err]

    plt.figure(figsize=(8, 5))
    plt.plot(x, y)
    plt.xlabel('n')
    plt.ylabel('% error')
    plt.title(f'% error based on n ({function_name}), {human_format(number_of_samples)} samples')
    plt.grid(True)
    plt.show()


from collections import deque

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

def bfs(self, root):
    queue = deque()

    if root:
        queue.append(root)

    level = 0

    while len(queue):
        print("level: ", level)
        for i in range(len(queue)):
            cur = queue.popLeft()
            print(cur.val)
            if cur.left:
                queue.append(cur.left)
            if cur.right:
                queue.append(cur.right)
        level += 1


##-----------------------------------------------------------------------------
##  Import
##-----------------------------------------------------------------------------
from cv2 import imread
import cv2
from fnc.segment import segment
from fnc.normalize import normalize
from fnc.encode import encode
from PIL import Image

##-----------------------------------------------------------------------------
##  Parameters for extracting feature
##	(The following parameters are default for CASIA1 dataset)
##-----------------------------------------------------------------------------
# Segmentation parameters
eyelashes_thres = 80

# Normalisation parameters
radial_res = 20
angular_res = 240

# Feature encoding parameters
minWaveLength = 18
mult = 1
sigmaOnf = 0.5

##-----------------------------------------------------------------------------
##  Function
##-----------------------------------------------------------------------------
def extractFeature(im_filename, eyelashes_thres=80, use_multiprocess=True):
	"""
	Description:
		Extract features from an iris image

	Input:
		im_filename			- The input iris image
		use_multiprocess	- Use multiprocess to run

	Output:
		template			- The extracted template
		mask				- The extracted mask
		im_filename			- The input iris image
	"""
	# Perform segmentation
	im = imread(im_filename, 0)
	ciriris, cirpupil, imwithnoise = segment(im, eyelashes_thres, use_multiprocess)

	#cv2.imshow("a", imwithnoise)

	# Perform normalization
	polar_array, noise_array = normalize(imwithnoise, ciriris[1], ciriris[0], ciriris[2],
										 cirpupil[1], cirpupil[0], cirpupil[2],
										 radial_res, angular_res)
	#noise_array = noise_array.astype(float)

	cv2.imwrite('polar.jpg', polar_array*255)
	cv2.imwrite('noise.jpg', noise_array.astype(float)*255)
	polar = cv2.imread('polar.jpg')
	noise = cv2.imread('noise.jpg')
	polar = cv2.resize(polar, (polar.shape[1]*5,polar.shape[0]*5))
	noise = cv2.resize(noise, (noise.shape[1]*5,noise.shape[0]*5))
	cv2.imwrite('polar.jpg', polar)
	cv2.imwrite('noise.jpg', noise)
	#cv2.imshow("polar", polar_array)
	#cv2.imshow("noise", noise_array.astype(float))

	# Perform feature encoding
	template, mask = encode(polar_array, noise_array, minWaveLength, mult, sigmaOnf)
	#cv2.imshow('a',template)
	#cv2.imshow('b',mask)
	cv2.imwrite('polar_encode.jpg', template*255)
	cv2.imwrite('noise_encode.jpg', mask.astype(float)*255)
	polar_encode = cv2.imread('polar_encode.jpg')
	noise_encode = cv2.imread('noise_encode.jpg')
	polar_encode = cv2.resize(polar_encode, (polar_encode.shape[1]*5,polar_encode.shape[0]*5))
	noise_encode = cv2.resize(noise_encode, (noise_encode.shape[1]*5,noise_encode.shape[0]*5))
	cv2.imwrite('polar_encode.jpg', polar_encode)
	cv2.imwrite('noise_encode.jpg', noise_encode)
	#cv2.waitKey(0)

	# Return
	return template, mask, im_filename


from typing import Union, Dict

import wikipediaapi

class Wikipedia:
    def __init__(self, query) -> None:
        wiki_wiki = wikipediaapi.Wikipedia("en")
        self.page_py = wiki_wiki.page(query)

    @property
    def get_information(self) -> Union[Dict, bool]:
        try:
            if self.page_py.exists():
                return {"title": self.page_py.title, "summary": self.page_py.summary[0:60]}
            else:
                return False
        except Exception as e:
            print(f"error: {e}")
            return False


from setuptools import setup

with open("README.md", "r", encoding="utf-8") as f_p:
    long_description = f_p.read()

setup(
    name='psda',
    version='1.0.0',
    packages=['psda', 'psda.stats', 'psda.io_data', 'psda.process'],
    license='MIT LICENSE',
    author='Paweł Rajkiewicz',
    author_email='pr382959@students.mimuw.edu.pl',
    description='Polish School Data Analyser is a small package made as a final assignment'
                'in Data in Python course at MIMUW, Spring 20/21.',
    long_description=long_description,
    long_description_content_type="text/markdown",
    install_requires=[
        "pandas>=1.2.5",
        "numpy>=1.21",
        "xlrd>=2.0.1",
        "openpyxl>=3.0.7"
    ],
    python_requires='>=3.8'
)


import torch
import numpy as np
from torch.utils.data import Dataset
import json
from tqdm import tqdm
from arguments import get_args

class DictDataset(Dataset):
    """A dataset of tensors that uses a dictionary for key-value mappings"""
    def __init__(self, **tensors):
        tensors.values()
        assert all(next(iter(tensors.values())).size(0) == tensor.size(0) for tensor in tensors.values())
        self.tensors = tensors

    def __getitem__(self, index):
        return {key: tensor[index] for key, tensor in self.tensors.items()}

    def __len__(self):
        return next(iter(self.tensors.values())).size(0)

    def cuda(self):
        for key in self.tensors:
            self.tensors[key] = self.tensors[key].cuda()

    def cpu(self):
        for key in self.tensors:
            self.tensors[key] = self.tensors[key].cpu()

class REPromptDataset(DictDataset):

    def __init__(self, path = None, name = None, rel2id = None, tokenizer = None, temps = None, features = None):

        with open(rel2id, "r",encoding='utf-8') as f: # 存放的是关系到关系编号的映射
            self.rel2id = json.loads(f.read())
        if not 'NA' in self.rel2id:
            # self.NA_NUM = self.rel2id['没有关系01'] # 用NA_NUM=13表示no_relationd的编号
            self.NA_NUM = 16 # 用NA_NUM=13表示no_relationd的编号
        # else:
        #     self.NA_NUM = self.rel2id['NA']

        self.num_class = len(self.rel2id) # 使用num_class表示关系的数量
        self.temps = temps
        self.get_labels(tokenizer)

        if features is None:
            self.args = get_args()
            with open(path+"/" + name, "r",encoding='utf8') as f:  # 加载数据集train or test or dev
                features = []
                for line in f.readlines():
                    line = line.rstrip()  # {'token': ['Tom', 'Thabane', 'resigned', 'in', 'October', 'last', 'year', 'to', 'form', 'the', 'All', 'Basotho', 'Convention', '-LRB-', 'ABC', '-RRB-', ',', 'crossing', 'the', 'floor', 'with', '17', 'members', 'of', 'parliament', ',', 'causing', 'constitutional', 'monarch', 'King', 'Letsie', 'III', 'to', 'dissolve', 'parliament', 'and', 'call', 'the', 'snap', 'election', '.'], 'h': {'name': 'All Basotho Convention', 'pos': [10, 13]}, 't': {'name': 'Tom Thabane', 'pos': [0, 2]}, 'relation': 'org:founded_by'}
                    if len(line) > 0:
                        features.append(eval(line))  # features存放文本数据列表token,头实体h,尾实体t,关系relasion: [{'token': ['Tom', 'Thabane', 'resigned', 'in', 'October', 'last', 'year', 'to', 'form', 'the', 'All', 'Basotho', 'Convention', '-LRB-', 'ABC', '-RRB-', ',', 'crossing', 'the', 'floor', 'with', '17', 'members', 'of', 'parliament', ',', 'causing', 'constitutional', 'monarch', 'King', 'Letsie', 'III', 'to', 'dissolve', 'parliament', 'and', 'call', 'the', 'snap', 'election', '.'], 'h': {'name': 'All Basotho Convention', 'pos': [10, 13]}, 't': {'name': 'Tom Thabane', 'pos': [0, 2]}, 'relation': 'org:founded_by'}]
            features = self.list2tensor(features, tokenizer)

        super().__init__(**features)  # super().__init__()，就是继承父类的init方法

    def get_labels(self, tokenizer):
        """
        输入：
            tokenizer： 编码器
        过程：
            构建 temp_ids{}:
            构建 set[]:
            构建 prompt_id_2_label[]:
            构建 prompt_label_idx[]:
        输出：null
        """
        total = {}
        self.temp_ids = {}

        for name in self.temps: # 按照每个模板进行循环 name；'per:charges'
            last = 0
            self.temp_ids[name] = {}
            self.temp_ids[name]['label_ids'] = []
            self.temp_ids[name]['mask_ids'] = []

            for index, temp in enumerate(self.temps[name]['temp']):  # 对每个子提示进行循环 index：0 temp:['the', '<mask>']
                _temp = temp.copy() # _temp=['the', '<mask>']
                _labels = self.temps[name]['labels'][index]  #  _labels=person
                _labels_index = [] # 记录label的索引，也就是[mask]的位置索引 _labels_index=[1]

                for i in range(len(_temp)):
                    if _temp[i] == tokenizer.mask_token:
                        _temp[i] = _labels[len(_labels_index)] # _labels只存放label 所以此时_temp的[MASK]变成了person _temp=['the', 'person']
                        _labels_index.append(i)

                # original = tokenizer.encode(" ".join(temp), add_special_tokens=False) # temp=['the', '<mask>'] 的单词编号 original=[627, 50264]
                # final =  tokenizer.encode(" ".join(_temp), add_special_tokens=False) # _temp=['the', 'person'] 的单词编号 final=[627, 621]
                original = tokenizer.encode(temp,add_special_tokens=False)  # temp=['the', '<mask>'] 的单词编号 original=[627, 50264]
                final = tokenizer.encode(_temp,add_special_tokens=False)  # _temp=['the', 'person'] 的单词编号 final=[627, 621]
                print("\n_temp:",_temp)
                print("original----------",original)
                print("final-------------",final)
                # print(tokenizer.encode(["'s"], add_special_tokens=False))
                # print(tokenizer.encode(["'s", 'relative'], add_special_tokens=False))
                # print(tokenizer.encode(["'s", 'relative', 'is'], add_special_tokens=False))
                # original = tokenizer.encode(temp,add_special_tokens=False)  # temp=['the', '<mask>'] 的单词编号 original=[627, 50264]
                # final = tokenizer.encode(_temp,add_special_tokens=False)  # _temp=['the', 'person'] 的单词编号 final=[627, 621]

                # assert（断言）用于判断一个表达式，在表达式条件为 false 的时候触发异常。断言可以在条件不满足程序运行的情况下直接返回错误。
                assert len(original) == len(final)
                self.temp_ids[name]['label_ids'] += [final[pos] for pos in _labels_index]  # temp_ids[name]['label_ids']中存放标签词label的编号

                for pos in _labels_index:
                    if not last in total:
                        total[last] = {}
                    total[last][final[pos]] = 1 # total={0: {621: 1}} 存放子模板的标签标号和1   -->第二轮 {0: {621: 1}, 1: {7325: 1}, 2: {1340: 1}, 3: {19: 1}} -->第三轮 {0: {621: 1}, 1: {7325: 1}, 2: {1340: 1}, 3: {19: 1}, 4: {515: 1}}
                    last+=1   # last用来存储此时加入total的是一个句子中的第几个标签词
                self.temp_ids[name]['mask_ids'].append(original)  # temp_ids[name]['mask_ids']存放['the', '<mask>'] 的单词编号 original=[627, 50264]

        print (total) # total里存放的是模板中每个位置对应会出现所有label的编号 ，一共有5个类型对应0，1，2，3，4的mask
        """{0: {621: 1, 1651: 1, 10014: 1},
            1: {7325: 1, 18: 1, 354: 1},
            2: {1340: 1, 962: 1, 4790: 1, 2421: 1, 5221: 1, 5407: 1, 1270: 1, 25385: 1, 2034: 1, 1207: 1, 919: 1, 8850: 1, 334: 1, 3200: 1, 21771: 1, 17117: 1, 4095: 1, 920: 1, 29853: 1, 8540: 1, 26241: 1, 998: 1, 1046: 1, 21821: 1},
            3: {19: 1, 15: 1, 11: 1, 9: 1, 30: 1, 16: 1, 21: 1, 34: 1, 7: 1},
            4: {515: 1, 1248: 1, 247: 1, 621: 1, 343: 1, 194: 1, 1270: 1, 1651: 1, 6825: 1, 346: 1, 46471: 1, 10014: 1}}"""
        self.set = [(list)((sorted)(set(total[i]))) for i in range(len(total))]
        """set=[[621, 1651, 10014],
                [18, 354, 7325],
                [334, 919, 920, 962, 998, 1046, 1207, 1270, 1340, 2034, 2421, 3200, 4095, 4790, 5221, 5407, 8540, 8850, 17117, 21771, 21821, 25385, 26241, 29853],
                [7, 9, 11, 15, 16, 19, 21, 30, 34],
                [194, 247, 343, 346, 515, 621, 1248, 1270, 1651, 6825, 10014, 46471]]"""
        print ("=================================")
        for i in self.set:
            print (i)
        print ("=================================")

        for name in self.temp_ids: # temp_ids={'per:charges': {'label_ids': [0, 7325, 1340, 19, 515], 'mask_ids': [[627, 50264], [50264, 50264, 50264], [627, 50264]]}, 'per:date_of_death': {'label_ids': [621, 7325, 962, 15, 1248], 'mask_ids': [[627, 50264], [50264, 50264, 50264], [627, 50264]]},
            for j in range(len(self.temp_ids[name]['label_ids'])):
                self.temp_ids[name]['label_ids'][j] = self.set[j].index(
                    self.temp_ids[name]['label_ids'][j])  # 将temp_ids[name]['label_ids']中的标签label编号改为其在set数组中的位置编号 ：'label_ids': [1651, 7325, 5221, 30, 621] --》'label_ids': [1, 2, 14, 7, 5]

        self.prompt_id_2_label = torch.zeros(len(self.temp_ids), len(self.set)).long() # 一个（12，5）的0矩阵

        for name in self.temp_ids:
            for j in range(len(self.prompt_id_2_label[self.rel2id[name]])):  # 当name='per:date_of_death'时，self.rel2id[name]=2  len(self.prompt_id_2_label[self.rel2id[name]])一直等于5
                self.prompt_id_2_label[self.rel2id[name]][j] = self.temp_ids[name]['label_ids'][j] # 模板每个位置对应的该位置能出现的label编号 prompt_id_2_label[][]用来按照rel2id里的顺序存放temp_ids[name]['label_ids'],一个temp_ids[name]['label_ids']为一行

        if (get_args().select_device == "cpu"):
            self.prompt_id_2_label = self.prompt_id_2_label.long().cpu()
        else:
            self.prompt_id_2_label = self.prompt_id_2_label.long().cuda()

        self.prompt_label_idx = [torch.Tensor(i).long() for i in self.set]  # prompt_label_idx 是 set的tensor形式
        """"[tensor([621,1651, 10014]),
            tensor([18,354, 7325]),
            tensor([334, 919, 920, 962, 998,1046,1207,1270,1340,2034, 2421,3200,4095,4790,5221,5407,8540,8850, 17117, 21771,21821, 25385, 26241, 29853]),
            tensor([ 7,9, 11, 15, 16, 19, 21, 30, 34]),
            tensor([194, 247, 343, 346, 515, 621,1248,1270,1651,6825,10014, 46471])]"""

    def save(self, path = None, name = None):
        path = path + "/" + name  + "/"
        np.save(path+"input_ids", self.tensors['input_ids'].numpy())
        np.save(path+"token_type_ids", self.tensors['token_type_ids'].numpy())
        np.save(path+"attention_mask", self.tensors['attention_mask'].numpy())
        np.save(path+"labels", self.tensors['labels'].numpy())
        np.save(path+"mlm_labels", self.tensors['mlm_labels'].numpy())
        np.save(path+"input_flags", self.tensors['input_flags'].numpy())
        # np.save(path+"prompt_label_idx_0", self.prompt_label_idx[0].numpy())
        # np.save(path+"prompt_label_idx_1", self.prompt_label_idx[1].numpy())
        # np.save(path+"prompt_label_idx_2", self.prompt_label_idx[2].numpy())

    @classmethod  # 一般来说，要使用某个类的方法，需要先实例化一个对象再调用方法。而使用@staticmethod或@classmethod，就可以不需要实例化，直接类名.方法名()来调用。这有利于组织代码，把某些应该属于某个类的函数给放到那个类里去，同时有利于命名空间的整洁。
    def load(cls, path = None, name = None, rel2id = None, temps = None, tokenizer = None):
        path = path + "/" + name  + "/"
        features = {}
        features['input_ids'] = torch.Tensor(np.load(path+"input_ids.npy")).long()
        features['token_type_ids'] = torch.Tensor(np.load(path+"token_type_ids.npy")).long()
        features['attention_mask'] = torch.Tensor(np.load(path+"attention_mask.npy")).long()
        features['labels'] = torch.Tensor(np.load(path+"labels.npy")).long()
        features['input_flags'] = torch.Tensor(np.load(path+"input_flags.npy")).long()
        features['mlm_labels'] = torch.Tensor(np.load(path+"mlm_labels.npy")).long()
        res = cls(rel2id = rel2id, features = features, temps = temps, tokenizer = tokenizer)
        # res.prompt_label_idx = [torch.Tensor(np.load(path+"prompt_label_idx_0.npy")).long(),
        #     torch.Tensor(np.load(path+"prompt_label_idx_1.npy")).long(),
        #     torch.Tensor(np.load(path+"prompt_label_idx_2.npy")).long()
        # ]
        return res

    def list2tensor(self, data, tokenizer):
        """输入：
            data:一条数据 [{'token': ['Tom', 'Thabane', 'resigned', ... , '.'], 'h': {'name': 'All Basotho Convention', 'pos': [10, 13]}, 't': {'name': 'Tom Thabane', 'pos': [0, 2]}, 'relation': 'org:founded_by'}]
            tokenizer:模型编码器
        过程：
            对上一步计算出的：input_ids[],token_type_ids[],attention_mask[],input_flags[] 进行补齐
            构建labels：表示关系对应的编号
            构建mlm_labels[]：[MASK]对应位置填1，其余位置填-1
        输出：
            res{}={'input_ids': [], 'token_type_ids': [], 'attention_mask': [], 'input_flags': [], 'mlm_labels': [], 'labels': []}
        """
        """'input_ids': [array([  0, 15691,  2032,   873,  1728,  6490,    11,   779,    94,
                                      76,     7,  1026,     5,   404,  7093,  6157,   139,  9127,
                                     111,   574, 26770,    12,  3943,   111, 25733,   387,    12,
                                    2156,  6724,     5,  1929,    19,   601,   453,     9,  3589,
                                    2156,  3735,  6100, 20303,  1745, 40702,   324,  6395,     7,
                                   30887,  3589,     8,   486,     5,  6788,   729,   479,   627,
                                   50264,   404,  7093,  6157,   139,  9127, 50264, 50264, 50264,
                                     627, 50264,  1560,  2032,   873,  1728,     2,     1,     1,
                                       1,     1,     1,     1,     1,     1,     1,     1,     1,
                                       1,     1,     1,     1,     1,     1,     1,     1, ...])]单词编号和 PAD:1
                'token_type_ids': [array([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...])]全0 同'input_flags':
                'attention_mask': [array([ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                                           1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                                           1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                                           1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...])]前1后0
                'mlm_labels': [array([ -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1.,
                                       -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1.,
                                       -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1.,
                                       -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1.,
                                       -1., -1.,  1., -1., -1., -1., -1., -1.,  1.,  1.,  1., -1.,  1.,
                                       -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1.,...])] [MASK]1 其余-1
                'labels': [array(41)]"""
        res = {}  # {'input_ids': [], 'token_type_ids': [], 'attention_mask': [], 'input_flags': [], 'mlm_labels': [], 'labels': []}
        res['input_ids'] = []
        res['token_type_ids'] = []
        res['attention_mask'] = []
        res['input_flags'] = []
        res['mlm_labels'] = []
        res['labels'] = []

        for index, i in enumerate(tqdm(data)):
            input_ids, token_type_ids, input_flags = self.tokenize(i, tokenizer)  # 根据句子的头尾实体组装prompt模板
            attention_mask = [1] * len(input_ids)  # attention_mask=[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
            padding_length = self.args.max_seq_length - len(input_ids)  # padding_length=512-70=442

            if padding_length > 0:  # 对 input_ids的 PAD进行填充，其中tokenizer.pad_token_id=1
                input_ids = input_ids + ([tokenizer.pad_token_id] * padding_length)
                attention_mask = attention_mask + ([0] * padding_length)  # attention_mask=[1*70,0*442]
                token_type_ids = token_type_ids + ([0] * padding_length)  # token_type_ids,input_flags=[0*512]
                input_flags = input_flags + ([0] * padding_length)

            assert len(input_ids) == self.args.max_seq_length
            assert len(attention_mask) == self.args.max_seq_length
            assert len(token_type_ids) == self.args.max_seq_length
            assert len(input_flags) == self.args.max_seq_length

            label = self.rel2id[i['relation']]  # label表示关系对应的编号 rel2id['org:founded_by']=41
            res['input_ids'].append(np.array(input_ids))
            res['token_type_ids'].append(np.array(token_type_ids))
            res['attention_mask'].append(np.array(attention_mask))
            res['input_flags'].append(np.array(input_flags))
            res['labels'].append(np.array(label))
            mask_pos = np.where(res['input_ids'][-1] == tokenizer.mask_token_id)[
                0]  # res['input_ids']中编号为[MASK]的编号50264的位置
            mlm_labels = np.ones(self.args.max_seq_length) * (-1)  # mlm_labels=[-1*512]
            mlm_labels[mask_pos] = 1  # 将mlm_labels中的mask_pos位置设置为1
            res['mlm_labels'].append(mlm_labels)
        for key in res:
            res[key] = np.array(res[key])
            res[key] = torch.Tensor(res[key]).long()
        return res

    # 组装prompt
    def tokenize(self, item, tokenizer): # {'token': ['Tom', 'Thabane', 'resigned', 'in', 'October', 'last', 'year', 'to', 'form', 'the', 'All', 'Basotho', 'Convention', '-LRB-', 'ABC', '-RRB-', ',', 'crossing', 'the', 'floor', 'with', '17', 'members', 'of', 'parliament', ',', 'causing', 'constitutional', 'monarch', 'King', 'Letsie', 'III', 'to', 'dissolve', 'parliament', 'and', 'call', 'the', 'snap', 'election', '.'], 'h': {'name': 'All Basotho Convention', 'pos': [10, 13]}, 't': {'name': 'Tom Thabane', 'pos': [0, 2]}, 'relation': 'org:founded_by'}
        """
        输入：
            item： 文本数据，形式为{'token': [], 'h': {'name': '', 'pos': []}, 't': {'name': '', 'pos': []}, 'relation': 'org:founded_by'}
            tokenizer： 编码器
        过程：
            组装prompt[]: prompt=temp_ids[rel_name]['mask_ids'][0] + e1 + self.temp_ids[rel_name]['mask_ids'][1] + self.temp_ids[rel_name]['mask_ids'][2] + e2
                temp_ids[rel_name]['mask_ids'][0]     = [627, 50264]
                e1：头实体编码                           = [404, 7093, 6157, 139, 9127]
                self.temp_ids[rel_name]['mask_ids'][1]= [50264, 50264, 50264]
                self.temp_ids[rel_name]['mask_ids'][2]= [627, 50264]
                e2：尾实体编码                           = [1560, 2032, 873, 1728]
                prompt='the [MASK]' + 'token_id(e1)' + '[MASK] [MASK] [MASK]' + 'the [MASK]' + 'token_id(e2)'
                prompt=[627, 50264]+[404, 7093, 6157, 139, 9127]+[50264, 50264, 50264]+[627, 50264]+[1560, 2032, 873, 1728]
        输出：
            input_ids[]：使用原始句子和模板组装：input_ids=[cls]+sentence+prompt+[sep]，使用单词对应索引表示
            token_type_ids[]：[0*70]
            input_flags[]：[0*70]
        """
        sentence = item['token']  # sentence=['Tom', 'Thabane', 'resigned', 'in', 'October', 'last', 'year', 'to', 'form', 'the', 'All', 'Basotho', 'Convention', '-LRB-', 'ABC', '-RRB-', ',', 'crossing', 'the', 'floor', 'with', '17', 'members', 'of', 'parliament', ',', 'causing', 'constitutional', 'monarch', 'King', 'Letsie', 'III', 'to', 'dissolve', 'parliament', 'and', 'call', 'the', 'snap', 'election', '.']
        pos_head = item['h']  # {'name': 'All Basotho Convention', 'pos': [10, 13]}
        pos_tail = item['t']  # {'name': 'Tom Thabane', 'pos': [0, 2]}
        rel_name = item['relation']  # 'org:founded_by'

        temp = self.temps[rel_name]  # 'org:founded_by' 对应的模板 {'name': 'org:founded_by', 'temp': [['the', '<mask>'], ['<mask>', '<mask>', '<mask>'], ['the', '<mask>']], 'labels': [('organization',), ('was', 'founded', 'by'), ('person',)]}

        sentence = " ".join(sentence) # 将句子拼起来 sentence='Tom Thabane resigned in October last year to form the All Basotho Convention -LRB- ABC -RRB- , crossing the floor with 17 members of parliament , causing constitutional monarch King Letsie III to dissolve parliament and call the snap election .'
        sentence = tokenizer.encode(sentence, add_special_tokens=False)  # sentence中的单词转变成单词编码 长度变为52？？？？根据使用模型的不同其分词会有区别 cuting--》'cut', '##ing' sentence=[15691, 2032, 873, 1728, 6490, 11, 779, 94, 76, 7, 1026, 5, 404, 7093, 6157, 139, 9127, 111, 574, 26770, 12, 3943, 111, 25733, 387, 12, 2156, 6724, 5, 1929, 19, 601, 453, 9, 3589, 2156, 3735, 6100, 20303, 1745, 40702, 324, 6395, 7, 30887, 3589, 8, 486, 5, 6788, 729, 479]
        # e1 = tokenizer.encode( pos_head['name'], add_special_tokens=False)[1:]  # 'was All Basotho Convention'的编码  e1：头实体编码 =[404, 7093, 6157, 139, 9127]
        # e2 = tokenizer.encode( pos_tail['name']+"的", add_special_tokens=False)[1:]  # 'was Tom Thabane'的编码  e2：尾实体编码 =[1560, 2032, 873, 1728]
        # prompt = e1 + self.temp_ids[rel_name]['mask_ids'][0] + e2 + self.temp_ids[rel_name]['mask_ids'][1]    # rel_name = 'org:founded_by'

        if (get_args().data_dir == "../datasets/diakg_temp1" or get_args().data_dir == "../datasets/CMeIE_temp1"):
            # β细胞胰岛素分泌功能已开始逐渐下降(2b级)[MASK][MASK][MASK][MASK][MASK]糖尿病的[MASK][MASK][MASK][MASK]。
            e1 = tokenizer.encode(pos_head['name'], add_special_tokens=False)  # 'was All Basotho Convention'的编码  e1：头实体编码 =[404, 7093, 6157, 139, 9127]
            e2 = tokenizer.encode(pos_tail['name']+"的", add_special_tokens=False)  # 'was Tom Thabane'的编码  e2：尾实体编码 =[1560, 2032, 873, 1728]
            prompt = e1 + self.temp_ids[rel_name]['mask_ids'][0] + e2 + self.temp_ids[rel_name]['mask_ids'][1]  # rel_name = 'org:founded_by'
        # elif (get_args().data_dir == "../datasets/diakg_temp2"):
        #     # β细胞胰岛素分泌功能已开始逐渐下降(2b级)是[MASK][MASK][MASK][MASK]糖尿病的[MASK][MASK][MASK][MASK]。
        #     e1 = tokenizer.encode(pos_head['name'] + "的",add_special_tokens=False)  # 'was All Basotho Convention'的编码  e1：头实体编码 =[404, 7093, 6157, 139, 9127]
        #     e2 = tokenizer.encode(pos_tail['name'] + "是",add_special_tokens=False)  # 'was Tom Thabane'的编码  e2：尾实体编码 =[1560, 2032, 873, 1728]
        #     prompt = e2 + self.temp_ids[rel_name]['mask_ids'][0] + e1 + self.temp_ids[rel_name]['mask_ids'][1]  # rel_name = 'org:founded_by'
        # elif (get_args().data_dir == "../datasets/CMeIE"):
        #     # 糖尿病是[MASK][MASK][MASK][MASK]。β细胞胰岛素分泌功能已开始逐渐下降(2b级)是[MASK][MASK][MASK][MASK]。
        #     e1 = tokenizer.encode(pos_head['name'] + "是",add_special_tokens=False)  # 'was All Basotho Convention'的编码  e1：头实体编码 =[404, 7093, 6157, 139, 9127]
        #     e2 = tokenizer.encode("。" + pos_tail['name'] + "是",add_special_tokens=False)  # 'was Tom Thabane'的编码  e2：尾实体编码 =[1560, 2032, 873, 1728]
        #     prompt = e1 + self.temp_ids[rel_name]['mask_ids'][0] + e2 + self.temp_ids[rel_name]['mask_ids'][1]  # rel_name = 'org:founded_by'
        elif (get_args().data_dir == "../datasets/CMeIE_temp2" or get_args().data_dir == "../datasets/diakg_temp2"):
            # 糖尿病是[MASK][MASK][MASK][MASK]。β细胞胰岛素分泌功能已开始逐渐下降(2b级)是[MASK][MASK][MASK][MASK]，二者[MASK]关系。
            e1 = tokenizer.encode(pos_head['name'] + "是",add_special_tokens=False)  # 'was All Basotho Convention'的编码  e1：头实体编码 =[404, 7093, 6157, 139, 9127]
            e2 = tokenizer.encode("," + pos_tail['name'] + "是",add_special_tokens=False)  # 'was Tom Thabane'的编码  e2：尾实体编码 =[1560, 2032, 873, 1728]
            prompt = e1 + self.temp_ids[rel_name]['mask_ids'][0] + e2 + self.temp_ids[rel_name]['mask_ids'][1] \
                     + self.temp_ids[rel_name]['mask_ids'][2] # rel_name = 'org:founded_by'
        """
        temp_ids['org:founded_by']: {'label_ids': [1, 2, 13, 7, 5], 'mask_ids': [[627, 50264], [50264, 50264, 50264], [627, 50264]]}
        temp_ids[rel_name]['mask_ids'][0]     = [627, 50264]
        e1：头实体编码                           = [404, 7093, 6157, 139, 9127]
        self.temp_ids[rel_name]['mask_ids'][1]= [50264, 50264, 50264]
        self.temp_ids[rel_name]['mask_ids'][2]= [627, 50264]
        e2：尾实体编码                           = [1560, 2032, 873, 1728]
        将头尾实体放入模板：['the', '<mask>'],['was All Basotho Convention'] ['<mask>', '<mask>', '<mask>'], ['the', '<mask>']['was Tom Thabane']
        prompt组装后：[627, 50264, 404, 7093, 6157, 139, 9127, 50264, 50264, 50264, 627, 50264, 1560, 2032, 873, 1728]
        ？？？这里暂时还没有把关系标签组装进去？？？
        """
        #  + \
        #  [tokenizer.unk_token_id, tokenizer.unk_token_id]

        flags = []   # 有单词的地方记录为0 flags =[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        # last = 0
        # for i in prompt:
            # if i == tokenizer.unk_token_id:
            #     last+=1
            #     flags.append(last)
            # else:
            # flags.append(0)

        tokens = sentence + prompt  # tokens：52+16 句子 和 模板 拼接起来[15691, 2032, 873, 1728, 6490, 11, 779, 94, 76, 7, 1026, 5, 404, 7093, 6157, 139, 9127, 111, 574, 26770, 12, 3943, 111, 25733, 387, 12, 2156, 6724, 5, 1929, 19, 601, 453, 9, 3589, 2156, 3735, 6100, 20303, 1745, 40702, 324, 6395, 7, 30887, 3589, 8, 486, 5, 6788, 729, 479, 627, 50264, 404, 7093, 6157, 139, 9127, 50264, 50264, 50264, 627, 50264, 1560, 2032, 873, 1728]
        flags = [0 for i in range(len(tokens))]  # flags：[0*68] 将tokens里有单词编码的位置设为0
        # tokens = prompt + sentence
        # flags =  flags + [0 for i in range(len(sentence))]

        tokens = self.truncate(tokens, max_length = self.args.max_seq_length - tokenizer.num_special_tokens_to_add(False))  # 对tokens长度进行裁剪
        flags = self.truncate(flags, max_length = self.args.max_seq_length - tokenizer.num_special_tokens_to_add(False))  # 对flags长度进行裁剪

        input_ids = tokenizer.build_inputs_with_special_tokens(tokens)  # build_inputs_with_special_tokens()函数：如果只有一句话就在首尾分别加上cls_token_id（0），sep_token_id（2）。  input_ids=[0, 15691, 2032, 873, 1728, 6490, 11, 779, 94, 76, 7, 1026, 5, 404, 7093, 6157, 139, 9127, 111, 574, 26770, 12, 3943, 111, 25733, 387, 12, 2156, 6724, 5, 1929, 19, 601, 453, 9, 3589, 2156, 3735, 6100, 20303, 1745, 40702, 324, 6395, 7, 30887, 3589, 8, 486, 5, 6788, 729, 479, 627, 50264, 404, 7093, 6157, 139, 9127, 50264, 50264, 50264, 627, 50264, 1560, 2032, 873, 1728, 2]
        token_type_ids = tokenizer.create_token_type_ids_from_sequences(tokens)  # create_token_type_ids_from_sequences()函数： 如果只有一句话返回列表 len(cls + token_ids_0 + sep) * [0]。   token_type_ids =[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        input_flags = tokenizer.build_inputs_with_special_tokens(flags)  # input_flags=[0, 0*68,  2]
        input_flags[0] = 0
        input_flags[-1] = 0  #  input_flags=[0*70]
        assert len(input_ids) == len(input_flags)
        assert len(input_ids) == len(token_type_ids)  # input_ids, token_type_ids, input_flags三者长度对齐
        return input_ids, token_type_ids, input_flags

    """对句子长度进行裁剪"""
    def truncate(self, seq, max_length):  # max_length=510
        if len(seq) <= max_length:
            return seq
        else:
            print ("=========")
            return seq[len(seq) - max_length:] # 如果长度大于510就取前510个


"""Module for Ingresses"""

__author__ = "Mariano Jose Abdala"
__version__ = "0.1.0"

from kubernetes.client.exceptions import ApiException
from rich.table import Table, Column

from devopscenter.modules.kube.views.base_view import ViewBase
from devopscenter.modules.kube.cluster_utils import pretty_annotations

class IngressView(ViewBase):
    """
    Class used to render the ResourceUsage of the pods.
    """

    def execute(self, args):
        """
        Entrypoint of the class where gets the arguments and use them.
        """
        if len(args) == 2:
            self.__show_ingress(args[1])
        else:
            self.__show_ingress()

    def __show_ingress(self, filter_value=None):
        """
        Method that render the resources of the pods.

        :param filter_value the filter_value to be apply to limit the resources to show.
        """
        ingresses = {}

        try:
            ingresses = self.api.list_cluster_custom_object(group="extensions",
                                                            version="v1",
                                                            plural="ingresses",
                                                            pretty=True)
        except ApiException:
            self.print("No Resources found")
            return

        table = Table(
            Column("Namespace", style="green"),
            Column("Ingress Name", style="green"),
            Column("Annotations", style="green"),
            show_lines=True,
        )
        ingresses_por_namespace = {}

        for ingress in ingresses["items"]:
            ingress_name = ingress["metadata"]["name"]
            annot = ingress["metadata"]["annotations"]
            namespace = ingress["metadata"]["namespace"]

            if filter_value is not None and filter_value not in ingress_name:
                continue
            annotations = ""

            if annot is not None:
                annotations = list(
                    filter(lambda x: "ingress.kubernetes.io" in x[0],
                           annot.items()))
                if len(annotations) > 0:
                    ingresses_por_namespace.update({
                        f"{namespace}:{ingress_name}": {
                            "ingress_name": ingress_name,
                            "annotations": pretty_annotations(annotations),
                            "namespace": namespace,
                        }
                    })

        for _, ingress in ingresses_por_namespace.items():

            table.add_row(
                ingress.get("namespace"),
                ingress.get("ingress_name"),
                str(ingress.get("annotations")),
            )
        self.print(table)


import re
import threading
import time
from typing import Any, cast, Callable, Dict, Optional

# Dependencies of salesforce.dbapi on Django are minimalized.
# The biggest challenges are django.conf.settings, django.db.connections and django.test.

try:
    settings = None  # type: Any
    from django.conf import settings
except ImportError:
    # mock for some tests without a real Django
    import importlib
    import os

    settings = importlib.import_module(os.environ['DJANGO_SETTINGS_MODULE'])

    if not getattr(settings, 'SF_CAN_RUN_WITHOUT_DJANGO', False):
        raise

def get_max_retries() -> int:
    """Get the maximal number of requests retries

    The maximal number of retries for timeouts in requests to Force.com API.
    Can be set dynamically
    None: use defaults from settings.REQUESTS_MAX_RETRIES (default 1)
    0: no retry
    1: one retry
    """
    return getattr(settings, 'REQUESTS_MAX_RETRIES', 1)  # type: ignore[no-any-return] # noqa

def get_thread_connections() -> Dict[Optional[str], Any]:
    if not hasattr(thread_loc, 'connections'):
        thread_loc.connections = {}
    return cast(Dict[Optional[str], Any], thread_loc.connections)

class TimeStatistics:

    def __init__(self, expiration: float = 300) -> None:
        self.expiration = expiration
        self.data = {}  # type: Dict[str, float]

    def update_callback(self, url: str, callback: Optional[Callable[[], Any]] = None) -> None:
        """Update the statistics for the domain"""
        domain = self.domain(url)
        last_req = self.data.get(domain, 0)
        t_new = time.time()
        do_call = (t_new - last_req > self.expiration)
        self.data[domain] = t_new
        if do_call and callback:
            callback()

    @staticmethod
    def domain(url: str) -> str:
        match = re.match(r'^(?:https|mock)://([^/]*)/?', url)
        assert match, "HOST must be including the protocol and :// like 'https://login.salesforce.com'"
        return match.groups()[0]

time_statistics = TimeStatistics(300)
thread_loc = threading.local()


#!/usr/bin/env python3

import psycopg2
from faker import Faker
import random

USERS = 10

def populate(cur, conn):
    conn.autocommit = True
    cur.execute("drop table if exists users")
    cur.execute("drop table if exists addresses")
    conn.autocommit = False
    fake = Faker()
    def populate_users(cur, con):
        cur.execute("""
    CREATE TABLE IF NOT EXISTS users (
        id serial,
        name  varchar,
        dob DATE,
        primary key(id))
        """)
        con.commit()
        for _ in range(USERS):
            cursor.execute(f"""
            INSERT INTO users(name, dob) VALUES('{fake.name()}', '{fake.date_of_birth()}')
            """)
        conn.commit()
    def populate_addresses(cur, con):
        cur.execute("""
    CREATE TABLE IF NOT EXISTS addresses(
        id int,
        address varchar)
        """)
        conn.commit()
        fake = Faker()
        for i in range(USERS - 1):
            cursor.execute(f"""
            INSERT INTO addresses(id, address) VALUES('{i+1}', '{fake.address()}')
            """)
        # some users have more than one address
        for _ in range(3):
            cursor.execute(f"""
            INSERT INTO addresses(id, address) VALUES('{random.randint(1, USERS - 1)}', '{fake.address()}')
            """)
    populate_users(cur, conn)
    populate_addresses(cur, conn)

def printrecords(f):
    def wrapper(cursor):
        f(cursor)
        for i in cursor:
            print(i)
        print()
    return wrapper

@printrecords
def fetch(cursor):
    cursor.execute("""
    SELECT users.id, users.name, addresses.address  FROM users
    inner join addresses
    on users.id  = addresses.id
    order by users.id
    """)

@printrecords
def fetchjoin(cursor):
    cursor.execute("""
    SELECT users.id, users.name, addresses.address  FROM users
    left join addresses
    on users.id  = addresses.id
    order by users.id
    """)

@printrecords
def homeless(cursor):
    cursor.execute("""
    SELECT users.id, users.name FROM users
    where (select count(id) from  addresses where id = users.id) = 0
    """)

with psycopg2.connect(user = "dima",
                      database = "dima") as connection:
    with connection.cursor() as cursor:
        populate(cursor, connection)
        fetch(cursor)
        fetchjoin(cursor)
        homeless(cursor)


#!/usr/bin/env python
"""
Demo microservice that records player events.
"""
import os
from optparse import OptionParser
from flask import request
from flask_api import FlaskAPI, exceptions
from cassandra.cluster import Cluster
from structures import DynamicActionArray
from util import parse_timesamp, parse_action, cassandra_insert
import settings

parser = OptionParser()
parser.add_option("-p", "--port", dest="port",
                  default=settings.LOCAL_SERVER_PORT,
                  help="Port to listen on", type="int")
parser.add_option("-l", "--listen", dest="listen",
                  default=settings.LOCAL_SERVER_IP,
                  help="Address to listen on", type="string")

# FlaskAPI has an eye candy browser view
app = FlaskAPI(__name__)
data = DynamicActionArray(settings.ACTION_ARRAY_INIT_SIZE,
                          settings.ACTION_GROW_FACTOR,
                          settings.SCORE_VALUES)

# Cassandra startup
if settings.CASSANDRA_SUPPORT:
    cluster = Cluster(settings.CASSANDRA_CLUSTER_IPS)
    session = cluster.connect(settings.CASSANDRA_KEYSPACE)

@app.route('/', methods=['GET'])
def server_status():
    """
    Display server status!
    """
    return {'description': 'Stats Microservice',
            'records': data.length,
            'load': os.getloadavg()}

@app.route('/user/<int:uid>/', methods=['GET', 'POST'])
def user_stats(uid):
    """
    Insert and query user events.
    """
    if request.method == 'POST':
        try:
            timestamp = parse_timesamp(request.data.get('timestamp', ''))
            action = parse_action(request.data.get('action', ''), min_action=1,
                                  max_action=len(settings.SCORE_VALUES))
            data.append(uid, action, timestamp)
            if settings.CASSANDRA_SUPPORT:
                cassandra_insert(session, uid, action, timestamp)
            return {'message': 'ok'}
        except Exception as ex:
            raise exceptions.ParseError(
                detail='{}: {}'.format(ex.__class__.__name__, ex.message))

    if request.method == 'GET':
        try:
            start = parse_timesamp(request.args.get('start', ''))
            end = parse_timesamp(request.args.get('end', ''))
            return data.query(uid, start, end)
        except Exception as ex:
            raise exceptions.ParseError(
                detail='{}: {}'.format(ex.__class__.__name__, ex.message))

if __name__ == '__main__':
    app.debug = settings.LOCAL_SERVER_DEBUG
    (options, args) = parser.parse_args()
    app.run(host=options.listen, port=options.port)


# -*- coding: UTF-8 -*-
from sys import argv
import dask.dataframe as dd
import logging
from datetime import datetime
import time

try:
    data_argv = argv
except IndexError as e:
    logging.error("Run script must with parameter")
    print('Run script must with parameter')
    exit('1')
    raise e

VERSION = 16.0

# ОКРУЖЕНИЕ
PROD = True

if PROD:
    # Путь к файлу для обработки:
    path_to_file_Commercial = "D:\\Export\\DP\\Commercial\\"
    path_to_file_PnL = "D:\\Export\\DP\\PnL\\"
    path_to_file_Calendar_shift = "D:\\Export\\DP\\Calendar_shift\\"
    path_to_file_Efficiency = "D:\\Export\\DP\\Efficiency\\"
    #  main .log file
    path_to_log = "D:\\HyperLog\\DP\\pyConvert.log"
else:
    path_to_file_Commercial = "C:\\Users\\60001240\\Desktop\\DP\\Commercial\\"
    path_to_file_PnL = "C:\\Users\\60001240\\Desktop\\DP\\PnL\\"
    path_to_file_Calendar_shift = "C:\\Users\\60001240\\Desktop\\DP\\Calendar_shift\\"
    path_to_file_Efficiency = "C:\\Users\\60001240\\Desktop\\DP\\Efficiency\\"
    path_to_log = "pyConvert.log"

# Название файлов по выгрузки
#  Коммерческие показатели
list_name_Commercial = [
    "CE_Commercial_TSC_Day.txt",
    "CE_Commercial_CPC_Month.txt",
    "CE_Commercial_CPC_Day.txt",
    "CE_Commercial_NoCPC_Day.txt",
    "CE_Commercial_TSC_Month.txt",
    "CE_Commercial_NoCPC_Month.txt"
]
#  CЧёт эксплуатации
list_name_PnL = [
    "CE_PnL_CPC_Month.txt",
    "CE_PnL_NoCPC_Month.txt"
]
Calendar_shift = [
    "CE_Calendar_shift.txt"
]
# Эффективность
list_name_Efficiency = [
    "CE_Efficiency_Month.txt"
]

#  Лог
logging.basicConfig(filename=path_to_log, level=logging.INFO)

# Функция конвертирует данные и проверяет кол-во записей.
def main(filename, path):
    print(filename)
    today = datetime.now()
    start_job = time.time()
    # Проверка типа поля DATA -> INT в CE_Calendar_shift.
    if filename == "CE_Calendar_shift.txt":
        df = dd.read_csv(path + filename, delimiter=';', encoding='1251')
        # Конвертируем в INT
        df[df.columns[14]] = df[df.columns[14]].astype('int64')
        # Конвертируем в INT название столбца, чтобы не потерялось первое значение.
        df = df.rename(columns={df.columns[14]: int(float(df.columns[14]))})
        count_txt = df.shape[0].compute() + 1
        df.to_csv(path + filename.replace(".txt", ".csv"), sep=";", index=False, single_file=True)
    else:
        df = dd.read_csv(path + filename, delimiter=';', dtype=str)
        # count all  lines.
        count_txt = df.shape[0].compute() + 1
        df.to_csv(path + filename.replace(".txt", ".csv"), sep=";", index=False, single_file=True)
        # Путь к файлу
        df = dd.read_csv(path + filename, delimiter=';', dtype=str)
        # Убираю доп. ковычки
        df.to_csv(path + filename.replace(".txt", ".csv"), sep=";", index=False, single_file=True)
    '''Сверка по кол-ву: txt == csv'''
    df_new = dd.read_csv(path + filename, delimiter=';', dtype=str)
    count_csv = df_new.shape[0].compute() + 1
    if count_txt == count_csv:
        print(f' count_txt {count_txt}  == count_csv {count_csv}')
    else:
        print(f' count_txt {count_txt} <> count_csv {count_csv}')
        logging.error("count_csv != count_csv")
        return 1  # 1 не сработало.

    #  В ЛОГ
    total_string = format(round(time.time() - start_job, 2))
    now_string = today.strftime("%d/%m/%Y %H:%M:%S")
    output = now_string + ';' + total_string + ";" + filename.replace(".txt",
                                                                      ".csv") + ";" + str(
        count_csv)
    # Add line to pyConvert.log
    logging.info(output)
    print(filename.replace(".txt", ".csv"))
    del df
    del df_new
    return 0  # 0 - всё ОК.

if __name__ == '__main__':
    start_time = time.time()
    try:
        now = datetime.now()
        dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
        # Обрабатываем каждую папку отдельно:Commercial
        if data_argv[1] == 'Commercial':
            for file in list_name_Commercial:
                main(filename=file, path=path_to_file_Commercial)

        #  Обрабатываем каждую папку отдельно: PnL
        if data_argv[1] == 'PnL':
            for file in list_name_PnL:
                main(filename=file, path=path_to_file_PnL)

        # Календарный сдвиг
        if data_argv[1] == 'Calendar_shift':

            for file in Calendar_shift:
                main(filename=file, path=path_to_file_Calendar_shift)

                #  Обрабатываем каждую папку отдельно: Efficiency
        if data_argv[1] == 'Efficiency':
            for file in list_name_Efficiency:
                main(filename=file, path=path_to_file_Efficiency)

        if not data_argv[1] == 'Efficiency' and \
           not data_argv[1] == 'Calendar_shift' and \
           not data_argv[1] == 'PnL' and \
           not data_argv[1] == 'Commercial':
            logging.error(f'Wrong data_argv {data_argv}')
            print(f'Used to: https://github.com/nvetrov/DP ')
            print('-----------------------------')
            print(f'py .\main.py Commercial')
            print(f'py .\main.py PnL')
            print(f'py .\main.py Calendar_shift')
            print(f'py .\main.py Efficiency')
            print(f'-------------------------------------')
            exit('1')

    except EOFError as e:
        # print("Caught the EOF error.")
        logging.error("Caught the EOF error")
        raise e
    except IOError as e:
        logging.error("Caught the I/O error")
        raise e
    except IndexError as e:
        logging.error(f'Run script must with parameter')
        print('Run script must with parameter: ')
        exit('1')
        raise e


import torch

class Lie:
    @classmethod
    def se3_exp_map(cls, log_transform: torch.Tensor, eps: float = 1e-4):
        """
        se3 -> SE3

        Args:
            log_transform: shape of (N, 6)
        Returns:
            transform: shape of (N, 4, 4)
        """
        assert (
            len(log_transform.shape) == 2 and log_transform.shape[-1] == 6
        ), "Input tensor shape has to be Nx6."
        N = log_transform.shape[0]

        log_trans, log_rot = log_transform.split(3, dim=-1)

        skews = cls.hat(log_rot)
        skews_square = torch.bmm(skews, skews)
        rot_angles = (log_rot**2).sum(-1).clamp(eps).sqrt()
        rot_angles_inv = 1.0 / rot_angles
        I = torch.eye(3).to(log_transform)[None]

        A = (rot_angles.sin() * rot_angles_inv)[:, None, None]
        B = ((1.0 - rot_angles.cos()) * (rot_angles_inv**2))[:, None, None]
        C = ((rot_angles - rot_angles.sin()) * (rot_angles_inv**3))[:, None, None]

        R = I + A * skews + B * skews_square
        V = I + B * skews + C * skews_square
        T = V @ log_trans[..., None]

        transform = torch.eye(4).to(log_transform).repeat(N, 1, 1)
        transform[..., :3, :4] = torch.cat([R, T], dim=-1)

        return transform

    @classmethod
    def so3_exp_map(cls, log_rotation: torch.Tensor, eps: float = 1e-4):
        """
        so3 -> SO3

        Args:
            log_rotation: shape of (N, 3)
        Returns:
            R: shape of (N, 3, 3)
        """
        assert (
            len(log_rotation.shape) == 2 and log_rotation.shape[-1] == 3
        ), "Input tensor shape has to be Nx3."

        skews = cls.hat(log_rotation)
        skews_square = torch.bmm(skews, skews)
        rot_angles = (log_rotation**2).sum(-1).clamp(eps).sqrt()
        rot_angles_inv = 1.0 / rot_angles
        I = torch.eye(3).to(log_rotation)[None]

        A = (rot_angles.sin() * rot_angles_inv)[:, None, None]
        B = ((1.0 - rot_angles.cos()) * (rot_angles_inv**2))[:, None, None]

        R = I + A * skews + B * skews_square

        return R

    @classmethod
    def se3_log_map(
        cls, transform: torch.Tensor, eps: float = 1e-4, cos_bound: float = 1e-4
    ):
        """
        SE3 -> se3

        Args:
            transform: shape of (N, 4, 4)
        Returns:
            : shape of (N, 6)
        """
        assert (
            len(transform.shape) == 3
            and transform.shape[1] == 4
            and transform.shape[2] == 4
        ), "Input tensor shape has to be Nx4x4."
        N = transform.shape[0]

        assert torch.allclose(
            transform[:, 3, :3], torch.zeros_like(transform[:, :3, 3])
        ), "All elements of `transform[:, :3, 3]` should be 0."

        R = transform[:, :3, :3]
        log_rot = cls.so3_log_map(R, eps=eps, cos_bound=cos_bound)

        T = transform[:, :3, 3]

        rot_angles = (log_rot**2).sum(-1).clamp(eps).sqrt()
        log_rot_hat = cls.hat(log_rot)
        log_rot_hat_square = torch.bmm(log_rot_hat, log_rot_hat)
        I = torch.eye(3).to(log_rot)[None]

        A = ((1 - torch.cos(rot_angles)) / (rot_angles**2))[:, None, None]
        B = ((rot_angles - torch.sin(rot_angles)) / (rot_angles**3))[:, None, None]

        V = I + A * log_rot_hat + B * log_rot_hat_square
        log_trans = torch.linalg.solve(V, T[:, :, None])[:, :, 0]

        return torch.cat([log_trans, log_rot], dim=1)

    @classmethod
    def so3_log_map(cls, R: torch.Tensor, eps: float = 0.0001, cos_bound: float = 1e-4):
        """
        SO3 -> so3

        Args:
            R: shape of (N, 3, 3)
        Returns:
            log_rotation: shape of (N, 3)
        """
        assert len(R.shape) == 3 and R.shape[1] == 3 and R.shape[2] == 3
        N = R.shape[0]

        rot_trace = R[:, 0, 0] + R[:, 1, 1] + R[:, 2, 2]
        assert not (
            (rot_trace < -1.0 - eps) + (rot_trace > 3.0 + eps)
        ).any(), "A matrix has trace outside valid range [-1-eps,3+eps]."

        phi_cos = (rot_trace - 1.0) * 0.5
        phi = torch.acos(phi_cos.clamp(-1 + cos_bound, 1 - cos_bound))
        phi_sin = torch.sin(phi)

        # We want to avoid a tiny denominator of phi_factor = phi / (2.0 * phi_sin).
        # Hence, for phi_sin.abs() <= 0.5 * eps, we approximate phi_factor with
        # 2nd order Taylor expansion: phi_factor = 0.5 + (1.0 / 12) * phi**2
        phi_factor = torch.empty_like(phi)
        ok_denom = phi_sin.abs() > (0.5 * eps)
        phi_factor[~ok_denom] = 0.5 + (phi[~ok_denom] ** 2) * (1.0 / 12)
        phi_factor[ok_denom] = phi[ok_denom] / (2.0 * phi_sin[ok_denom])

        log_rotation_hat = phi_factor[:, None, None] * (R - R.permute(0, 2, 1))

        log_rotation = cls.hat_inv(log_rotation_hat)

        return log_rotation

    @classmethod
    def hat(cls, v: torch.Tensor):
        assert len(v.shape) == 2 and v.shape[-1] == 3
        N, dim = v.shape

        h = torch.zeros((N, 3, 3), dtype=v.dtype, device=v.device)
        x, y, z = v.unbind(-1)
        h[:, 0, 1] = -z
        h[:, 0, 2] = y
        h[:, 1, 0] = z
        h[:, 1, 2] = -x
        h[:, 2, 0] = -y
        h[:, 2, 1] = x

        return h

    @classmethod
    def hat_inv(cls, h: torch.Tensor, hat_inv_skew_symmetric_tol: float = 1e-5):
        assert (
            len(h.shape) == 3 and h.shape[1] == 3 and h.shape[2] == 3
        ), "Input has to be a batch of 3x3 Tensors."

        ss_diff = torch.abs(h + h.permute(0, 2, 1)).max()
        assert (
            float(ss_diff) < hat_inv_skew_symmetric_tol
        ), "One of input matrices is not skew-symmetric."

        x = h[:, 2, 1]
        y = h[:, 0, 2]
        z = h[:, 1, 0]
        v = torch.stack((x, y, z), dim=1)

        return v

class ExtrinsicOptimizer(torch.nn.Module):
    def __init__(self, n_views):
        super().__init__()

        self.se3_refinement = torch.nn.Embedding(n_views, 6)
        torch.nn.init.zeros_(self.se3_refinement.weight)

    def forward(self, extrinsics: torch.Tensor, indices: torch.tensor):
        """
        Optimize the camera extrinsic of the given index.

        Args:
            extrinsics: torch.Tensor, RT matrix of shape (B, 4, 4).
            indices: torch.Tensor of shape (B, 1)
        """
        refinement = Lie.se3_exp_map(self.se3_refinement(indices))
        return refinement @ extrinsics


from __future__ import absolute_import

from flytekit.common.notifications import PagerDuty
from flytekit.common.schedules import CronSchedule
from flytekit.common.types.primitives import String, Integer, Boolean
from flytekit.models.core.execution import WorkflowExecutionPhase
from flytekit.sdk.tasks import (
    python_task,
    inputs,
    outputs,
)
from flytekit.sdk.types import Types
from flytekit.sdk.workflow import workflow_class, Input, Output

PAGE_ON_FAILURE_IN_PRODUCTION = PagerDuty(
    phases=[WorkflowExecutionPhase.FAILED, WorkflowExecutionPhase.TIMED_OUT],
    recipients_email=["testservice-low-urgency@lyft.pagerduty.com"],
)

TEST_CRON_SCHEDULE = CronSchedule("0/15 * * * ? *")

@inputs(list_of_nums=[Types.Integer])
@outputs(are_num_odd=[Types.Boolean])
@python_task(cache_version='1')
def find_odd_numbers(wf_params, list_of_nums, are_num_odd):
    if wf_params and wf_params.logging:
        wf_params.logging.info("Running find_odd_nums python task")
    output_list = []
    for num in list_of_nums:
        b = num % 2 == 1
        output_list.append(b)
        if wf_params and wf_params.logging:
            wf_params.logging.info("Number {} is odd? {}".format(num, b))
    are_num_odd.set(output_list)

@workflow_class()
class OnePythonTaskWF(object):
    odd_nums_task = find_odd_numbers(list_of_nums=[2, 3, 4, 7])
    task_output = odd_nums_task.outputs.are_num_odd

onePythonTaskLP = OnePythonTaskWF.create_launch_plan(schedule=TEST_CRON_SCHEDULE,
                                                     notifications=[PAGE_ON_FAILURE_IN_PRODUCTION])

@inputs(list_of_nums=[Types.Integer], demo_string=Types.String)
@outputs(are_num_odd=[Types.Boolean], altered_string=Types.String)
@python_task(cache_version='1')
def find_odd_numbers_with_string(wf_params, list_of_nums, demo_string, are_num_odd, altered_string):
    if wf_params and wf_params.logging:
        wf_params.logging.info("Running find_odd_nums python task")
    output_list = []
    for num in list_of_nums:
        b = num % 2 == 1
        output_list.append(b)
        if wf_params and wf_params.logging:
            wf_params.logging.info("Number {} is odd? {}".format(num, b))
    are_num_odd.set(output_list)
    altered_string.set(demo_string + '_changed')

@workflow_class()
class WorkflowWithIO(object):
    a = Input(Types.Integer, default=10, help="Test integer input with default")
    b = Input(Types.String, required=True, help="Test string with no default")
    odd_nums_task = find_odd_numbers_with_string(list_of_nums=[2, 3, 4, 7], demo_string=b)
    task_output = Output(odd_nums_task.outputs.are_num_odd, sdk_type=[Boolean])
    output_a = Output(a, sdk_type=Integer)  # pass through output
    output_b = Output(odd_nums_task.outputs.altered_string, sdk_type=String)


import random as rd
import hangman_art as ha
import hangman_words as hw
from replit import clear

print(ha.logo)
word_list = hw.word_list
stages = ha.stages
chosen_word = rd.choice(word_list)
chosen_word_len = len(chosen_word)

# Blank display
print(chosen_word)
display = []
for bar in range(chosen_word_len):
    display.append("_")
print(f"{' '.join(display)}")

end_of_game = False
lives = 6
while not end_of_game:
    user_guess = input("\nGuess a letter: ").lower()
    clear()
    if user_guess in display:
        print(f"\n{user_guess}, You've already tried this one! Try Another One :(")
    for letter in range(chosen_word_len):
        if user_guess == chosen_word[letter]:
            display[letter] = user_guess

    if "_" not in display:
        print("\n\t You've Won :) \n")
        end_of_game = True
        break

    elif user_guess not in chosen_word:
        print(f"\n{user_guess}, doesn't fits! Try Another One :(")
        lives -= 1
        print(f"{stages[lives]}")
        if lives == 0:
            print("\n\t You Lose :( \n")
            print(f"Word: {chosen_word}")
            end_of_game = True
            break

    print(f"{' '.join(display)}")


import tkinter as tk
from tkinter import *
import phonenumbers

from phonenumbers import geodata, geocoder, carrier

root = tk.Tk()
root.geometry('300x400')
root.title('phone number tracker')

# code for clearing the textarea and entry_box
def clear():
    ent_1.delete(0, END)
    tex_area1.delete(1.0, END)

def check():
    ch = phonenumbers.parse(ent_1, 'EN')
    p = (geocoder.description_for_number(ch, 'eo'))
    print(len(p))
    service_name = phonenumbers.parse(ent_1, 'we')
    tex_area1.get(carrier.name_for_number(service_name, 'ru'))

lab_1 = Label(root, text='ENTER THE PHONE NUMBER(+...) ', bg='red', fg='white')
lab_1.place(x=44, y=10)

# entry for inputing the phone number
ent_1 = Entry(root)
ent_1.place(x=55, y=40)

# text_area for showing the information required
tex_area1 = Text(root, height=10, width=20)
tex_area1.place(x=55, y=125)

lab_1 = Label(root, text='THE INFORMATION WILL BE DISPLAY BELOW: ', bg='red', fg='white')
lab_1.place(x=44, y=100)

# CLEAR BUTTON
cle_1 = Button(root, text='clear', bg='blue', fg='whitesmoke', command=clear)
cle_1.place(x=44, y=310)

# exit BUTTON
exit_1 = Button(root, text='Exit', bg='blue', fg='whitesmoke')
exit_1.place(x=84, y=310)

# Check BUTTON
chk_1 = Button(root, text='Check', bg='blue', fg='whitesmoke', command=check)
chk_1.place(x=124, y=310)

root.mainloop()


#!/usr/bin/env python
import os
import sys

import dotenv

# Configs for running coverage from https://adamj.eu/tech/2019/04/30/getting-a-django-application-to-100-percent-coverage/

if __name__ == "__main__":
    dotenv.load_dotenv()

    try:
        command = sys.argv[1]
    except IndexError:
        command = "help"

    running_tests = (command == 'test')

    if running_tests:
        os.environ["DJANGO_SETTINGS_MODULE"] = "config.settings.test"
        from coverage import Coverage
        cov = Coverage()
        cov.erase()
        cov.start()
    else:
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.dev")

    from django.core.management import execute_from_command_line

    execute_from_command_line(sys.argv)

    if running_tests:
        cov.stop()
        cov.combine()
        cov.save()
        covered = cov.report()
        cov.erase()
        # Not sure if we want this. It needs to be kept in sync with our .coveragerc fail value
        # if covered < 80:
        #     sys.exit(1)


import numpy as np
import math
import matplotlib.pyplot as plt
from visualizer import KalmanFilterVisualizer

def save_plots(real_position, measured_position, kalman_position, real_speed, kalman_speed, measured_error,
               kalman_error, times):
    plt.plot(times, real_position, label='Faktyczne położenie')
    plt.plot(times, measured_position, label='Zmierzone położenie')
    plt.plot(times, kalman_position, label='Estymowane położenie')
    plt.xlabel('czas (s)')
    plt.ylabel('położenie (m)')
    plt.legend()
    plt.title('Położenie')
    plt.savefig('positions.png')
    plt.clf()
    plt.plot(times[200:400], real_position[200:400], label='Faktyczne położenie')
    plt.plot(times[200:400], measured_position[200:400], label='Zmierzone położenie')
    plt.plot(times[200:400], kalman_position[200:400], label='Estymowane położenie')
    plt.legend()
    plt.xlabel('czas (s)')
    plt.ylabel('położenie (m)')
    plt.title('Położenie pomiędzy 2 a 4 sekundą ruchu')
    plt.savefig('positions24.png')
    plt.clf()

    plt.plot(times, real_speed, label='Faktyczna prędkość')
    plt.plot(times, kalman_speed, label='Estymowana prędkość')
    plt.xlabel('czas (s)')
    plt.ylabel('prędkość (m/s)')
    plt.legend()
    plt.title('Prędkość')
    plt.savefig('speed.png')
    plt.clf()
    plt.plot(times[200:400], real_speed[200:400], label='Faktyczna prędkość')
    plt.plot(times[200:400], kalman_speed[200:400], label='Estymowana prędkość')
    plt.legend()
    plt.xlabel('czas (s)')
    plt.ylabel('szybkość (m/s)')
    plt.title('Szybkość 2s-4s')
    plt.savefig('speed24.png')
    plt.clf()

    plt.plot(times, measured_error, label='Błąd odczytu położenia')
    plt.plot(times, kalman_error, label='Błąd estymacji położenia filtrem Kalmana')
    plt.xlabel('czas (s)')
    plt.ylabel('błąd (m)')
    plt.legend()
    plt.title('Przebieg błędu')
    plt.savefig('error.png')
    plt.clf()
    plt.plot(times[200:400], measured_error[200:400], label='Błąd odczytu położenia')
    plt.plot(times[200:400], kalman_error[200:400], label='Błąd estymacji położenia filtrem Kalmana')
    plt.legend()
    plt.xlabel('czas (s)')
    plt.ylabel('błąd (m)')
    plt.title('Przebieg błędu pomiędzy 2 a 4 sekundą ruchu')
    plt.savefig('error24.png')
    plt.clf()

def num_iters(T, h):
    return int(math.ceil(T/h))

def simulate(velocity_list, T, kp, ki, kd):
    timestep = 0.01
    iters = num_iters(T, timestep)
    iter_change = round(iters / len(velocity_list))
    last_velocity_index = 0

    u_max = 4
    accelnoise = 0.06
    x0 = np.array([[0], [0]])
    A = np.array([[1, timestep], [0, 1]])
    B = np.array([[1/2 * (timestep ** 2)], [timestep]])
    C = np.array([[1, 0]])
    measnoise = 3

    v_zadane = velocity_list[last_velocity_index]

    Sz = measnoise ** 2
    Sw = accelnoise ** 2 * np.array([[timestep ** 4 / 4, timestep ** 3 / 2], [timestep ** 3 / 2, timestep ** 2]])
    P = Sw

    errors = np.zeros(iters)
    errorSum = errors[0] * timestep
    u_val = np.zeros(iters)

    xhat = x0
    state_history = np.zeros((iters, 2, 1))
    kalman_history = np.zeros((iters, 2, 1))
    state_history[0] = x0
    kalman_history[0] = xhat
    measurement_history = np.zeros(iters)
    for i in range(iters - 1):
        error = v_zadane - xhat[1]
        errorSum += (error * timestep)
        u = kp * error + ki * errorSum
        if(u > u_max):
            u = u_max
        errors[i + 1] = error
        u_val[i + 1] = u

        if i % iter_change == 0 and i != 0 :
            last_velocity_index += 1
            v_zadane = velocity_list[last_velocity_index]

        process_noise = accelnoise * np.array([[1/2 * (timestep**2) * np.random.normal()], [timestep * np.random.normal()]])
        x = A@(state_history[i]) + B*u + process_noise
        measure_noise = np.random.normal() * measnoise
        y = C @ x + measure_noise

        xhat = A @ xhat + B * u
        inn = y - C @ xhat
        s = C @ P @ C.T + Sz
        K = A @ P @ C.T @ np.linalg.inv(s)
        xhat = xhat + K @ inn
        P = A @ P @ A.T - A @ P @ C.T @ np.linalg.inv(s) @ C @ P @ A.T + Sw
        kalman_history[i+1] = xhat
        state_history[i+1] = x
        measurement_history[i+1] = y

    return state_history, measurement_history, np.arange(0, T, timestep), kalman_history, errors, u_val

def test_statistically():
    errors_test = np.zeros((1000, 10000))
    errors_test_kalman = np.zeros((1000, 10000))
    for i in range(1000):
        print(i)
        history, measurement_history, times, kalman, _, _ = simulate([10, 20, 30, 10], 100, 1, 0.1, 0)
        errors = measurement_history - np.squeeze(history[:, 0, :])
        error_after = np.squeeze(kalman[:, 0, :]) - np.squeeze(history[:, 0, :])
        errors_test[i] = errors
        errors_test_kalman[i] = error_after

    errors_avg = np.average(np.abs(errors_test))
    errors_kalman_avg = np.average(np.abs(errors_test_kalman))

    errors_std_dev = np.std(errors_test)
    errors_kalman_std_dev = np.std(errors_test_kalman)
    return errors_avg, errors_std_dev, errors_kalman_avg, errors_kalman_std_dev

if __name__ == '__main__':
    # test_statistically()

    history, measurement_history, times, kalman, _, _ = simulate([10, 20, 30, 10], 100, 1, 0.1, 0)
    errors = measurement_history - np.squeeze(history[:, 0, :])
    error_after = np.squeeze(kalman[:, 0, :]) - np.squeeze(history[:, 0, :])

    save_plots(history[:, 0, :], measurement_history, kalman[:, 0, :], history[:, 1, :], kalman[:, 1, :],
               errors, error_after, times)

    kalman_errors = error_after
    measured_errors = errors
    velocities = np.squeeze(history[:, 1, :])
    kalman_velocities = np.squeeze(kalman[:, 1, :])
    visualizer = KalmanFilterVisualizer(measured_errors, kalman_errors, velocities, kalman_velocities, 100)
    visualizer.run()


from typing import List

class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        l, r, res = 0, len(nums)-1, []
        while l <= r:
            left, right = nums[l]**2, nums[r]**2
            if left > right:
                res.append(left)
                l += 1
            else:
                res.append(right)
                r -= 1
        return res[::-1]

SquidGame/Day8/977. Squares of a Sorted Array.py


# import the necessary packages
#from imutils.video import VideoStream
from imutils.video import FPS
import time
import argparse
import imutils
import cv2
import numpy as np

# open a pointer to the video file
print("[INFO] opening video stream...")
stream = cv2.VideoCapture(0)

# wait 2 seconds for the camera to warm up
time.sleep(2.0)
fps = FPS().start()

# initialize averaged frame
(grabbed,frame) = stream.read()
avgframe = np.float32(frame)

# loop over frames from the video stream
while True:
	# grab the frame from the stream
	(grabbed, frame) = stream.read()

	# if the frame was not grabbed, then break out
	if not grabbed:
		break

	# show the grabbed frame
	cv2.imshow("Live Video", frame)

	key = cv2.waitKey(1) & 0xFF

	# if the `q` key was pressed, break from the loop
	if key == 27:
		break

	# update the FPS counter
	fps.update()

 	# accumulate logic
 	# the alpha parameter (float 0-1) controls how fast the accumulator forgets earlier frames (lower = longer memory)
	cv2.accumulateWeighted(frame, avgframe, 0.02)
	avgframeres = cv2.convertScaleAbs(avgframe)

	# show the averaged frame
	cv2.imshow("Averaged Video", avgframeres)

# stop the timer and display FPS information
fps.stop()
print("[INFO] elapsed time: {:.2f}".format(fps.elapsed()))
print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))

# do a bit of cleanup
stream.release()
cv2.destroyAllWindows()


"""
AI-Economist inspired pytorch model

Author: bonom
Github: https://github.com/bonom

Adapted from: Sa1g (https://github.com/sa1g)

Date: 2023-07-30

"""

import torch
import numpy as np
import torch.nn as nn

WORLD_MAP = "world-map"
WORLD_IDX_MAP = "world-idx_map"
ACTION_MASK = "action_mask"

N_DIMS = {
    "world-map": 4,
    "world-idx_map": 4,
    "flat": 2,
    "time": 2,
    "action_mask": 2,
    "p0": 2,
    "p1": 2,
    "p2": 2,
    "p3": 2,
}

class LSTMModel(nn.Module):
    """
    Actor&Critic (Policy) Model.
    """

    def __init__(
            self,
            obs_space: dict,
            action_space: dict,
            device: str = "cpu"
        ):
        """
        Initialize the ActorCritic Model.
        """
        super().__init__()

        self.action_space = action_space
        self.device = device

        ### Initialize some variables needed here
        self.cell_size = 128
        self.input_emb_vocab = 100
        self.emb_dim = 4
        self.num_conv = 2
        self.fc_dim = 128
        self.num_fc = 2
        self.filter = (16, 32)
        self.kernel_size = (3, 3)
        self.strides = 2
        self.lr = 0.0003
        self.momentum = 0.9

        if self.action_space == 22:
            self.output_dim = 7
        else:
            self.output_dim = 1

        ### Manage observation shape(s)
        self.conv_map_channels, self.conv_shape_r, self.conv_shape_c = obs_space.spaces[
            WORLD_MAP
        ].shape

        self.conv_idx_channels = obs_space.spaces[WORLD_IDX_MAP].shape[0] * self.emb_dim

        ### Embedding layers

        self.embed_map_idx_policy = nn.Embedding(
            self.input_emb_vocab, self.emb_dim, device=device, dtype=torch.float32
        )
        self.embed_map_idx_value = nn.Embedding(
            self.input_emb_vocab, self.emb_dim, device=device, dtype=torch.float32
        )
        self.conv_layers_policy = nn.ModuleList()
        self.conv_layers_value = nn.ModuleList()
        self.conv_shape = (
            self.conv_shape_r,
            self.conv_shape_c,
            self.conv_map_channels + self.conv_idx_channels,
        )

        for i in range(1, self.num_conv):
            if i == 1:
                self.conv_layers_policy.append(
                    nn.Conv2d(
                        in_channels=self.conv_shape[1],
                        out_channels=self.filter[0],
                        kernel_size=self.kernel_size,
                        stride=self.strides,
                    )
                )
                self.conv_layers_value.append(
                    nn.Conv2d(
                        in_channels=self.conv_shape[1],
                        out_channels=self.filter[0],
                        kernel_size=self.kernel_size,
                        stride=self.strides,
                    )
                )
            self.conv_layers_policy.append(
                nn.Conv2d(
                    in_channels=self.filter[0],
                    out_channels=self.filter[1],
                    kernel_size=self.kernel_size,
                    stride=self.strides,
                )
            )
            self.conv_layers_value.append(
                nn.Conv2d(
                    in_channels=self.filter[0],
                    out_channels=self.filter[1],
                    kernel_size=self.kernel_size,
                    stride=self.strides,
                )
            )

        self.conv_dims = 192 if self.action_space == 50 else 320
        self.flatten_dims = (
            self.conv_dims
            + obs_space.spaces["flat"].shape[0]
            + obs_space.spaces["time"].shape[0]
        )

        if self.action_space == 22:
            for agent in ["p0", "p1", "p2", "p3"]:  # 32
                self.flatten_dims += obs_space.spaces[agent].shape[0]

        self.fc_layer_1_policy = nn.Linear(
            in_features=self.flatten_dims, out_features=self.fc_dim
        )
        self.fc_layer_2_policy = nn.Linear(
            in_features=self.fc_dim, out_features=self.fc_dim
        )
        self.fc_layer_1_value = nn.Linear(
            in_features=self.flatten_dims, out_features=self.fc_dim
        )
        self.fc_layer_2_value = nn.Linear(
            in_features=self.fc_dim, out_features=self.fc_dim
        )
        self.lstm_policy = nn.LSTM(
            input_size=self.fc_dim,
            hidden_size=self.cell_size,
            num_layers=1,
        )
        self.lstm_value = nn.LSTM(
            input_size=self.fc_dim,
            hidden_size=self.cell_size,
            num_layers=1,
        )
        self.layer_norm_policy = nn.LayerNorm(self.fc_dim)
        self.layer_norm_value = nn.LayerNorm(self.fc_dim)
        self.output_policy = nn.Linear(
            in_features=self.cell_size, out_features=self.action_space
        )
        self.output_value = nn.Linear(in_features=self.cell_size, out_features=1)

        self.relu = nn.ReLU()
        self.softmax = nn.Softmax()

        self.optimizer = torch.optim.AdamW(self.parameters(), lr=self.lr)
        self.scheduler = torch.optim.lr_scheduler.StepLR(
            self.optimizer, step_size=1, gamma=0.99
        )
        self.mse_loss = nn.MSELoss()

        self.logit_mask = torch.ones(self.action_space).to(self.device) * -10000000
        self.one_mask = torch.ones(self.action_space).to(self.device)

    def apply_logit_mask(self, logits, mask):
        """
        Apply mask to logits, gets an action and calculates its log_probability.
        Mask values of 1 are valid actions.

        Args:
            obs: agent environment observation

        Returns:
            action: taken action
            action_logprob: log probability of that action
        """
        # Add huge negative values to logits with 0 mask values.
        logit_mask = self.logit_mask * (self.one_mask - mask)
        action_probs = logits + logit_mask

        dist = torch.distributions.Categorical(logits=action_probs)

        action = dist.sample()
        action_logprob = dist.log_prob(action)

        return action, action_logprob

    def __forward(self, obs):
        """
        Calculates action probability from the model.

        Args:
            obs: environment observation

        Returns:
            probability: ...
        """

        _world_map = obs[WORLD_MAP].int()
        _world_idx_map = obs[WORLD_IDX_MAP].int()
        _flat = obs["flat"]
        _time = obs["time"].int()
        # _action_mask = obs[ACTION_MASK].int()

        if self.action_space == 22:
            _p0 = obs["p0"]
            _p1 = obs["p1"]
            _p2 = obs["p2"]
            _p3 = obs["p3"]

        conv_input_map = torch.permute(_world_map, (0, 2, 3, 1))
        conv_input_idx = torch.permute(_world_idx_map, (0, 2, 3, 1))

        # Concatenate the remainings of the input
        if self.action_space == 22:
            non_convolutional_input = torch.cat(
                [
                    _flat,
                    _time,
                    _p0,
                    _p1,
                    _p2,
                    _p3,
                ],
                axis=1,
            )
        else:
            non_convolutional_input = torch.cat(
                [
                    _flat,
                    _time,
                ],
                axis=1,
            )

        # Policy
        # Embedd from 100 to 4
        map_embedd = self.embed_map_idx_policy(conv_input_idx)
        # Reshape the map
        map_embedd = torch.reshape(
            map_embedd,
            (-1, self.conv_shape_r, self.conv_shape_c, self.conv_idx_channels),
        )
        # Concatenate the map and the idx map
        conv_input = torch.cat([conv_input_map, map_embedd], axis=-1)

        # Convolutional Layers
        for conv_layer in self.conv_layers_policy:
            conv_output = conv_layer(conv_input)
            conv_input = self.relu(conv_output)

        # Flatten the output of the convolutional layers
        flatten = torch.reshape(
            conv_input, (-1, self.conv_dims)
        )  # 192 is from 32 * 3 * 2

        # Concatenate the convolutional output with the non convolutional input
        fc_in = torch.cat([flatten, non_convolutional_input], axis=-1)

        # Fully Connected Layers
        for i in range(self.num_fc):
            if i == 0:
                fc_in = self.relu(self.fc_layer_1_policy(fc_in))
            else:
                fc_in = self.relu(self.fc_layer_2_policy(fc_in))

        # Normalize the output
        layer_norm_out = self.layer_norm_policy(fc_in)
        # LSTM

        # Project LSTM output to logits
        lstm_out, _ = self.lstm_policy(layer_norm_out)
        logits = self.output_policy(lstm_out)

        return logits

    def act(self, obs):
        """
        Args:
            obs: agent environment observation

        Returns:
            action: taken action
            action_logprob: log probability of that action
        """
        for key in obs.keys():
            if isinstance(obs[key], np.ndarray):
                obs[key]: torch.Tensor = torch.from_numpy(obs[key])
            obs[key]: torch.Tensor = obs[key].to(self.device)

        if obs.get('world-map').dim() < 4:
            obs['world-map'] = obs['world-map'].unsqueeze(0)
        if obs.get('world-idx_map').dim() < 4:
            obs['world-idx_map'] = obs['world-idx_map'].unsqueeze(0)
        if obs.get('time').dim() < 2:
            obs['time'] = obs['time'].unsqueeze(0)
        if obs.get('flat').dim() < 2:
            obs['flat'] = obs['flat'].unsqueeze(0)
        if obs.get('action_mask').dim() < 2:
            obs['action_mask'] = obs['action_mask'].unsqueeze(0)

        logits = self.__forward(obs)

        _action_mask = obs[ACTION_MASK].int()

        # Mask the logits
        if self.action_space == 22:
            logits = torch.split(logits, self.action_space, dim=1)
            mask = torch.split(_action_mask, self.action_space, dim=1)

            # for batch, log in enumerate(logits):
            action = torch.zeros((self.output_dim, self.action_space))
            new_action_logprob = torch.zeros((self.output_dim, self.action_space))
            for idx, l in enumerate(logits):
                out_action, action_logprob = self.apply_logit_mask(l, mask[idx])
                action[idx] = out_action
                new_action_logprob[idx] = action_logprob

            action_logprob = new_action_logprob
        else:
            action, action_logprob = self.apply_logit_mask(logits, _action_mask)

        return action, action_logprob

    def evaluate(self, obs, act):
        """
        Args:
            obs: agent environment observation
            act: action that is mapped with

        Returns:
            action_logprobs: log probability that `act` is taken with this model
            state_values: value function reward prediction
            dist_entropy: entropy of actions distribution
        """
        for key in obs.keys():
            # if key in ['world-map', 'world-idx_map']:
            if key == "time":
                if len(obs[key].shape) < 2:
                    obs[key] = obs[key].unsqueeze(-1)
                elif len(obs[key].shape) > 2:
                    obs[key] = obs[key].squeeze(1)

                obs[key] = obs[key].to(self.device).int()
            else:
                obs[key] = obs[key].squeeze(1).to(self.device)
            # else:
            #     obs[key] = obs[key].to(self.device).squeeze(-1)

        action_probs = self.__forward(obs)
        dist = torch.distributions.Categorical(logits=action_probs)

        action_logprobs = dist.log_prob(act)
        dist_entropy = dist.entropy()

        _world_map = obs[WORLD_MAP].int()
        _world_idx_map = obs[WORLD_IDX_MAP].int()
        _flat = obs["flat"]
        _time = obs["time"].int()

        if self.action_space == 22:
            _p0 = obs["p0"]
            _p1 = obs["p1"]
            _p2 = obs["p2"]
            _p3 = obs["p3"]

        conv_input_map = torch.permute(_world_map, (0, 2, 3, 1))
        conv_input_idx = torch.permute(_world_idx_map, (0, 2, 3, 1))
        # # CRITIC
        # Embedd from 100 to 4
        map_embedd = self.embed_map_idx_value(conv_input_idx)

        # Reshape the map
        map_embedd = torch.reshape(
            map_embedd,
            (-1, self.conv_shape_r, self.conv_shape_c, self.conv_idx_channels),
        )

        if self.action_space == 22:
            non_convolutional_input = torch.cat(
                [
                    _flat,
                    _time,
                    _p0,
                    _p1,
                    _p2,
                    _p3,
                ],
                axis=1,
            )
        else:
            non_convolutional_input = torch.cat(
                [
                    _flat,
                    _time,
                ],
                axis=1,
            )

        # Concatenate the map and the idx map
        conv_input = torch.cat([conv_input_map, map_embedd], axis=-1)

        # Convolutional Layers
        for conv_layer in self.conv_layers_value:
            conv_input = self.relu(conv_layer(conv_input))

        # Flatten the output of the convolutional layers
        flatten = torch.reshape(
            conv_input, (-1, self.conv_dims)
        )  # 192 is from 32 * 3 * 2

        # Concatenate the convolutional output with the non convolutional input
        fc_in = torch.cat([flatten, non_convolutional_input], axis=-1)

        # Fully Connected Layers
        for i in range(self.num_fc):
            if i == 0:
                fc_in = self.relu(self.fc_layer_1_value(fc_in))
            else:
                fc_in = self.relu(self.fc_layer_2_value(fc_in))

        # Normalize the output
        layer_norm_out = self.layer_norm_value(fc_in)

        # Project LSTM output to logits
        lstm_out, _ = self.lstm_value(layer_norm_out)
        state_values = self.output_value(lstm_out)

        return action_logprobs, state_values, dist_entropy

    def get_weights(self) -> dict:
        """
        Get policy weights.

        Return:
            actor_weights, critic_weights
        """
        actor_weights = self.state_dict(keep_vars=True)
        critic_weights = 0
        optimizer_weights = 0

        return actor_weights, critic_weights, optimizer_weights

    def set_weights(self, actor_weights: dict, critic_weights: dict, optimizer_weights):
        """
        Set policy weights.

        Args:
            actor_weights: actor weights dictionary - from numpy
            critic_weights: critic weights dictionary - from numpy
        """
        self.load_state_dict(actor_weights)


#ecncoding=utf-8
import jieba.posseg as pseg
def doParse(question):
	sq = pseg.cut(question)
	result = []
	for w in sq:
		result.append((w.word, w.flag))
	sepaStr = ""
	for inner_item in result:
		sepaStr += (inner_item[0] + " " + str(inner_item[1]) + ", ")

	return sepaStr