from bs4 import BeautifulSoup
import requests

#  поиск раздела см. также
def find_see_also(data):
    if data.find('See also') != -1:
        while data.find('See also') != -1:
            pos = data.find('See also')
            data = data[pos + 8:]

        #  находить ссылки в этом промежутке и рабоатать с ними
        pos = data.find('^')
        data = data[:pos]
    else:
        data = ''
    return data

def title_check(current_titles, possible_titles):
    titles = []
    for possible_title in possible_titles:
        for current_title in current_titles:
            if '/wiki/' + current_title == possible_title:
                titles.append(current_title)

    return titles
    #  Позже попробовать реализовать и сравнить результат

#  функция для проверки на мусорный ввод
def normalize_titles(cut_data, possible_links):
    titles = cut_data.split('\n')
    chars = '!/.,:;\'\"?%^#@*&'

    for title in titles:
        if title == 'Edit' or title == '[edit]':
            titles.remove(title)

        flag = False

        for char in chars:
            if title.find(char) != -1:
                flag = True

        #  Иногда случается что этот элемент был удален ранее и вылазит ошибка
        try:
            if flag:
                titles.remove(title)
        except:
            pass

    for i in range(len(titles)):
        if titles[i].find('[edit]'):
            titles[i] = titles[i].replace('[edit]', '')

    try:
        while titles[-1] == '':
            titles.remove('')
    except:
        pass

    for title in titles:
        if len(title) > 80 or title == 'References':
            titles.remove(title)

    for i in range(len(titles)):
        titles[i] = titles[i].replace(' ', '_')

    #  titles = title_check(titles, possible_links)

    #  Вывод заголовков
    with open('outp.txt', 'a') as f:
        for title in titles:
            f.write(title + '\n')

    return titles

#  Парсим
def parsing(url):
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'html.parser')

    return soup

def duplicate_check(links, link):
    for checker in links:
        if link == checker:
            return False
    #  Если еще не брали
    return True

def main():
    links = []
    links.append('https://en.wikipedia.org/wiki/Online chat')

    for link in links:
        soup = parsing(link)

        possible_links = []

        for possible_link in soup.find_all('a'):
            possible_links.append(str(possible_link.get('href')))

        cutten_data = find_see_also(soup.text)

        #  Заголовки которые мы ищем
        titles = normalize_titles(cutten_data, possible_links)

        for title in titles:
            link = 'https://en.wikipedia.org/wiki/' + title
            if duplicate_check(links, link):
                links.append(link)
                parsing(link)  # Рекусивный поиск ссылок

if __name__ == "__main__":
    main()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import paho.mqtt.client as mqtt
from datetime import datetime
import time
import os
import json
import ast

########## Config ##########
PORT = 1883
CONNECTIONS_FILE = "connections.txt"
TOPIC_ACTION = "action/%s/#"
ACTION_LOG_FILE = "actions.txt"

############################

class mqttClient(object):
    hostname = 'localhost'
    port = 1883
    client_id = ''

    def __init__(self, hostname, port, client_id):
        self.hostname = hostname
        self.port = port
        self.clientid = client_id

        # Create MQTT client
        self.client = mqtt.Client(client_id=self.client_id, clean_session=True, userdata=None, protocol=mqtt.MQTTv31)

        # Register callback functions
        self.client.on_connect = self._on_connect

    def _on_connect(self, client, userdata, flags, rc):
        print("[" + datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3] + "]: " + "ClientID: " + self.clientid + "; Connected with result code " + str(rc))
        print("Connected with result code " + str(rc))

    # publishes message to MQTT broker
    def sendMessage(self, topic, msg):
        self.client.publish(topic=topic, payload=msg, qos=0, retain=False)
        print(msg)

    def start(self):
        # Start MQTT client
        self.client.connect(self.hostname, self.port, 60)
        self.client.loop_start()

def main(argv):
    #print(argv)
    #print(argv[0])

    # default interval for sending data
    sendingInterval = [30]
    sensorVals = []

    # Read other interval informations from parameter data
    paramArray = json.loads(argv[0])
    print(paramArray)
    test =[]

    #stringReplacement = str(param3["value"])
    #replacedStr = stringReplacement.replace("-", ", ")
    #print(replacedStr)

    for param in paramArray:
        print(param)
        if not ('name' in param and 'value' in param):
            continue
        else:
            if(param["name"] == 'interval'):
                sendingInterval = str(param["value"]).replace("-", ", ")
            elif(param["name"] == 'value'):
                sensorVals = str(param["value"]).replace("-", ", ")

    configFileName = "connections.txt"
    topics = []
    brokerIps = []
    configExists = False

    hostname = 'localhost'
    topic_pub = 'test'

    configFile = os.path.join(os.getcwd(), configFileName)

    while (not configExists):
        configExists = os.path.exists(configFile)
        time.sleep(1)

    # BEGIN parsing file
    fileObject = open(configFile)
    fileLines = fileObject.readlines()
    fileObject.close()

    for line in fileLines:
        pars = line.split('=')
        topic = pars[0].strip('\n').strip()
        ip = pars[1].strip('\n').strip()
        topics.append(topic)
        brokerIps.append(ip)

    # END parsing file

    hostname = brokerIps [0]
    topic_pub = topics [0]
    topic_splitted = topic_pub.split('/')
    component = topic_splitted [0]
    component_id = topic_splitted [1]

    print("Connecting to: " + hostname + " pub on topic: " + topic_pub)

    # --- Begin start mqtt client
    id = "id_%s" % (datetime.utcnow().strftime('%H_%M_%S'))
    publisher = mqttClient(hostname, 1883, id)
    publisher.start()

    try:
        sensorVals = eval(sensorVals)
        sendingInterval = eval(sendingInterval)
        startTime = sendingInterval[0]
        counter = 1
        # This loop ensures your code runs continuously,
        # for example, to read sensor values regularly at a given interval.
        # while True:
        for sensorValue in sensorVals:
            value = sensorValue
            msg_pub = {"component": component.upper(), "id": component_id, "value": "%f" % (value) }
            publisher.sendMessage(topic_pub, json.dumps(msg_pub))
            print(topic_pub, json.dumps(msg_pub))
            if(counter < len(sendingInterval)):
                interval = sendingInterval[counter] - startTime
                startTime = sendingInterval[counter]
                counter += 1
                time.sleep(interval)

    except:
        error = sys.exc_info()
        print('Error:', str(error))

# Call main function
if __name__ == "__main__":
    main(sys.argv[1:])


'''
class:net182
name:Lee
ID:201810101580036
'''
marks = {}
marks['Sam'] = 90.5
marks['Jane'] = 85.4
marks['Max'] = 92.3
marks['Alice'] = 64.5
marks['John'] = 69.4
print(marks)

sum = 0
for i in marks:
    sum += marks[i]
    Average = sum / len(marks)
print('Sum: ',sum)
print('Average: ',Average)

Python_OOP/Exercise/Exercise 05/201810101580036 - Lee/05-04.py


import pandas as pd
import xgboost as xgb
from sklearn.metrics import roc_auc_score
from xgboost import plot_importance
from matplotlib import pyplot as plt
from sklearn.preprocessing import LabelEncoder

le = LabelEncoder()
from time import strftime, localtime

# 打印当前时间
def printTime():
    print(strftime("%Y-%m-%d %H:%M:%S", localtime()))
    return

def handleFlagField(x):
    if x !=1 and x !=0:
        return 0
    else:
        return x
'''
    指定数据字段的类型及处理空值
'''

## 指标独热编码
def handeleOneHotCode(X):
    le.fit(X)
    return le.transform(X)

##  使用Z-SCORE方法进行归一化处理

def handleDataToOne(x):
    z_score = (x - x.mean()) / x.std()
    return abs(z_score)
'''
def handleDataToOne(x):
    return  x
'''

def changeType(data):
    data['prov_id'].fillna('099', inplace=True)
    data['prov_id'] = handeleOneHotCode(data['prov_id'])
    data['user_id'].fillna('9999999999', inplace=True)
    data['product_id'].fillna('9999999', inplace=True)
    data['area_id'].fillna('0991', inplace=True)
    data['device_number'].fillna('9999999999', inplace=True)
    data['cust_sex'].fillna('1', inplace=True)
    data['cert_age'] = data['cert_age'].apply(pd.to_numeric, errors='coerce').fillna(34.98)
    data["cert_age"] = data["cert_age"].round(2)
    data['total_fee'] = data['total_fee'].apply(pd.to_numeric, errors='coerce').fillna(60.66)
    data['total_fee'] = handleDataToOne(data['total_fee'])
    data["total_fee"] = data["total_fee"].round(2)
    data['jf_flux'] = data['jf_flux'].apply(pd.to_numeric, errors='coerce').fillna(6.9)
    data['jf_flux'] = handleDataToOne(data['jf_flux'])
    data["jf_flux"] = data["jf_flux"].round(1)
    data['fj_arpu'] = data['fj_arpu'].apply(pd.to_numeric, errors='coerce').fillna(5.4)
    data['fj_arpu'] = handleDataToOne(data['fj_arpu'])
    data["fj_arpu"] = data["fj_arpu"].round(1)
    data['ct_voice_fee'] = data['ct_voice_fee'].apply(pd.to_numeric, errors='coerce').fillna(4.0)
    data['ct_voice_fee'] = handleDataToOne(data['ct_voice_fee'])
    data["ct_voice_fee"] = data["ct_voice_fee"].round(1)
    data['total_flux'] = data['total_flux'].apply(pd.to_numeric, errors='coerce').fillna(16265.98)
    data['total_flux'] = handleDataToOne(data['total_flux'])
    data["total_flux"] = data["total_flux"].round(2)
    data['total_dura'] = data['total_dura'].apply(pd.to_numeric, errors='coerce').fillna(322.45)
    data['total_dura'] = handleDataToOne(data['total_dura'])
    data["total_dura"] = data["total_dura"].round(2)
    data['roam_dura'] = data['roam_dura'].apply(pd.to_numeric, errors='coerce').fillna(64.81)
    data['roam_dura'] = handleDataToOne(data['roam_dura'])
    data["roam_dura"] = data["roam_dura"].round(2)
    data['total_times'] = data['total_times'].apply(pd.to_numeric, errors='coerce').fillna(434.88)
    data['total_times'] = handleDataToOne(data['total_times'])
    data["total_times"] = data["total_times"].round(2)
    data['total_nums'] = data['total_nums'].apply(pd.to_numeric, errors='coerce').fillna(204.89)
    data['total_nums'] = handleDataToOne(data['total_nums'])
    data["total_nums"] = data["total_nums"].round(2)
    data['local_nums'] = data['local_nums'].apply(pd.to_numeric, errors='coerce').fillna(156.85)
    data['local_nums'] = handleDataToOne(data['local_nums'])
    data["local_nums"] = data["local_nums"].round(2)
    data['roam_nums'] = data['roam_nums'].apply(pd.to_numeric, errors='coerce').fillna(36.26)
    data['roam_nums'] = handleDataToOne(data['roam_nums'])
    data["roam_nums"] = data["roam_nums"].round(2)
    data['in_cnt'] = data['in_cnt'].apply(pd.to_numeric, errors='coerce').fillna(100.04)
    data['in_cnt'] = handleDataToOne(data['in_cnt'])
    data["in_cnt"] = data["in_cnt"].round(2)
    data['out_cnt'] = data['out_cnt'].apply(pd.to_numeric, errors='coerce').fillna(104.86)
    data['out_cnt'] = handleDataToOne(data['out_cnt'])
    data["out_cnt"] = data["out_cnt"].round(2)
    data['in_dura'] = data['in_dura'].apply(pd.to_numeric, errors='coerce').fillna(152.31)
    data['in_dura'] = handleDataToOne(data['in_dura'])
    data["in_dura"] = data["in_dura"].round(1)
    data['out_dura'] = data['out_dura'].apply(pd.to_numeric, errors='coerce').fillna(169.66)
    data['out_dura'] = handleDataToOne(data['out_dura'])
    data["out_dura"] = data["out_dura"].round(1)
    data['heyue_flag'].fillna(0, inplace=True)
    data['is_limit_flag'].fillna('0', inplace=True)
    data['product_type'].fillna('other', inplace=True)
    data['product_type'] = handeleOneHotCode(data['product_type'])
    data['5g_flag'] = data['5g_flag'].apply(lambda x: handleFlagField(x))
    data['visit_cnt'] = data['visit_cnt'].apply(pd.to_numeric, errors='coerce').fillna(2231.73)
    data['visit_cnt'] = handleDataToOne(data['visit_cnt'])
    data["visit_cnt"] = data["visit_cnt"].round(2)
    data['visit_dura'] = data['visit_dura'].apply(pd.to_numeric, errors='coerce').fillna(35562.76)
    data['visit_dura'] = handleDataToOne(data['visit_dura'])
    data["visit_dura"] = data["visit_dura"].round(2)
    data['up_flow'] = data['up_flow'].apply(pd.to_numeric, errors='coerce').fillna(1.14)
    data['up_flow'] = handleDataToOne(data['up_flow'])
    data["up_flow"] = data["up_flow"].round(2)
    data['down_flow'] = data['down_flow'].apply(pd.to_numeric, errors='coerce').fillna(4.67)
    data['down_flow'] = handleDataToOne(data['down_flow'])
    data["down_flow"] = data["down_flow"].round(2)
    data['total_flow'] = data['total_flow'].apply(pd.to_numeric, errors='coerce').fillna(4.91)
    data['total_flow'] = handleDataToOne(data['total_flow'])
    data["total_flow"] = data["total_flow"].round(2)
    data['active_days'] = data['active_days'].apply(pd.to_numeric, errors='coerce').fillna(9.96)
    data['active_days'] = handleDataToOne(data['active_days'])
    data["active_days"] = data["active_days"].round(2)
    data['brand_flag'].fillna(13, inplace=True)
    data['imei_duration'] = data['imei_duration'].apply(pd.to_numeric, errors='coerce').fillna(12.0)
    data['imei_duration'] = handleDataToOne(data['imei_duration'])
    data["imei_duration"] = data["imei_duration"].round(2)
    data['avg_duratioin'] = data['avg_duratioin'].apply(pd.to_numeric, errors='coerce').fillna(12.0)
    data['avg_duratioin'] = handleDataToOne(data['avg_duratioin'])
    data["avg_duratioin"] = data["avg_duratioin"].round(2)
    #data['flag'].fillna(0, inplace=True)
    return data

printTime()
trainFilePath = 'D:/data/python/work/qwr_woyinyue_basic_result1.txt'
testFilePath = 'D:/data/python/work/qwr_woyinyue_user_result2006_87.txt'
## , 'fj_arpu'
all_params = ['prov_id','user_id','cust_id','product_id','area_id','device_number','cust_sex','cert_age','total_fee','jf_flux','fj_arpu',
              'ct_voice_fee','total_flux','total_dura','roam_dura','total_times','total_nums','local_nums','roam_nums','in_cnt','out_cnt',
              'in_dura','out_dura','heyue_flag','is_limit_flag','product_type','5g_flag','visit_cnt','visit_dura','up_flow','down_flow',
              'total_flow','active_days','brand','brand_flag','brand_detail','imei_duration','avg_duratioin']
labels = ['flag']
label = 'flag'

all_params1 = all_params
train = pd.read_csv(filepath_or_buffer=trainFilePath, sep="|", names=all_params + labels, encoding='utf-8')
test = pd.read_csv(filepath_or_buffer=testFilePath, sep=",", names=all_params, encoding='utf-8')

## 对空值和分类字段进行处理
train1 = changeType(train)
train1[label] = train1[label].apply(lambda x: handleFlagField(x))
test1 = changeType(test)

## 生成DMatrix,字段内容必须为数字或者boolean    , 'fj_arpu'
x_featur_params = ['prov_id','cert_age','total_fee','fj_arpu','ct_voice_fee','total_flux','jf_flux',
                   'total_dura','total_times','local_nums','roam_nums','in_cnt','out_cnt','in_dura','out_dura',
                   'heyue_flag','5g_flag','visit_cnt','visit_dura','up_flow','down_flow','total_flow','active_days',
                   'brand_flag','imei_duration','avg_duratioin']

x_featur_params2 = ['prov_id','cert_age','total_fee','fj_arpu','total_flux',
                   'total_dura','total_times','local_nums','roam_nums','in_cnt','out_cnt',
                   'visit_cnt','visit_dura','up_flow','down_flow','total_flow','active_days','imei_duration','avg_duratioin']

xgb_train = xgb.DMatrix(train1[x_featur_params],train1[label])
xgb_test = xgb.DMatrix(test1[x_featur_params])

#y_test = test1['flag'].apply(lambda x: handleFlagField(x))

## 定义模型训练参数
params = {
    'booster': 'gbtree',   ####  gbtree   gblinear
    'objective': 'binary:logistic',  # 多分类的问题  'objective': 'binary:logistic' 二分类，multi:softmax 多分类问题
    'gamma': 0.01,                  # 用于控制是否后剪枝的参数,越大越保守，一般0.1、0.2这样子。
    'max_depth': 6,               # 构建树的深度，越大越容易过拟合
    'min_child_weight': 1.5,
    'eta': 0.01,                  # 如同学习率
    'learning_rate':0.1,
    'subsample':0.5,
    'colsample_bytree':1.0,
    'reg_alpha':1.0
}
## 寻找最佳的 n_estimators
plst = params.items()
## 训练轮数
num_rounds = [215,300,400,500]
num_round = 215
print(num_round)
printTime()
## 模型训练
model = xgb.train(params, xgb_train, num_round)

## 分析特征值
importance = model.get_fscore()
importance = sorted(importance.items(), key=lambda x: x[1], reverse=True)

ans = model.predict(xgb_test)

test1['score'] = ans
#print('预测值AUC为 ：%f' % roc_auc_score(y_test, ans))

# 对结果归一化处理
test1['score1'] = (test1['score'] - test1['score'].min()) / (test1['score'].max() - test1['score'].min())

# 将结果输出到文件
test1.to_csv('D:/data/python/work/result'+str(num_round)+'.csv')

# 显示重要特征
plot_importance(model)
plt.show()
printTime()

实例/xgboost实例练习/特征分析-网格搜索.py

特征分析-网格搜索.py


import tornado.ioloop
import tornado.web
import instagram

Instagram = instagram.Instagram('http://cmashinho.ru/instagram')

class CodeHandler(tornado.web.RequestHandler):
    def get(self):
        code = self.get_argument('code')
        print(Instagram.get_token(code))

class StatisticHandler(tornado.web.RequestHandler):
    def get(self):
        statistic = Instagram.get_statistic()
        print(statistic)

application = tornado.web.Application([
    (r'/instagram', CodeHandler),
    (r'/instagram/statistic', StatisticHandler)
])

if __name__ == '__main__':
    Instagram.print_auth_url()
    application.listen(8000)
    tornado.ioloop.IOLoop.current().start()


from augment import augment_images
from datetime import datetime
from helpers import get_files, log_dir_or_None, write_log, LINE
import numpy as np
import os
import pandas as pd
from pathlib import Path
import re
import skimage.filters as filters
from skimage.measure import regionprops
from skimage.morphology._util import _offsets_to_raveled_neighbors
from tifffile import TiffWriter, imread
from time import time
import torch
from tqdm import tqdm
import zarr

# -------------------
# Generate Train Data
# -------------------
def get_train_data(
                   image_paths,
                   labels_paths,
                   out_dir,
                   shape=(10, 256, 256),
                   n_each=100,
                   channels=('z-1', 'y-1', 'x-1', 'centreness'),
                   scale=(4, 1, 1),
                   log=True
                   ):
    """
    Generate training data from whole ground truth volumes.

    Parameters
    ----------
    image_path: str
        path to the image zarr file, which must be in tczyx dim format (ome bioformats)
    labels_path: str
        path to the labels zarr file, which must be in tczyx dim format
    shape: tuple of int
        Shape of the test data to
    channels: tuple of str
        tuple of channels to be added to the training data.
            Affinities: 'axis-n' (pattern: r'[xyz]-\d+' e.g., 'z-1')
            Centreness: 'centreness'
    scale: tuple of numeric
        Scale of channels. This is used in calculating centreness score.
    log: bool
        Should print out be recorded in out_dir/log.txt?

    Returns
    -------
    xs: list of torch.Tensor
        List of images for training
    ys: list of torch.Tensor
        List of affinities for training
    ids: list of str
        ID strings by which each image and label are named.
        Eventually used for correctly labeling network output

    Notes
    -----
    It takes a very long time to obtain training data with sufficient
    information (as determined by min_affinity param).
    """
    assert len(image_paths) == len(labels_paths)
    for i in range(len(image_paths)):
        print(LINE)
        s = f'Generating training data from image: {image_paths[i]}, labels: {labels_paths[i]}'
        print(s)
        if log:
            write_log(LINE, out_dir)
            write_log(s, out_dir)
        im = zarr.open_array(image_paths[i])
        l = zarr.open_array(labels_paths[i])
        if i == 0:
            xs, ys, ids = get_random_chunks(im, l,
                                            out_dir,
                                            shape=shape,
                                            n=n_each,
                                            channels=channels,
                                            scale=scale,
                                            log=log)
        else:
            xs_n, ys_n, ids_n = get_random_chunks(im, l,
                                                  out_dir,
                                                  shape=shape,
                                                  n=n_each,
                                                  channels=channels,
                                                  scale=scale,
                                                  log=log)
            for j in range(len(xs_n)):
                xs.append(xs_n[j])
                ys.append(ys_n[j])
                ids.append(ids_n[j])
    return xs, ys, ids

def get_random_chunks(
                      image,
                      labels,
                      out_dir,
                      shape=(10, 256, 256),
                      n=25,
                      min_affinity=300,
                      channels=('z-1', 'y-1', 'x-1', 'centreness'),
                      scale=(4, 1, 1),
                      log=True
                      ):
    '''
    Obtain random chunks of data from whole ground truth volumes.

    Parameters
    ----------
    image: array like
        same shape as labels
    labels: array like
        same shape as image
    shape: tuple of int
        shape of chunks to obtain
    n: int
        number of random chunks to obtain
    min_affinity:
        minimum cut off sum of affinities for an image.
        As affinities as belong to {0, 1}, this param
        is the number of voxels that boarder labels.

    Returns
    -------
    xs: list of torch.Tensor
        List of images for training
    ys: list of torch.Tensor
        List of affinities for training
    ids: list of str
        ID strings by which each image and label are named.
        Eventually used for correctly labeling network output

    '''
    im = np.array(image)
    l = np.array(labels)
    assert len(im.shape) == len(shape)
    a = get_training_labels(l, channels=channels, scale=scale)
    xs = []
    ys = []
    labs = []
    i = 0
    df = {'z_start' : [],
          'y_start' : [],
          'x_start' : []}
    while i < n:
        dim_randints = []
        for j, dim in enumerate(shape):
            max_ = im.shape[j] - dim - 1
            ri = np.random.randint(0, max_)
            dim_randints.append(ri)
        # Get the network output: affinities
        s_ = [slice(None, None),] #
        for j in range(len(shape)):
            s_.append(slice(dim_randints[j], dim_randints[j] + shape[j]))
        s_ = tuple(s_)
        y = a[s_]
        if y.sum() > min_affinity * len(channels): # if there are a sufficient number of boarder voxels
            # add coords to output df
            for j in range(len(shape)):
                _add_to_dataframe(j, dim_randints[j], df)
            # Get the network input: image
            s_ = [slice(dim_randints[j], dim_randints[j] + shape[j]) for j in range(len(shape))]
            s_ = tuple(s_)
            x = im[s_]
            x = normalise_data(x)
            # get the GT labels so that later quatitative comparison can be made with final
            #   segmentation
            lab = l[s_] # that's right, be confused by my variable names!!
            # data augmentation for better generalisation
            x, y, lab = augment_images(x, y, lab)
            # add the affinities and image chunk to the training data
            y = torch.from_numpy(y.copy())
            ys.append(y)
            x = torch.from_numpy(x.copy())
            xs.append(x)
            labs.append(lab)
            # another successful addition, job well done you crazy mofo
            i += 1
    print(LINE)
    s = f'Obtained {n} {shape} chunks of training data'
    print(s)
    if log:
        write_log(LINE, out_dir)
        write_log(s, out_dir)
    log_dir = log_dir_or_None(log, out_dir)
    print_labels_info(channels, out_dir=log_dir)
    ids = save_random_chunks(xs, ys, labs, out_dir)
    now = datetime.now()
    d = now.strftime("%y%m%d_%H%M%S")
    df['data_ids'] = ids
    df = pd.DataFrame(df)
    df.to_csv(os.path.join(out_dir, 'start_coords' + d + '.csv'))
    return xs, ys, ids

def _add_to_dataframe(dim, start, df):
    if dim == 0:
        df['z_start'].append(start)
    if dim == 1:
        df['y_start'].append(start)
    if dim == 2:
        df['x_start'].append(start)

# --------------------------
# Lable Generating Functions
# --------------------------

def get_training_labels(
                        l,
                        channels=('z-1', 'y-1', 'x-1', 'centreness'),
                        scale=(4, 1, 1)):
    labels = []
    for chan in channels:
        if chan.startswith('z'):
            axis = 0
        elif chan.startswith('y'):
            axis = 1
        elif chan.startswith('x'):
            axis = 2
        n = re.search(r'\d+', chan)
        if n is not None:
            # get the nth affinity
            n = int(n[0])
            lab = nth_affinity(l, n, axis)
        elif chan == 'centreness':
            # get the centreness score
            lab = get_centreness(l, scale=scale)
        elif chan == 'centreness-log':
            lab = get_centreness(l, scale=scale, log=True)
        elif chan == 'centroid-gauss':
            lab = get_gauss_centroids(l)
        else:
            m = f'Unrecognised channel type: {chan} \n'
            m = m + 'Please enter str of form axis-n for nth affinity \n'
            m = m + 'or centreness for centreness score.'
            raise ValueError(m)
        if chan.endswith('-smooth'):
            lab = smooth(lab)
        labels.append(lab)
    labels = np.stack(labels, axis=0)
    return labels

def nth_affinity(labels, n, axis):
    affinities = []
    labs_pad = np.pad(labels, n, mode='reflect')
    for i in range(labels.shape[axis]):
        s_0 = [slice(None, None)] * len(labs_pad.shape)
        s_0[axis] = slice(i, i + 1)
        s_0 = tuple(s_0)
        s_n = [slice(None, None)] * len(labs_pad.shape)
        s_n[axis] = slice(i + n, i + n + 1)
        s_n = tuple(s_n)
        new = labs_pad[s_0] - labs_pad[s_n]
        new = np.squeeze(new)
        if len(new) > 0:
            affinities.append(new)
    affinities = np.stack(affinities, axis=axis)
    s_ = [slice(n, -n)] * len(labs_pad.shape)
    s_[axis] = slice(None, None)
    s_ = tuple(s_)
    affinities = affinities[s_]
    affinities = np.where(affinities != 0, 1., 0.)
    return affinities

def get_centreness(labels, scale=(4, 1, 1), log=False, power=False):
    """
    Obtains a centreness score for each voxel belonging to a labeled object.
    Values in each object sum to one. Values are inversely proportional
    to euclidian distance from the object centroid.

    Notes
    -----
    Another possible implementation would involve the medioid, as in:
    Lalit, M., Tomancak, P. and Jug, F., 2021. Embedding-based Instance
    Segmentation of Microscopy Images. arXiv.

    Unfortunately, skimage doesn't yet have a method for finding the
    medioid (more dev, *sigh*).
    """
    scale = np.array(scale)
    def dist_score(mask):
        output = np.zeros_like(mask, dtype=np.float32)
        c = np.mean(np.argwhere(mask), axis=0)
        indices, values = inverse_dist_score(
                mask, c, scale, log=log, power=power
                )
        output[indices] = values
        return output
    t = time()
    props = regionprops(labels, extra_properties=(dist_score,))
    new = np.zeros(labels.shape, dtype=np.float32)
    for i, prop in tqdm(enumerate(props), desc='Score centreness'):
        new[prop.slice] += prop.dist_score
    new = np.nan_to_num(new)
    print('------------------------------------------------------------')
    print(f'Obtained centreness scores in {time() - t} seconds')
    return new

def inverse_dist_score(mask, centroid, scale, log, power):
    '''
    Compute euclidian distances of each index from a mask
    representing a single object from the centroid of said object

    Uses scale to account for annisotropy in image
    '''
    indices = np.argwhere(mask > 0)
    distances = []
    centre = centroid
    for i in range(indices.shape[0]):
        ind = indices[i, ...]
        diff = (centre - ind) * scale
        dist = np.linalg.norm(diff)
        if log and abs(dist) > 0:
            m = f'Infinite value with distance of {dist}'
            dist = np.log(dist)
            assert not np.isinf(dist), m
        if power:
            dist = 2 ** dist
        distances.append(dist)
    distances = np.array(distances)
    if log:
        distances = distances + np.abs(distances.min()) # bring min value to 0
    norm_distances = distances / distances.max()
    values = (1 - norm_distances)
    indices = tuple(indices.T.tolist())
    return indices, values

# not used
def get_gauss_centroids(labels, sigma=1, z=0):
    centroids = [prop['centroid'] for prop in regionprops(labels)]
    centroids = tuple(np.round(np.stack(centroids).T).astype(int))
    centroid_image = np.zeros(labels.shape, dtype=float)
    centroid_image[centroids] = 1.
    gauss_cent = []
    for i in range(labels.shape[z]):
        s_ = [slice(None, None)] * labels.ndim
        s_[z] = slice(i, i+1)
        s_ = tuple(s_)
        plane = np.squeeze(centroid_image[s_])
        gauss_cent.append(filters.gaussian(plane, sigma=sigma))
    out = np.stack(gauss_cent, axis=z)
    out = out - out.min()
    out = out / out.max()
    #print(out.dtype, out.shape, out.max(), out.min())
    return out

def smooth(image, z=0, sigma=1):
    out = []
    for i in range(image.shape[z]):
        s_ = [slice(None, None)] * image.ndim
        s_[z] = slice(i, i+1)
        s_ = tuple(s_)
        plane = np.squeeze(image[s_])
        out.append(filters.gaussian(plane, sigma=sigma))
    out = np.stack(out, axis=z)
    return out

# not currently referenced, uses nth_affinity() for generality
def get_affinities(image):
    """
    Get short-range voxel affinities for a segmentation. Affinities are
    belonging to {0, 1} where 1 represents a segment boarder voxel in a
    particular direction. Affinities are produced for each dimension of
    the labels and each dim has its own channel (e.g, (3, z, y, x)).

    Note
    ----
    Others may represent affinities with {-1, 0}, because technically...
    My network wasn't designed for this :)
    """
    padded = np.pad(image, 1, mode='reflect')
    affinities = []
    for i in range(len(image.shape)):
        a = np.diff(padded, axis=i)
        a = np.where(a != 0, 1.0, 0.0)
        a = a.astype(np.float32)
        s_ = [slice(1, -1)] * len(image.shape)
        s_[i] = slice(None, -1)
        s_ = tuple(s_)
        affinities.append(a[s_])
    affinities = np.stack(affinities)
    return affinities

# -------------
# Log and Print
# -------------

def print_labels_info(channels, out_dir=None, log_name='log.txt'):
    print(LINE)
    s = f'Training labels have {len(channels)} output channels: \n'
    print(s)
    if out_dir is not None:
            write_log(LINE, out_dir, log_name)
            write_log(s, out_dir, log_name)
    for i, chan in enumerate(channels):
        affinity_match = re.search(r'[xyz]-\d*', chan)
        if affinity_match is not None:
            n = f'{affinity_match[0]} affinities'
        elif chan == 'centreness':
            n = 'centreness score'
        elif chan == 'centreness-log':
            n = 'log centreness score'
        elif chan == 'centroid-gauss':
            n = 'gaussian centroids'
        else:
            n = 'Unknown channel type'
        s = f'Channel {i}: {n}'
        print(s)
        if out_dir is not None:
            write_log(s, out_dir, log_name)

# -----------
# Save Output
# -----------

def save_random_chunks(xs, ys, labs, out_dir):
    '''
    Save the random chunks as they are sampled
    '''
    os.makedirs(out_dir, exist_ok=True)
    assert len(xs) == len(ys)
    ids = []
    # iterate over the sample
    for i in range(len(xs)):
        # get the datetime to give the samples unique names
        now = datetime.now()
        d = now.strftime("%y%m%d_%H%M%S") + '_' + str(i)
        ids.append(d)
        # save the image
        i_name = d + '_image.tif'
        i_path = os.path.join(out_dir, i_name)
        with TiffWriter(i_path) as tiff:
            tiff.write(xs[i].numpy())
        # save the labels
        l_name = d + '_labels.tif'
        l_path = os.path.join(out_dir, l_name)
        with TiffWriter(l_path) as tiff:
            tiff.write(ys[i].numpy())
        # save the ground truth segmentation
        s_name = d + '_GT.tif'
        s_path = os.path.join(out_dir, s_name)
        with TiffWriter(s_path) as tiff:
            tiff.write(labs[i]) # this is already ndarray not tensor
    assert len(ids) == len(ys)
    print('------------------------------------------------------------')
    print('Training data saved at:')
    print(out_dir)
    return ids

# ---------------
# Load Train Data
# ---------------

def load_train_data(
                    data_dir,
                    id_regex=r'\d{6}_\d{6}_\d{1,3}',
                    x_regex=r'\d{6}_\d{6}_\d{1,3}_image.tif',
                    y_regex=r'\d{6}_\d{6}_\d{1,3}_labels.tif'
                    ):
    '''
    Load train data from a directory according to a naming convention

    Parameters
    ----------
    data_dir: str
        Directory containing data
    id_regex: r string
        regex that will be used to extract IDs that will
        be used to label network output
    x_regex: r string
        regex that represents image file names, complete with
        extension (tiff please)
    y_regex: r string
        regex that represents training label files, complete
        with extension (tiff please)

    Returns
    -------
    xs: list of torch.Tensor
        List of images for training
    ys: list of torch.Tensor
        List of affinities for training
    ids: list of str
        ID strings by which each image and label are named.
        Eventually used for correctly labeling network output

    '''
    # Get file names for images and training labels
    x_paths, y_paths = get_files(
                                 data_dir,
                                 x_regex=x_regex,
                                 y_regex=x_regex
                                 )
    # Get IDs
    id_pattern = re.compile(id_regex)
    ids = []
    x_paths.sort()
    y_paths.sort()
    for i in range(len(x_paths)):
        xn = Path(x_paths[i]).stem # this could have been avoided
        yn = Path(y_paths[i]).stem # why would I bother now though?!
        # assumes there will be a match for each
        xid = id_pattern.search(xn)[0]
        yid = id_pattern.search(yn)[0]
        m = 'There is a mismatch in image and label IDs'
        assert xid == yid, m
        ids.append(xid)
    # Get images and training labels in tensor form
    xs = []
    ys = []
    for i in range(len(x_paths)):
        xp = x_paths[i]
        yp = y_paths[i]
        x = imread(xp)
        x = normalise_data(x)
        y = imread(yp)
        xs.append(torch.from_numpy(x))
        ys.append(torch.from_numpy(y))
    # returns objects in the same manner as get_train_data()
    print('------------------------------------------------------------')
    print(f'Loaded {len(xs)} sets of training data')
    print_labels_info(ys[0].shape)
    return xs, ys, ids

# ------------------------
# General Helper Functions
# ------------------------

def normalise_data(image):
    '''
    Bring image values to between 0-1

    Parameters
    ----------
    image: np.array
        Image data. Dtype should be float.
    '''
    im = image / image.max()
    return im

if __name__ =="__main__":
    #
    pass


import sys
from PyQt5 import QtWidgets,QtCore
from Inventory.InventoryView import *

class ViewInventoryList(QtWidgets.QGridLayout):
    def __init__(self, frame):
        super().__init__()
        self.frame = frame
        self.frame.setWindowTitle("View Inventory")
        self.init_ui()

    def add_table_entries(self):
        db_connection = InventoryDatabase()
        products = db_connection.get_product_list()
        for x in range(len(products)):
            self.tInventory_Table.setItem(x,0,QtWidgets.QTableWidgetItem(str(products[x].id)))
            self.tInventory_Table.setItem(x,1,QtWidgets.QTableWidgetItem(str(products[x].quantity)))
            self.tInventory_Table.setItem(x,2,QtWidgets.QTableWidgetItem(products[x].supplier))
            self.tInventory_Table.setItem(x,3,QtWidgets.QTableWidgetItem(str(products[x].last_updated)))
        db_connection.close_connection()

    def init_ui(self):
        #Create Widgets
        self.lInventory_Details = QtWidgets.QLabel("INVENTORY LIST")
        self.lInventory_Details.setStyleSheet('QLabel { font-size: 12pt; padding: 10px;}')

		#Inventory Table#
        self.tInventory_Table = QtWidgets.QTableWidget()
        self.tInventory_Table.setRowCount(10)
        self.tInventory_Table.setColumnCount(4)
        self.tInventory_Table.setHorizontalHeaderLabels(["Inventory Number", "Amount", "Buyer", "Date"])
        self.tInventory_Table.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents)
        tablewidth = self.tInventory_Table.width() + 4
        self.tInventory_Table.setColumnWidth(0, tablewidth / 6)
        self.tInventory_Table.setColumnWidth(1, tablewidth / 6)
        self.tInventory_Table.setColumnWidth(2, tablewidth / 2)
        self.tInventory_Table.setColumnWidth(3, tablewidth / 6)
        self.tInventory_Table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)

        self.Add_Inventory_Table = QtWidgets.QPushButton("Add Inventory")
        self.Add_Inventory_Table.setStyleSheet('QPushButton { font-size: 12pt; padding: 10px;}')

        ###backend function
        self.add_table_entries()

        self.bBack = QtWidgets.QPushButton("Back")
        self.bBack.setStyleSheet('QPushButton { font-size: 12pt; padding: 10px;}')
        self.bBack.setFixedWidth(200)

        self.setColumnStretch(6,1)
        self.setColumnStretch(1,1)
        self.setRowStretch(16,1)

        #Add Widgets
        self.addWidget(self.lInventory_Details, 0, 2, 1, 1)
        self.addWidget(self.tInventory_Table, 1, 2, 10, 3)
        self.addWidget(self.bBack, 15, 4, 1, 1)


#imports

import pandas as pd
import numpy as np
import math

from shapely.geometry import Point, Polygon
import matplotlib.pyplot as plt
import geopandas as gpd
#from seaborn import palplot

pd.options.display.max_columns =200
pd.options.display.max_rows =500
pd.options.display.max_colwidth =500

## functions

def route_stats_split_coordinates(route_id):
    coordinates_strings = [latlon.split(',') for latlon in route_id.all_stop_latlon.split(';')]
    coordinates_floats = [(float(lat), float(lon)) for lat, lon in coordinates_strings]

    return coordinates_floats

def route_stats_split_stops(route_id, col):
    return route_id[col].split(';')

def route_stats_2_stops(route_stats):
    route_stats = route_stats.copy()

    route_stats_stops = pd.DataFrame(columns=['route_id', 'stop_index', 'stop_id', 'coordinates'])

    route_stats['all_stop_latlon'] = route_stats.apply(lambda r: route_stats_split_coordinates(r), axis=1)
    route_stats['all_stop_id'] = route_stats.apply(lambda r: route_stats_split_stops(r, 'all_stop_id'), axis=1)

    for route_id in route_stats['route_id']:
        route_id_stops = pd.DataFrame()
        route_id_stops['stop_id'] = pd.Series(
            route_stats[route_stats['route_id'] == route_id]['all_stop_id'].tolist()[0])
        route_id_stops['coordinates'] = pd.Series(
            route_stats[route_stats['route_id'] == route_id]['all_stop_latlon'].tolist()[0])
        route_id_stops['stop_index'] = route_id_stops.index + 1
        route_id_stops['route_id'] = route_id

        route_stats_stops = route_stats_stops.append(route_id_stops)

    route_stats_stops = route_stats_stops[['route_id', 'stop_index', 'stop_id', 'coordinates']] \
        .sort_values(by=['route_id', 'stop_index'])

    return route_stats_stops

def plot_route_id_stops(route_stats_stops):
    route_stats_stops['coordinates'] = route_stats_stops['coordinates'].apply(Point)
    gdf = gpd.GeoDataFrame(route_stats_stops, geometry='coordinates')

    route_ids = dict(tuple(gdf.groupby('route_id')))

    fig = plt.figure(num=None, figsize=(10, 8))

    first_route_id = list(route_ids.keys())[0]

    ax = route_ids[first_route_id].plot()

    for route_id in route_ids.keys():
        if route_id == first_route_id:
            pass
        else:
            route_ids[route_id].plot(ax=ax)

def set_buffer(route_stats_stops, buffer_rad=0.01):
    route_stats_stops['coordinates'] = route_stats_stops['coordinates'].apply(Point)
    gdf = gpd.GeoDataFrame(route_stats_stops, geometry='coordinates')
    gdf['buffer'] = gdf.buffer(buffer_rad)
    gdf.set_index('stop_id', inplace=True, drop=False)

    return gdf

def find_route_id_similarity(trip, route_stats_stops_gdf, route_stats_unique):
    similarity_summary = {}

    for route_id in route_stats_unique.route_id:

        route_id_buffers = route_stats_stops_gdf[route_stats_stops_gdf['route_id'] == route_id]['buffer']

        route_id_stops_results = {key: trip.within(geom) for key, geom in route_id_buffers.items()}

        route_id_stops_summary = {}
        for stop in route_id_stops_results.keys():
            route_id_stops_summary[stop] = np.any(route_id_stops_results[stop])

        route_id_mean = np.mean(list(route_id_stops_summary.values()))

        route_id_count = len(route_id_stops_summary)

        similarity_summary[str(route_id) + '_mean'] = [route_id_mean]

        similarity_summary[str(route_id) + '_cnt'] = [route_id_count]

    return pd.DataFrame(similarity_summary)

def match_route_id(trip, route_stats_unique, min_match_prob=0.8, floor_val=0.05):
    match_summary = {}

    # drop route_ids with % prob < min_match_prob
    for route_id in route_stats_unique.route_id:

        # for each route
        if trip[str(route_id) + '_mean'] >= min_match_prob:
            match_summary[route_id] = round(math.floor(trip[str(route_id) + '_mean'] / floor_val) * floor_val, 2)

    if not match_summary:
        return 'No match'

    else:

        # choose best match
        max_match = max(match_summary.values())

        match_summary = {key: val for key, val in match_summary.items() if val == max_match}

        if len(match_summary) == 1:

            # if
            return list(match_summary.keys())[0]

        else:
            max_match_route_ids = match_summary.keys()
            match_summary = {}  # reset match_summary to contain route_ids number of stops
            for route_id in max_match_route_ids:
                match_summary[route_id] = trip[str(route_id) + '_cnt']

            # match_summary = sorted(match_summary.items(), key=lambda x: x[1], reverse=True)

            max_match = max(match_summary.values())

            match_summary = {key: val for key, val in match_summary.items() if val == max_match}

            if len(match_summary) == 1:

                # if
                return list(match_summary.keys())[0]
            else:

                # if
                return 'No match'

## script

train = pd.read_csv('train.csv', encoding='windows-1255')
train.drop_duplicates(subset=['trip_index']).route_id.value_counts()
route_stats = pd.read_csv('route_stats.csv', index_col=[0])
route_stats_unique = route_stats.groupby(['route_id','all_stop_id','all_stop_latlon'],
                                        as_index=False)['date'].agg(['min','max'])\
                                        .rename(columns = {'min':'start_date', 'max': 'end_date'})\
                                        .reset_index().sort_values(by = ['route_id','start_date'])

route_stats_stops = route_stats_2_stops(route_stats_unique)
route_stats_stops_gdf = set_buffer(route_stats_stops)
train['coordinates'] = list(zip(train.lat, train.lon))
train['coordinates'] = train['coordinates'].apply(Point)

train_gdf = gpd.GeoDataFrame(train, geometry='coordinates')
train_similarity_matrix = train_gdf.groupby(['trip_index',
                'route_id']).apply(lambda trip: find_route_id_similarity(trip, route_stats_stops_gdf, route_stats_unique))

train_similarity_matrix.tail(1).apply(lambda trip: match_route_id(trip, route_stats_unique), axis=1).to_frame()

train_trips = train_similarity_matrix.apply(lambda trip: match_route_id(trip, route_stats_unique), axis=1).to_frame()

train_trips.rename(columns = {0: 'route_id_pred'}, inplace=True)

train_trips.reset_index(inplace=True)

train_trips.drop(columns=['level_2'], inplace=True)

train_trips['route_id_pred_true'] = np.where(train_trips.route_id==train_trips.route_id_pred,1,0)


import json
import re
from datetime import datetime
from typing import List

from app.dao.config.GConfigDao import GConfigDao
from app.dao.test_case.TestCaseAssertsDao import TestCaseAssertsDao
from app.dao.test_case.TestCaseDao import TestCaseDao
from app.middleware.AsyncHttpClient import AsyncRequest
from app.models.constructor import Constructor
from app.models.test_case import TestCase
from app.utils.decorator import case_log
from app.utils.gconfig_parser import StringGConfigParser, JSONGConfigParser, YamlGConfigParser
from app.utils.logger import Log

class Executor(object):
    log = Log("Executor")
    el_exp = r"\$\{(.+?)\}"
    pattern = re.compile(el_exp)
    # 需要替换全局变量的字段
    fields = ['body', 'url', 'request_header']

    def __init__(self, log=None):
        if log is None:
            self._logger = list()
            self._main = True
        else:
            self._logger = log
            self._main = False

    @property
    def logger(self):
        return self._logger

    def append(self, log_data, content):
        log_data.append("[{}]: 步骤开始 -> {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), content))

    @case_log
    def parse_gconfig(self, data: TestCase, *fields):
        """
        解析全局变量
        """
        for f in fields:
            self.parse_field(data, f)

    @case_log
    def get_parser(self, key_type):
        """获取变量解析器
        """
        if key_type == 0:
            return StringGConfigParser.parse
        if key_type == 1:
            return JSONGConfigParser.parse
        if key_type == 2:
            return YamlGConfigParser.parse
        raise Exception(f"全局变量类型: {key_type}不合法, 请检查!")

    @case_log
    def parse_field(self, data: TestCase, field):
        """
        解析字段
        """
        try:
            field_origin = getattr(data, field)
            variables = self.get_el_expression(field_origin)
            for v in variables:
                key = v.split(".")[0]
                # TODO 注意此处实时查询数据库，后续需要改成Redis
                cf = GConfigDao.get_gconfig_by_key(key)
                if cf is not None:
                    # 解析变量
                    parse = self.get_parser(cf.key_type)
                    new_value = parse(cf.value, v)
                    new_field = field_origin.replace("${%s}" % v, new_value)
                    setattr(data, field, new_field)
                    field_origin = new_field
        except Exception as e:
            Executor.log.error(f"查询全局变量失败, error: {str(e)}")
            raise

    def parse_params(self, logger, data: TestCase, params: dict):
        self.append(logger, "正在替换变量")
        try:
            for c in data.__table__.columns:
                field_origin = getattr(data, c.name)
                if not isinstance(field_origin, str):
                    continue
                variables = self.get_el_expression(field_origin)
                for v in variables:
                    key = v.split(".")
                    if not params.get(key[0]):
                        continue
                    result = params
                    for branch in key:
                        if isinstance(branch, int):
                            # 说明路径里面的是数组
                            result = result[int(branch)]
                        else:
                            result = result.get(branch)
                    if c.name != "request_header":
                        new_value = json.dumps(result, ensure_ascii=False)
                    else:
                        new_value = result
                        if new_value is None:
                            self.append(logger, "替换变量失败, 找不到对应的数据")
                            continue
                    new_field = field_origin.replace("${%s}" % v, new_value)
                    setattr(data, c.name, new_field)
                    field_origin = new_field
        except Exception as e:
            Executor.log.error(f"替换变量失败, error: {str(e)}")
            raise Exception(f"替换变量失败, error: {str(e)}")

    @case_log
    def get_constructor(self, case_id):
        """获取构造数据"""
        return TestCaseDao.select_constructor(case_id)

    async def execute_constructors(self, logger, path, params, req_params, constructors: List[Constructor]):
        """开始构造数据"""
        if len(constructors) == 0:
            self.append(logger, "构造方法为空, 跳出构造环节")
        for i, c in enumerate(constructors):
            await self.execute_constructor(logger, i, path, params, req_params, c)

    async def execute_constructor(self, logger, index, path, params, req_params, constructor: Constructor):
        if constructor.type == 0:
            self.append(logger, f"当前路径: {path}, 第{index + 1}条构造方法")
            # 说明是case
            executor = Executor(logger)
            data = json.loads(constructor.constructor_json)
            new_param = data.get("params")
            if new_param:
                temp = json.loads(new_param)
                req_params.update(temp)
            case_id = data.get("case_id")
            testcase, _ = TestCaseDao.query_test_case(case_id)
            result, err = await executor.run(case_id, params, req_params, f"{path}->{testcase.name}")
            if err:
                raise Exception(f"{path}->{testcase.name} 第{index + 1}个构造方法执行失败: {err}")
            params[constructor.value] = result
            self.parse_params(logger, testcase, params)

    @case_log
    async def run(self, case_id: int, params_pool: dict = None, request_param: dict = None, path="主case"):
        """
        开始执行测试用例
        """
        result = dict()

        # 初始化case全局变量, 只存在于case生命周期 注意 它与全局变量不是一套逻辑
        case_params = params_pool
        if case_params is None:
            case_params = dict()

        req_params = request_param
        if req_params is None:
            req_params = dict()

        try:
            case_info, err = TestCaseDao.query_test_case(case_id)
            if err:
                return result, err

            # Step1: 替换全局变量
            self.parse_gconfig(case_info, *Executor.fields)

            # Step2: 获取构造数据
            constructors = self.get_constructor(case_id)

            # Step3: 执行构造方法
            await self.execute_constructors(self.logger, path, case_params, req_params, constructors)

            # Step4: 获取断言
            asserts, err = TestCaseAssertsDao.list_test_case_asserts(case_id)

            if err:
                return result, err

            # Step5: 获取后置操作
            # TODO

            # Step6: 批量改写主方法参数
            self.parse_params(self.logger, case_info, case_params)

            if case_info.request_header != "":
                headers = json.loads(case_info.request_header)
            else:
                headers = dict()
            if "Content-Type" not in headers:
                headers['Content-Type'] = "application/json; charset=UTF-8"
            if case_info.body != '':
                body = case_info.body
            else:
                body = None

            # Step5: 替换请求参数
            body = self.replace_body(request_param, body)

            # Step6: 完成http请求

            if "form" not in headers['Content-Type']:
                request_obj = AsyncRequest(case_info.url, headers=headers,
                                           data=body.encode() if body is not None else body)
            else:
                if body is not None:
                    body = json.loads(body)
                request_obj = AsyncRequest(case_info.url, headers=headers, data=body)
            method = case_info.request_method.upper()
            response_info = await request_obj.invoke(method)
            response_info["url"] = case_info.url
            response_info["request_method"] = method

            # 执行完成进行断言
            response_info["asserts"] = self.my_assert(asserts, response_info)
            # 日志输出, 如果不是开头用例则不记录
            if self._main:
                response_info["logs"] = "\n".join(self.logger)
            return response_info, None
        except Exception as e:
            Executor.log.error(f"执行用例失败: {str(e)}")
            return result, f"执行用例失败: {str(e)}"

    @case_log
    def replace_body(self, req_params, body):
        """根据传入的构造参数进行参数替换"""
        try:
            if body:
                data = json.loads(body)
                for k, v in req_params.items():
                    if data.get(k) is not None:
                        data[k] = v
                return json.dumps(data, ensure_ascii=False)
            self.append(self.logger, f"body为空, 不进行替换")
        except Exception as e:
            self.append(self.logger, f"替换请求body失败, {e}")
        return body

    @staticmethod
    def get_time():
        return datetime.now().strftime('%Y-%m-%d %H:%M:%S')

    @case_log
    def my_assert(self, asserts: List, response_info) -> dict:
        """
        断言验证
        """
        result = dict()
        if len(asserts) == 0:
            self.append(self.logger, "[{}]: 未设置断言, 用例结束".format(Executor.get_time()))
            return result
        for item in asserts:
            a, err = self.parse_variable(response_info, item.expected)
            if err:
                result[item.id] = {"status": False, "msg": f"解析变量失败, {err}"}
                continue
            b, err = self.parse_variable(response_info, item.actually)
            if err:
                result[item.id] = {"status": False, "msg": f"解析变量失败, {err}"}
                continue
            try:
                a, b = self.translate(a), self.translate(b)
                status, err = self.ops(item.assert_type, a, b)
                result[item.id] = {"status": status, "msg": err}
            except Exception as e:
                result[item.id] = {"status": False, "msg": str(e)}
        return result

    @case_log
    def ops(self, assert_type: str, a, b) -> (bool, str):
        """
        通过断言类型进行校验
        """
        if assert_type == "equal":
            if a == b:
                return True, f"预期结果: {a} == 实际结果: {b}"
            return False, f"预期结果: {a} != 实际结果: {b}"
        if assert_type == "not_equal":
            if a != b:
                return True, f"预期结果: {a} != 实际结果: {b}"
            return False, f"预期结果: {a} == 实际结果: {b}"
        if assert_type == "in":
            if a in b:
                return True, f"预期结果: {a} in 实际结果: {b}"
            return False, f"预期结果: {a} in 实际结果: {b}"
        return False, "不支持的断言方式"

    @case_log
    def get_el_expression(self, string: str):
        """获取字符串中的el表达式
        """
        return re.findall(Executor.pattern, string)

    @case_log
    def translate(self, data):
        """
        反序列化为Python对象
        """
        return json.loads(data)

    @case_log
    def parse_variable(self, response_info, string: str):
        """
        解析返回response中的变量
        """
        data = self.get_el_expression(string)
        if len(data) == 0:
            return string, None
        data = data[0]
        el_list = data.split(".")
        # ${response.data.id}
        result = response_info
        try:
            for branch in el_list:
                if isinstance(branch, int):
                    # 说明路径里面的是数组
                    result = result[int(branch)]
                else:
                    result = result.get(branch)
        except Exception as e:
            return None, f"获取变量失败: {str(e)}"
        return json.dumps(result, ensure_ascii=False), None


# -*- encoding: utf-8 -*-
import numpy as np
import math

def loadDataSet():
    postingList=[['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],
                 ['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
                 ['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],
                 ['stop', 'posting', 'stupid', 'worthless', 'garbage'],
                 ['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
                 ['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]
    # 1代表侮辱性文字，0代表正常言论
    classVec = [0, 1, 0, 1, 0, 1]
    return postingList, classVec

def createVocabList(dataSet):
    # 创建一个空集
    vocabSet = set([])
    for document in dataSet:
        # 创建两个集合的并集
        vocabSet = vocabSet | set(document)
    return list(vocabSet)

def setOfWords2Vec(vocabList, inputSet):
    returnVec = [0] * len(vocabList)
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)] = 1
        else:
            print('单词: %s不在我的词汇表中！' %(word))
    return returnVec

postingList, classList = loadDataSet()
vocabList = createVocabList(postingList)
print(vocabList)
# vocabList是一张词汇表[a, b, c]，postingList[1](ade)表示一篇文章，如果出现一个词则使用1标示[1, 0, 0]
# 以上是将词的出现与否作为一个特征，此称为词集模型（set-of-words model）
returnVec = setOfWords2Vec(vocabList, postingList[1])
print(returnVec)

'''
1)朴素贝叶斯分类器；
2)1代表侮辱性文字，0代表正常言论
classVec = [0, 1, 0, 1, 0, 1]
trainMatrix:
[[1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0],
[0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]]
'''
def trainNB0(trainMatrix, trainCategory):
    # 所有文档构成的文档矩阵，获取文档数量，一行代表一篇
    numTrainDocs = len(trainMatrix)
    # 获取文档的单词数，注意这里是指词汇表的数量
    numWords = len(trainMatrix[0])
    # 因为侮辱性使用1表示，所以sum求和为侮辱性文章数量，再除以文章总数量，得到侮辱性文章的概率（先验概率）
    pAbusive = sum(trainCategory) / float(numTrainDocs)
    p0Num = np.ones(numWords)
    p1Num = np.ones(numWords)
    p0Denom = 2.0
    p1Denom = 2.0
    for i in range(numTrainDocs):
        # 在侮辱性文章中，获取每个单词出现的次数以及出现单词的总次数
        if trainCategory[i] == 1:
            p1Num += trainMatrix[i]
            p1Denom += sum(trainMatrix[i])
        # 在正常的文章中，获取每个单词出现的次数以及出现单词的总次数
        else:
            p0Num += trainMatrix[i]
            p0Denom += sum(trainMatrix[i])
    # 侮辱性文章的概率向量
    p1Vect = np.log(p1Num / p1Denom)
    # 正常的文章的概率向量
    p0Vect = np.log(p0Num / p0Denom)
    return p0Vect, p1Vect, pAbusive

myVocabList = createVocabList(postingList)
trainMatrix = []
for doc in postingList:
    trainMatrix.append(setOfWords2Vec(myVocabList, doc))
print('======================train matrix=======================')
print(trainMatrix)
p0V, p1V, pAb = trainNB0(trainMatrix, classList)
print(p0V)
print(p1V)
print(pAb)

'''
计算朴素贝叶斯：
1)给出的某一篇文章词向量:[0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
2)词向量 * 侮辱性文章的概率向量 * 先验概率: 由于侮辱性文章的概率向量已经求过log，直接*词向量即可，再将*先验概率也转换为log: + log(侮辱性先验概率)
3)词向量 * 正常性文章的概率向量 * 先验概率: 由于正常性文章的概率向量已经求过log，直接*词向量即可，再将*先验概率也转换为log: + log(正常性先验概率)
4)比较2和3，看谁的概率大，那么此向量文章就属于哪类
'''
def classifyNB(wordsVec, p0Vec, p1Vec, pAb):
    p1 = np.sum(wordsVec * p1Vec) + np.log(pAb)
    p0 = np.sum(wordsVec * p0Vec) + np.log(1.0 - pAb)
    if(p1 > p0):
        return 1
    else:
        return 0

def testingNB():
    # 加载训练数据以及对应的分类标签
    postingList, classesList = loadDataSet()
    # 根据训练数据创建词表库
    myVocabList = createVocabList(postingList)
    # 以词表库为基础，将训练数据文章转化为矩阵数据集，出现的单词为1，否则为0
    trainMatrix = []
    for doc in postingList:
        trainMatrix.append(setOfWords2Vec(myVocabList, doc))
    # 已训练数据为基础计算出p0Vec（所有训练文章的正常性文章中的词向量概率）和p1Vec（所有训练文章的侮辱性文章中的词向量概率）以及pAb（侮辱性分类的先验概率）
    p0Vec, p1Vec, pAb = trainNB0(trainMatrix, classesList)
    # 测试文章
    testDocment = ['love', 'my', 'dalmation']
    # 将测试文章转换为词向量
    testDocVec = setOfWords2Vec(myVocabList, testDocment)
    print('测试文章被分类为: %s' %(classifyNB(testDocVec, p0Vec, p1Vec, pAb)))
    testDocment = ['stupid', 'garbage']
    testDocVec = setOfWords2Vec(myVocabList, testDocment)
    print('测试文章被分类为: %s' %(classifyNB(testDocVec, p0Vec, p1Vec, pAb)))

testingNB()

'''
  以上朴素贝叶斯分类算法中，是将每个词的出现与否作为一个特征，被称为词集模型（set-of-words model）；
  如果一个词在文档中出现不止一次，可能意味着包含该词是否出现在文档中所不能表达的某种信息，此种被称为词袋模型（bag-of-words model）；
  在词袋中，每个单词可以出现多次，而在词集中，每个词只能出现一次。为适应词袋模型
，需要对函数setOfWords2Vec()进行修改为bagOfWords2Vec().
'''
def bagOfWords2Vec(vocabList, inputSet):
    returnVec = [0] * len(vocabList)
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)] += 1
    return returnVec

def textParse(bigString):
    import re
    listOfTokens = re.split(r'[\W*]', bigString)
    return [token.lower() for token in listOfTokens if len(token) > 2]

def spamText():
    import random
    docList = []
    fullTest = []
    classList = []
    for i in range(1, 26):
        spamEmailText = open('email/spam/%d.txt' %(i)).read()
        # 解析邮件内容进行字符串分割
        wordList = textParse(spamEmailText)
        # 将解析的一篇邮件内容放到docList，docList包含所有邮件内容，一行代表一封邮件
        docList.append(wordList)
        # 将所有的邮件内容一篇篇追加到fullText数组中
        fullTest.extend(wordList)
        # 将解析的spam垃圾邮件标示分类为1
        classList.append(1)

        hamEmailText = open('email/ham/%d.txt' %(i)).read()
        wordList = textParse(hamEmailText)
        docList.append(wordList)
        fullTest.extend(wordList)
        # 将解析的ham邮件标示分类为0
        classList.append(0)

    # 通过docList创建自己的词汇表
    vocabList = createVocabList(docList)
    trainingSet = list(range(50))
    testSet = []
    for i in range(10):
        # 随机构建训练集数据
        # random.uniform(a, b) 用于生成一个指定范围内的随机浮点数
        randIndex = int(random.uniform(0, len(trainingSet)))
        # randIndex为在0~50取的其中一个值，然后在trainingSet取值
        testSet.append(trainingSet[randIndex])
        # 从训练集数据中随机抽取10个测试集合，抽取之后需要从训练集中删除。这种随机选择数据的一部分作为训练集，
        # 而剩余部分作为测试集的过程称为留存交叉验证（hold-out cross validation)
        del(trainingSet[randIndex])
    trainMatrix = []
    trainClasses = []
    #print(docList)
    for docIndex in trainingSet:
        # 计算出一篇邮件的词向量，并放入到训练集矩阵中
        docVec = setOfWords2Vec(vocabList, docList[docIndex])
        trainMatrix.append(docVec)
        # 同时放入对应的分类标签类型
        trainClasses.append(classList[docIndex])
    # 从训练数据集中计算出p0Vec（正常邮件词向量概率）和p1Vec（垃圾邮件词向量概率）以及pSpam（垃圾邮件分类的先验概率）
    p0Vec, p1Vec, pSpam = trainNB0(trainMatrix, trainClasses)
    # 从测试数据集来测试分类邮件
    errorCount = 0
    for docIndex in testSet:
        testDocVec = setOfWords2Vec(vocabList, docList[docIndex])
        if classifyNB(testDocVec, p0Vec, p1Vec, pSpam) != classList[docIndex]:
            errorCount += 1
    print('从%d封测试邮件中分类错误率为: %.3f' %(len(testSet), errorCount / float(len(testSet))))

spamText()


import allure
import requests
import time
from allure_commons.types import AttachmentType
from selenium import webdriver
import pytest
from selenium.webdriver.common.keys import Keys

class TestPageSearch:
    def setup(self):
        self.driver = webdriver.Chrome(("C:/Users/shubina/PycharmProjects/chromedriver"))
        self.driver.maximize_window()
        self.urls = ['http://staging-leto19.letomall.ru/', 'http://staging-kry19.planeta-mall.ru/',
                     'http://staging-nkz19.planeta-mall.ru/', 'http://staging-aura19.planeta-mall.ru/',
                     'http://staging-ufa19.planeta-mall.ru/']

    def teardown(self):
        self.driver.quit()

    def test_link_to_legal_information(self):
        driver = self.driver
        urls = self.urls
        errors = []
        for url in urls:
            driver.get(url)
            driver.find_element_by_class_name('footerLegalLink').click()
            driver.implicitly_wait(3)
            driver.switch_to.window(driver.window_handles[1])
            document_type = driver.find_element_by_tag_name('embed').get_attribute('type')
            try:
                assert document_type == 'application/pdf'
                driver.switch_to.window(driver.window_handles[0])
            except Exception as e:
                errors.append('Can`t open pdf document on the page  ' + url)
                driver.switch_to.window(driver.window_handles[0])
        assert not errors, "errors occured:\n{}".format("\n".join(errors))

    def test_link_rutorika(self):
        driver = self.driver
        urls = self.urls
        errors = []
        for url in urls:
            driver.get(url)
            driver.find_element_by_class_name('rutorika').send_keys(Keys.ENTER)
            driver.switch_to.window(driver.window_handles[1])
            try:
                assert driver.current_url == 'https://rutorika.ru/'
                driver.close()
                driver.switch_to.window(driver.window_handles[0])
            except Exception as e:
                errors.append('Didn`t open link Rutorika from page ' + url)
                driver.close()
                driver.switch_to.window(driver.window_handles[0])
        assert not errors, "errors occured:\n{}".format("\n".join(errors))


import abc
import numpy as np
import tensorflow as tf
import copy
from collections import defaultdict

import gym
from gym import Env as GymEnv
from gym.spaces import Discrete, Box

from dps import cfg
from dps.rl import RolloutBatch
from dps.utils import Parameterized, gen_seed, Param

class Env(Parameterized, GymEnv, metaclass=abc.ABCMeta):
    ta_order = "obs action reward done log_prob entropy util policy_state".split()
    info_shapes = None
    n_rollouts = None
    has_differentiable_loss = False

    def __init__(self, **kwargs):
        self._samplers = {}
        super(Env, self).__init__(**kwargs)

    def set_mode(self, mode, n_rollouts):
        """ Called at the beginning of `do_rollouts`, before `reset`. """
        assert mode in 'train val test'.split(), "Unknown mode: {}.".format(mode)
        self._mode = mode
        self._n_rollouts = n_rollouts

    def build_reset(self):
        return tf.py_func(self.reset_wrapper, [], tf.float32, name="{}.reset".format(self.__class__.__name__))

    def build_step(self, actions):
        types = (tf.float32,) * (3 + len(self.info_shapes))
        return tf.py_func(self.step_wrapper, [actions], types, name="{}.step".format(self.__class__.__name__))

    def reset_wrapper(self):
        """ Need to make sure all return values have type float32. """
        obs = self.reset()
        return obs.astype('f')

    def step_wrapper(self, action):
        """ tf.py_func requires that a LIST of tensors be returned, but gym returns info as a dictionary.
            Also need to make sure all return values have type float32. """
        obs, reward, done, info = self.step(action)
        _info = [info[key] for key in sorted(self.info_shapes)]

        return [a.astype('f') for a in [obs, reward, done, *_info]]

    @abc.abstractmethod
    def reset(self):
        raise Exception("NotImplemented")

    @abc.abstractmethod
    def step(self, action):
        raise Exception("NotImplemented")

    @abc.abstractproperty
    def obs_shape(self):
        """ The shape of one observation (doesn't include batch_shape). """
        raise Exception("NotImplemented")

    @abc.abstractproperty
    def action_shape(self):
        """ The shape of one action (doesn't include batch_shape). """
        raise Exception("NotImplemented")

    def maybe_build_placeholders(self):
        if self.n_rollouts is None:
            self.n_rollouts = tf.placeholder(tf.int32, (), name="n_rollouts")
            self.T = tf.placeholder(tf.int32, (), name="T")
            self.mode = tf.placeholder(tf.string, (), name="mode")

            self.is_training = tf.equal(self.mode, 'train')
            self.is_testing = tf.equal(self.mode, 'test')

    def maybe_build_sampler(self, policy):
        sampler = self._samplers.get(id(policy))
        if not sampler:
            self.maybe_build_placeholders()

            with tf.name_scope("sampler_" + policy.display_name):

                if self.info_shapes is None:
                    # Get info shapes by running the env for one step
                    dummy_n_rollouts = 2
                    self.set_mode(mode="train", n_rollouts=dummy_n_rollouts)
                    self.reset()
                    dummy_action = np.zeros((dummy_n_rollouts,) + self.action_shape)
                    _, _, _, info = self.step(dummy_action)
                    self.info_shapes = {k: v.shape[1:] for k, v in info.items()}

                def cond(step, done, *_):
                    return tf.logical_and(
                        tf.logical_or(self.T <= 0, step < self.T),
                        tf.logical_not(tf.reduce_all(done > 0.5))
                    )

                def body(step, done, policy_state, obs, *tas):
                    (log_prob, action, entropy, util), new_policy_state = policy(obs, policy_state)
                    new_obs, reward, new_done, *info = self.build_step(action)
                    new_obs = tf.reshape(new_obs, (self.n_rollouts, *self.obs_shape))
                    reward = tf.reshape(reward, (self.n_rollouts, 1))
                    new_done = tf.reshape(new_done, (self.n_rollouts, 1))

                    for _info, (_, shape) in zip(info, sorted(self.info_shapes.items())):
                        _info = tf.reshape(_info, (self.n_rollouts, *shape))

                    values = [obs, action, reward, done, log_prob, entropy, util, policy_state, *info]

                    new_tas = []
                    for ta, val in zip(tas, values):
                        new_ta = ta.write(ta.size(), tf.to_float(val))
                        new_tas.append(new_ta)

                    return (step+1, new_done, new_policy_state, new_obs, *new_tas)

                done = tf.fill((self.n_rollouts, 1), 0.0)
                policy_state = policy.zero_state(self.n_rollouts, tf.float32)
                obs = self.build_reset()
                obs = tf.reshape(obs, (self.n_rollouts, *self.obs_shape))

                n_tas = len(self.ta_order) + len(self.info_shapes)
                inp = (
                    [0, done, policy_state, obs] +
                    [tf.TensorArray(dtype=tf.float32, size=0, dynamic_size=True) for i in range(n_tas)]
                )

                # Force build_step to be called in a safe (non-loop) environment for the first time.
                dummy_action = tf.zeros((self.n_rollouts,) + self.action_shape)
                self.build_step(dummy_action)

                _, final_done, final_policy_state, final_obs, *tas = tf.while_loop(
                    cond, body, inp, parallel_iterations=1)

                obs_ta, action_ta, reward_ta, done_ta, log_prob_ta, entropy_ta, util_ta, policy_state_ta, *info_tas = tas

                rollout = dict(
                    obs=tf.concat([obs_ta.stack(), final_obs[None, ...]], axis=0),
                    actions=action_ta.stack(),
                    rewards=reward_ta.stack(),
                    done=tf.concat([done_ta.stack()[1:], final_done[None, :, :]], axis=0),
                    log_probs=log_prob_ta.stack(),
                    entropy=entropy_ta.stack(),
                    utils=util_ta.stack(),
                    policy_states=policy_state_ta.stack(),
                    # policy_states=tf.concat([policy_state_ta.stack(), final_policy_state[None, ...]], axis=0)
                )

                assert len(self.info_shapes) == len(info_tas)
                info = {k: ta.stack() for k, ta in zip(sorted(self.info_shapes), info_tas)}
                intersection = info.keys() & rollout.keys()
                assert not intersection, "Info names cannot overlap with rollout names: {}".format(intersection)

                rollout.update(info)

                static = dict(exploration=policy.exploration)

            self._samplers[id(policy)] = rollout, static
            sampler = self._samplers[id(policy)]

        return sampler

    def do_rollouts(self, policy, n_rollouts=None, T=None, exploration=None, mode='train'):
        # Important to do this first, it can mess with the mode and other things.
        rollout, static = self.maybe_build_sampler(policy)

        policy.set_mode(mode)
        self.set_mode(mode, n_rollouts)

        T = 0 if T is None else T
        feed_dict = {self.n_rollouts: n_rollouts, self.T: T, self.mode: mode}

        if exploration is not None:
            feed_dict.update({policy.exploration: exploration})

        sess = tf.get_default_session()

        _rollout, _static = sess.run([rollout, static], feed_dict=feed_dict)

        return RolloutBatch(**_rollout, static=_static)

    def do_slow_rollouts(
            self, policy, n_rollouts=None, T=None, exploration=None,
            mode='train', render_mode=None):

        policy.set_mode(mode)

        T = T or cfg.T

        obs = self.reset()
        batch_size = obs.shape[0]

        policy_state = policy.zero_state(batch_size, tf.float32)
        policy_state = tf.get_default_session().run(policy_state)

        rollouts = RolloutBatch()

        t = 0

        done = [False]
        while not all(done):
            if T is not None and t >= T:
                break
            (log_probs, action, entropy, utils), policy_state = policy.act(obs, policy_state, exploration)
            new_obs, reward, done, info = self.step(action)
            rollouts.append(
                obs, action, reward, done=done, entropy=entropy,
                log_probs=log_probs, static=dict(exploration=exploration), info=info)
            obs = new_obs
            t += 1

            if render_mode is not None:
                self.render(mode=render_mode)

        return rollouts

    def visualize(self, render_rollouts=None, **rollout_kwargs):
        if cfg.show_plots:
            self.do_slow_rollouts(render_mode="human", **rollout_kwargs)

class TensorFlowEnv(Env):
    @abc.abstractmethod
    def build_reset(self, registers):
        raise Exception("NotImplemented")

    @abc.abstractmethod
    def build_step(self, t, registers, action):
        raise Exception("NotImplemented")

class BatchGymEnv(Env):
    gym_env = Param(help="Either an instance of gym's Env class, or a string specifying an env to create.")
    reward_scale = Param(None)

    def __init__(self, **kwargs):
        super(BatchGymEnv, self).__init__()
        if isinstance(self.gym_env, str):
            self.env_string = self.gym_env
            self.gym_env = gym.make(self.env_string)
        else:
            self.env_string = ""

        self._env_copies = []
        self._active_envs = []

        assert isinstance(self.gym_env.observation_space, Box)

        if isinstance(self.gym_env.action_space, Discrete):
            self._action_shape = (1,)
            self.n_actions = self.gym_env.action_space.n
        else:
            action_shape = self.gym_env.action_space.shape
            self._action_shape = action_shape or (1,)

        self._obs = np.zeros((0,)+self.obs_shape)
        self._done = np.ones((0, 1)).astype('bool')

    @property
    def obs_shape(self):
        return self.gym_env.observation_space.shape

    @property
    def action_shape(self):
        return self._action_shape

    def set_mode(self, mode, n_rollouts):
        assert mode in 'train val test'.split(), "Unknown mode: {}.".format(mode)
        self._mode = mode
        self._n_rollouts = n_rollouts

        n_needed = n_rollouts - len(self._env_copies)

        if n_needed > 0:
            self._env_copies.extend(
                [copy.deepcopy(self.gym_env) for i in range(n_needed)])

            self._obs = np.concatenate(
                [self._obs, np.zeros((n_needed,)+self.obs_shape)], axis=0)

            self._done = np.concatenate(
                [self._done, np.ones((n_needed, 1))], axis=0)

        self._active_envs = self._env_copies[:n_rollouts]
        self.obs = self._obs[:n_rollouts, ...]
        self.done = self._done[:n_rollouts, ...]

    def reset(self):
        for i, env in enumerate(self._active_envs):
            self.done[i, 0] = True

        for idx, env in enumerate(self._active_envs):
            if self.done[idx, 0]:
                self.obs[idx, ...] = env.reset()
                self.done[idx, 0] = False

        return self.obs.copy()

    def step(self, actions):
        rewards = []
        info = defaultdict(list)
        assert len(actions) == self._n_rollouts

        actions = np.array(actions).astype(self.gym_env.action_space.dtype).reshape((-1, *self.gym_env.action_space.shape))

        for idx, (a, env) in enumerate(zip(actions, self._active_envs)):
            if self.done[idx, 0]:
                rewards.append(0.0)
            else:
                o, r, d, i = env.step(a)
                self.obs[idx, ...] = o
                rewards.append(r)
                self.done[idx, 0] = d

                for k, v in i.items():
                    info[k].append(v)

        rewards = np.array(rewards).reshape(-1, 1)
        if self.reward_scale:
            rewards /= self.reward_scale

        info = {k: np.array(v) for k, v in info.items()}

        return (self.obs.copy(), rewards, self.done.copy(), info)

    def render(self, mode='human'):
        self._active_envs[0].render(mode=mode)

    def close(self):
        for env in self._env_copies:
            env.close()

    def seed(self, seed=None):
        np.random.seed(seed)
        for env in self._env_copies:
            s = gen_seed()
            env.seed(s)


from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtWidgets import QGridLayout, QLayout
from PyQt5.QtWidgets import QTextEdit, QLineEdit, QToolButton, QComboBox, QMessageBox
from PyQt5.QtGui import QColor, QFont

from Petstate import *
import random

class Dog_raising_game(QWidget):

    def __init__(self, parent=None):
        super().__init__(parent)

        # Status Layout creation
        gameLayout = QGridLayout()

        #pet state display window
        self.petstate = QTextEdit()
        self.petstate.setReadOnly(True)
        self.petstate.setAlignment(Qt.AlignLeft)
        font = self.petstate.font()
        font.setPointSize(font.pointSize())
        self.petstate.setFont(font)
        gameLayout.addWidget(self.petstate, 0, 0, 5, 2)

        #current pet display window
        self.currentpet = QTextEdit()
        self.currentpet.setReadOnly(True)
        gameLayout.addWidget(self.currentpet, 0, 2, 5, 1)

        #each function button (eat, walk, stroke, shower, sleep)
        self.eatButton = QToolButton()
        self.eatButton.setText('    Feeding    ')
        self.eatButton.clicked.connect(self.eatClicked)
        self.eatButton.setStyleSheet('QToolButton {font: bold; background-color: #B0E0E6;}')
        gameLayout.addWidget(self.eatButton, 0, 3)

        self.walkButton = QToolButton()
        self.walkButton.setText('    walking    ')
        self.walkButton.clicked.connect(self.walkClicked)
        self.walkButton.setStyleSheet('QToolButton {font: bold; background-color: #B0E0E6;}')
        gameLayout.addWidget(self.walkButton, 1, 3)

        self.strokeButton = QToolButton()
        self.strokeButton.setText('    stroking   ')
        self.strokeButton.clicked.connect(self.strokeClicked)
        self.strokeButton.setStyleSheet('QToolButton {font: bold; background-color: #B0E0E6;}')
        gameLayout.addWidget(self.strokeButton, 2, 3)

        self.showerButton = QToolButton()
        self.showerButton.setText('  showering  ')
        self.showerButton.clicked.connect(self.showerClicked)
        self.showerButton.setStyleSheet('QToolButton {font: bold; background-color: #B0E0E6;}')
        gameLayout.addWidget(self.showerButton, 3, 3)

        self.sleepButton = QToolButton()
        self.sleepButton.setText('    sleeping   ')
        self.sleepButton.clicked.connect(self.sleepClicked)
        self.sleepButton.setStyleSheet('QToolButton {font: bold; background-color: #B0E0E6;}')
        gameLayout.addWidget(self.sleepButton, 4, 3)

        # new game button
        self.newGameButton = QToolButton()
        self.newGameButton.setText('New game')
        self.newGameButton.clicked.connect(self.startgame)
        self.newGameButton.setStyleSheet('QToolButton {font: bold; background-color: #A3C1DA; color: blue;}')
        gameLayout.addWidget(self.newGameButton, 5, 0)

        # game rules button
        self.ruleButton = QToolButton()
        self.ruleButton.setText('?')
        self.ruleButton.clicked.connect(self.gameRules)
        self.ruleButton.setStyleSheet('QToolButton {font: bold; background-color: #A3C1DA; color: blue;}')
        gameLayout.addWidget(self.ruleButton, 5, 1)

        #pet Status Change message
        self.message = QLineEdit()
        self.message.setReadOnly(True)
        self.message.setAlignment(Qt.AlignCenter)
        gameLayout.addWidget(self.message, 5, 2)

        #job select box
        self.job = QComboBox()
        self.job.addItem('doctor')
        self.job.addItem("president")
        self.job.addItem("soccer player")
        self.job.addItem("teacher")
        gameLayout.addWidget(self.job, 5, 3)

        # Layout placement
        mainLayout = QGridLayout()
        mainLayout.setSizeConstraint(QLayout.SetFixedSize)
        mainLayout.addLayout(gameLayout, 0, 0)
        self.setLayout(mainLayout)
        self.setWindowTitle('Rasing your own Pet')

        #game start
        self.startgame()

    def startgame(self):
        self.Petname = input("Enter your pet name")

        self.colorChange()    # pet's color changes at random
        self.state = state(self.Petname)
        self.petstate.setText(self.state.displayCurrent())
        self.currentpet.setText(self.state.currentShape())
        self.message.clear()

        self.eatButton.setDisabled(False)
        self.showerButton.setDisabled(False)
        self.strokeButton.setDisabled(False)
        self.sleepButton.setDisabled(False)
        self.walkButton.setDisabled(False)

    def colorChange(self):    #pet color change
        color_list = [QColor(250, 140, 0), QColor(145, 210, 80), QColor(0, 180, 20), QColor(230, 30, 100),
                      QColor(155, 40, 175), QColor(105, 60, 185), QColor(255,70,50)]
        colorvar = random.choice(color_list)
        self.currentpet.setTextColor(colorvar)
        self.currentpet.setFontWeight(QFont.Bold)

    def gameRules(self):   #gamerule message box
        rule = """
        ✔ feeding: hungry-20, happy+15, dirty+15
        ✔ walking: hungry+20, happy+20, tired+30, dirty+25
        ✔ sleeping: happy+15, tired-20
        ✔ showering: happy-25, tired+15, dirty-30
        ✔ stroking: happy+15, dirty+10

        ✔ You can choose your own pet's job.
          When a pet's level reaches 10, it turns into a job!

        ✘ Keep your pet happiness index above zero!
        (Your pet may run away.)
        """
        QMessageBox.about(self, 'Game rules', rule)

    def eatClicked(self):
        if self.state.current['°⌓° hungry']<=20:
            self.message.setText("I\'m not hungry")
        else:
            self.state.current['°⌓° hungry'] -= 20  #pet state change
            self.state.current['･ᴗ･  happy'] += 15
            self.state.current['ʘ‿ʘ  dirty'] += 15
            self.petstate.setText(self.state.displayCurrent())
            self.currentpet.setText(self.state.currentShape())
            self.message.setText('hungry: -20, happy, dirty: +15!')
        self.checkLevel()

    def walkClicked(self):
        if self.state.current['⌣_⌣́    tired']>=80:
            self.message.setText("I\'m very tired")
        elif self.state.current['°⌓° hungry']>=80:
            self.message.setText("I\'m very hungry")
        elif self.state.current['ʘ‿ʘ  dirty']>=70:
            self.message.setText('Let me take a shower first!')
        else:
            self.state.current['°⌓° hungry'] += 20  #pet state change
            self.state.current['･ᴗ･  happy'] += 20
            self.state.current['⌣_⌣́    tired'] += 30
            self.state.current['ʘ‿ʘ  dirty'] += 25
            self.petstate.setText(self.state.displayCurrent())
            self.currentpet.setText(self.state.currentShape())
            self.message.setText('hungry, happy: +20, dirty: +25, tired: +30')
        self.checkLevel()

    def showerClicked(self):
        if self.state.current['⌣_⌣́    tired']>=80:
            self.message.setText("I\'m very tired")
        elif self.state.current['ʘ‿ʘ  dirty']<=30:
            self.message.setText("I\'m clean now!")
        else:
            self.state.current['･ᴗ･  happy'] -= 25  #pet state change
            self.state.current['⌣_⌣́    tired'] += 15
            self.state.current['ʘ‿ʘ  dirty'] -= 30
            self.petstate.setText(self.state.displayCurrent())
            self.currentpet.setText(self.state.currentShape())
            self.message.setText('happy: -25, tired: +15, dirty: -30')
        self.checkLevel()

    def strokeClicked(self):
        if self.state.current['ʘ‿ʘ  dirty']>=90:
            self.message.setText('Let me take a shower first!')
        else:
            self.state.current['･ᴗ･  happy'] += 15   #pet state change
            self.state.current['ʘ‿ʘ  dirty'] += 10
            self.petstate.setText(self.state.displayCurrent())
            self.currentpet.setText(self.state.currentShape())
            self.message.setText('happy: +15, dirty: +10')
            self.checkLevel()

    def sleepClicked(self):
        if self.state.current['⌣_⌣́    tired']<=20:
            self.message.setText("I\'m not sleepy")
        else:
            self.state.current['･ᴗ･  happy'] += 15    #pet state change
            self.state.current['⌣_⌣́    tired'] -= 20
            self.petstate.setText(self.state.displayCurrent())
            self.currentpet.setText(self.state.currentShape())
            self.message.setText('happy: +15, tired: -20')
        self.checkLevel()

    def checkLevel(self):
        if self.state.current['･ᴗ･  happy'] <= 0:
            self.currentpet.setText(self.state.currentShape())
            self.message.setText('Sorry. Your pet ran away')
            self.eatButton.setDisabled(True)    #button deactivation
            self.showerButton.setDisabled(True)
            self.strokeButton.setDisabled(True)
            self.sleepButton.setDisabled(True)
            self.walkButton.setDisabled(True)

        elif self.state.current['✔ Level']>=10:
            job = self.job.currentText()
            self.petstate.setText(self.state.displayCurrent())
            self.currentpet.setText(self.state.futureShape(job))
            self.message.setText('Your pet got a job!: {}'.format(job))
            QMessageBox.about(self, "The end", "Congratulations!")
            self.eatButton.setDisabled(True)    #button deactivation
            self.showerButton.setDisabled(True)
            self.strokeButton.setDisabled(True)
            self.sleepButton.setDisabled(True)
            self.walkButton.setDisabled(True)

        elif self.state.current['･ᴗ･  happy']>=90:
            self.state.current['✔ Level']+=1
            self.state.current['･ᴗ･  happy'] = 30
            self.petstate.setText(self.state.displayCurrent())
            self.currentpet.setText(self.state.currentShape())
            self.message.setText('Level up!')

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    game = Dog_raising_game()
    game.show()
    sys.exit(app.exec_())