#!/usr/bin/env python

"""
    helpers.py
"""

from __future__ import print_function

import numpy as np

import torch
from torch.autograd import Variable
import scipy.sparse as sp
from sklearn.feature_extraction.text import TfidfTransformer
from preprocess.word_emb import count2feat

def set_seeds(seed=0):
    np.random.seed(seed)
    _ = torch.manual_seed(seed)
    if torch.cuda.is_available():
        _ = torch.cuda.manual_seed(seed)

def to_numpy(x):
    if isinstance(x, Variable):
        return x.cpu().data.numpy() if x.is_cuda else x.data.numpy()

    return x.cpu().item().item if x.is_cuda else x.item().item

def read_embed(path="./data/dblp/",
               emb_file="APC"):
    with open("{}{}.emb".format(path, emb_file)) as f:
        n_nodes, n_feature = map(int, f.readline().strip().split())
    print("number of nodes:{}, embedding size:{}".format(n_nodes, n_feature))

    embedding = np.loadtxt("{}{}.emb".format(path, emb_file),
                           dtype=np.float32, skiprows=1)
    emb_index = {}
    for i in range(n_nodes):
        emb_index[embedding[i, 0]] = i

    features = np.asarray([embedding[emb_index[i], 1:] for i in range(n_nodes)])

    assert features.shape[1] == n_feature
    assert features.shape[0] == n_nodes

    return features, n_nodes, n_feature

def normalize(mx):
    """Row-normalize sparse matrix"""
    rowsum = np.array(mx.sum(1))
    r_inv = np.power(rowsum, -1).flatten()
    r_inv[np.isinf(r_inv)] = 0.
    r_mat_inv = sp.diags(r_inv)
    mx = r_mat_inv.dot(mx)
    return mx

def load_2hop_index(path="./data/dblp/", file="APA"):
    index = {}
    with open("{}{}.ind".format(path, file), mode='r') as f:
        for line in f:
            array = [int(x) for x in line.split()]
            a1 = array[0]
            a2 = array[1]
            if a1 not in index:
                index[a1] = {}
            if a2 not in index[a1]:
                index[a1][a2] = set()
            for p in array[2:]:
                index[a1][a2].add(p)

    return index

def read_mpindex_dblp(path="./data/dblp2/",train_per=0.1):
    print(train_per)
    label_file = "author_label"
    PA_file = "PA"
    PC_file = "PC"
    PT_file = "PT"
    feat_emb_file = 'term_emb.npy'
    feat_emb = np.load("{}{}".format(path, feat_emb_file))
    # print("{}{}.txt".format(path, PA_file))
    PA = np.genfromtxt("{}{}.txt".format(path, PA_file),
                       dtype=np.int32)
    PC = np.genfromtxt("{}{}.txt".format(path, PC_file),
                       dtype=np.int32)
    PT = np.genfromtxt("{}{}.txt".format(path, PT_file),
                       dtype=np.int32)
    PA[:, 0] -= 1
    PA[:, 1] -= 1
    PC[:, 0] -= 1
    PC[:, 1] -= 1
    PT[:, 0] -= 1
    PT[:, 1] -= 1

    paper_max = max(PA[:, 0]) + 1
    author_max = max(PA[:, 1]) + 1
    term_max = max(PT[:, 1]) + 1

    PA_s = sp.coo_matrix((np.ones(PA.shape[0]), (PA[:, 0], PA[:, 1])),
                         shape=(paper_max, author_max),
                         dtype=np.float32)
    PT_s = sp.coo_matrix((np.ones(PT.shape[0]), (PT[:, 0], PT[:, 1])),
                         shape=(paper_max, term_max),
                         dtype=np.float32)

    # transformer = TfidfTransformer()
    features = PA_s.transpose() * PT_s  # AT
    # features = transformer.fit_transform(features)
    # features = np.array(features.todense())
    features = count2feat(features, feat_emb)

    labels_raw = np.genfromtxt("{}{}.txt".format(path, label_file),
                               dtype=np.int32)
    labels_raw[:, 0] -= 1
    labels_raw[:, 1] -= 1
    labels = np.zeros(author_max)
    labels[labels_raw[:, 0]] = labels_raw[:, 1]

    reordered = np.random.permutation(labels_raw[:, 0])
    total_labeled = labels_raw.shape[0]

    idx_train = reordered[range(int(total_labeled * train_per))]
    idx_val = reordered[range(int(total_labeled * train_per), int(total_labeled * 0.8))]
    idx_test = reordered[range(int(total_labeled * 0.8), total_labeled)]

    folds = {'train':idx_train,'val':idx_val,'test':idx_test}

    return features, labels, folds

def read_mpindex_aminer(path="./data/aminer/",train_per=0.1):
    print(train_per)
    label_file = "label"
    PA_file = "PA"
    PC_file = "PC"
    feat_emb_file = 'paper_fea.npy'
    feat_emb = np.load("{}{}".format(path, feat_emb_file))
    # print("{}{}.txt".format(path, PA_file))
    PA = np.genfromtxt("{}{}.txt".format(path, PA_file),
                       dtype=np.int32)
    PC = np.genfromtxt("{}{}.txt".format(path, PC_file),
                       dtype=np.int32)

    paper_max = max(PA[:, 0]) + 1 #416554
    author_max = max(PA[:, 1]) + 1

    # PA_s = sp.coo_matrix((np.ones(PA.shape[0]), (PA[:, 0], PA[:, 1])),
    #                      shape=(paper_max, author_max),
    #                      dtype=np.float32)
    # PT_s = sp.coo_matrix((np.ones(PT.shape[0]), (PT[:, 0], PT[:, 1])),
    #                      shape=(paper_max, term_max),
    #                      dtype=np.float32)

    features = feat_emb

    labels_raw = np.genfromtxt("{}{}.txt".format(path, label_file),
                               dtype=np.int32)
    # labels_raw[:, 0] -= 1
    # labels_raw[:, 1] -= 1
    labels = labels_raw
    # labels[labels_raw[:, 0]] = labels_raw[:, 1]

    assert paper_max == labels_raw.shape[0]

    reordered = np.random.permutation(np.arange(paper_max))
    total_labeled = labels_raw.shape[0]

    idx_train = reordered[range(int(total_labeled * train_per))]
    idx_val = reordered[range(int(total_labeled * train_per), int(total_labeled * 0.8))]
    idx_test = reordered[range(int(total_labeled * 0.8), total_labeled)]

    folds = {'train':idx_train,'val':idx_val,'test':idx_test}

    return features, labels, folds

def read_mpindex_cora(path="./data/cora/",train_per=0.1):
    label_file = "paper_label"
    feat_emb_file = 'term_emb.npy'
    PT_file = "PT"

    feat_emb = np.load("{}{}".format(path,feat_emb_file))

    PT = np.genfromtxt("{}{}.txt".format(path, PT_file),
                       dtype=np.int32)
    PT[:, 0] -= 1
    PT[:, 1] -= 1

    paper_max = max(PT[:, 0]) + 1
    term_max = max(PT[:, 1]) + 1

    PT_s = sp.coo_matrix((np.ones(PT.shape[0]), (PT[:, 0], PT[:, 1])),
                         shape=(paper_max, term_max),
                         dtype=np.float32)

    # transformer = TfidfTransformer()
    features = PT_s  # AT
    # features = transformer.fit_transform(features)
    # features = np.array(features.todense())
    # features = np.zeros(paper_max).reshape(-1, 1)

    features = count2feat(features,feat_emb)

    labels_raw = np.genfromtxt("{}{}.txt".format(path, label_file),
                               dtype=np.int32)
    labels_raw[:, 0] -= 1

    no_label_mask = labels_raw[:,1] != 0
    labels_raw = labels_raw[no_label_mask]

    print('labels shape: ', labels_raw.shape)

    #remap label
    label_dict={}
    for i in labels_raw[:,1]:
        if i not in label_dict:
            label_dict[i]=len(label_dict)
    print('number of label classes: ', len(label_dict))
    for i in range(labels_raw.shape[0]):
        labels_raw[i,1] = label_dict[labels_raw[i,1]]

    labels = np.zeros(paper_max)
    labels[labels_raw[:, 0]] = labels_raw[:, 1]

    reordered = np.random.permutation(labels_raw[:, 0])
    total_labeled = labels_raw.shape[0]

    idx_train = reordered[range(int(total_labeled * train_per))]
    idx_val = reordered[range(int(total_labeled * train_per), int(total_labeled * 0.8))]
    idx_test = reordered[range(int(total_labeled * 0.8), total_labeled)]

    folds = {'train':idx_train,'val':idx_val,'test':idx_test}

    return features, labels, folds

def load_edge_emb(path, schemes, n_dim=17, n_author=20000):
    data = np.load("{}edge{}.npz".format(path, n_dim))
    index = {}
    emb = {}
    for scheme in schemes:
        # print('number of authors: {}'.format(n_author))
        ind = sp.coo_matrix((np.arange(1,data[scheme].shape[0]+1),
                             (data[scheme][:, 0], data[scheme][:, 1])),
                            shape=(n_author, n_author),
                            dtype=np.long)

        ind = ind + ind.T.multiply(ind.T>ind)
        ind = sparse_mx_to_torch_sparse_tensor(ind)#.to_dense()

        embedding = np.zeros(n_dim, dtype=np.float32)
        embedding = np.vstack((embedding, data[scheme][:, 2:]))
        emb[scheme] = torch.from_numpy(embedding).float()

        index[scheme] = ind.long()
        print('loading edge embedding for {} complete, num of embeddings: {}'.format(scheme,embedding.shape[0]))

    return index, emb

def sparse_mx_to_torch_sparse_tensor(sparse_mx):
    """Convert a scipy sparse matrix to a torch sparse tensor."""
    sparse_mx = sparse_mx.tocoo().astype(np.float32)
    indices = torch.from_numpy(
        np.vstack((sparse_mx.row, sparse_mx.col)).astype(np.int64))
    values = torch.from_numpy(sparse_mx.data)
    shape = torch.Size(sparse_mx.shape)
    return torch.sparse.FloatTensor(indices, values, shape)

def read_mpindex_yelp(path="../../data/yelp/",train_per=0.1):
    label_file = "true_cluster"
    feat_file = "attributes"

    # print("{}{}.txt".format(path, PA_file))
    feat = np.genfromtxt("{}{}.txt".format(path, feat_file),
                       dtype=np.float)

    features = feat[:,:2]
    #features = np.zeros((feat.shape[0],1))
    #features = np.eye(feat.shape[0])

    labels = np.genfromtxt("{}{}.txt".format(path, label_file),
                               dtype=np.int32)

    reordered = np.random.permutation(np.arange(labels.shape[0]))
    total_labeled = labels.shape[0]

    idx_train = reordered[range(int(total_labeled * train_per))]
    idx_val = reordered[range(int(total_labeled * train_per), int(total_labeled * 0.8))]
    idx_test = reordered[range(int(total_labeled * 0.8), total_labeled)]

    folds = {'train':idx_train,'val':idx_val,'test':idx_test}

    return features, labels, folds

def read_mpindex_yago(path="../../data/yago/", label_file = "labels",train_per=0.1):

    movies = []
    with open('{}{}.txt'.format(path, "movies"), mode='r', encoding='UTF-8') as f:
        for line in f:
            movies.append(line.split()[0])

    n_movie = len(movies)
    movie_dict = {a: i for (i, a) in enumerate(movies)}

    features = np.zeros(n_movie).reshape(-1,1)

    labels_raw = []
    with open('{}{}.txt'.format(path, label_file), 'r', encoding='UTF-8') as f:
        for line in f:
            arr = line.split()
            labels_raw.append([int(movie_dict[arr[0]]), int(arr[1])])
    labels_raw = np.asarray(labels_raw)

    labels = np.zeros(n_movie)
    labels[labels_raw[:, 0]] = labels_raw[:, 1]

    reordered = np.random.permutation(labels_raw[:, 0])
    total_labeled = labels_raw.shape[0]

    idx_train = reordered[range(int(total_labeled * train_per))]
    idx_val = reordered[range(int(total_labeled * train_per), int(total_labeled * 0.8))]
    idx_test = reordered[range(int(total_labeled * 0.8), total_labeled)]

    folds = {'train': idx_train, 'val': idx_val, 'test': idx_test}

    return features, labels, folds

def read_homograph(path="../../data/yago/", problem='yago',):
    dataset = "homograph"
    emb_file = {'yago':'MADW_16','dblp':'APC_16','yelp':'RBUK_16'}
    with open("{}{}.emb".format(path, emb_file[problem])) as f:
        n_nodes, n_feature = map(int, f.readline().strip().split())
    embedding = np.loadtxt("{}{}.emb".format(path, emb_file[problem]),
                           dtype=np.float32, skiprows=1, encoding='latin-1')
    emb_index = {}
    for i in range(n_nodes):
        # if type(embedding[i, 0]) is not int:
        #     continue
        emb_index[embedding[i, 0]] = i

    features = np.asarray([embedding[emb_index[i], 1:] for i in range(embedding.shape[0])])
    features = torch.FloatTensor(features)

    edges = np.genfromtxt("{}{}.txt".format(path, dataset),
                          dtype=np.int32)
    adj = sp.coo_matrix((np.ones(edges.shape[0]), (edges[:, 0], edges[:, 1])),
                        shape=(n_nodes, n_nodes),
                        dtype=np.float32)

    # build symmetric adjacency matrix
    adj = adj + adj.T.multiply(adj.T > adj) - adj.multiply(adj.T > adj)

    # features = normalize(features)
    adj = normalize(adj + sp.eye(adj.shape[0]))
    adj = sparse_mx_to_torch_sparse_tensor(adj)

    return adj, features

# features, labels, folds = read_mpindex_yago()


# coding: utf-8

from __future__ import unicode_literals, absolute_import, print_function, division

from aiohttp import web
from scilib.gender.benchmark.benchmark import CONFIGS_MAP
import redis

KEY_PREFIX = 'scilib-gender'
POOL = redis.ConnectionPool()

async def gender(request):
    tool = request.query.get('tool', 'gender_guesser')
    names = request.query.get('name', None)
    if tool not in CONFIGS_MAP:
        return web.json_response(dict(status='error', message_type='invalid_tool'))
    if not names:
        return web.json_response(dict(status='error', message_type='invalid_name'))

    func = CONFIGS_MAP[tool][1]
    names = [i.strip() for i in names.split(';') if i.strip()]

    conn = redis.Redis(connection_pool=POOL)
    results = conn.hmget(f'{KEY_PREFIX}-{tool}', keys=names)
    results = [i.decode('utf-8') if i else None for i in results]

    results_items = [[i, r] for i, r in enumerate(results)]
    blank_items = [[i, r] for i, r in results_items if not r]
    if blank_items:
        call_results = func([names[i] for i, r in blank_items])
        for i, r in enumerate(call_results):
            results_items[blank_items[i][0]][1] = r

    results = [r for i, r in results_items]
    if not all(results):
        return web.json_response(dict(status='error', message_type='invalid_results', results_items=results_items))

    if blank_items:
        conn.hset(f'{KEY_PREFIX}-{tool}', mapping={names[i]: r for i, r in results_items})

    return web.json_response(dict(
        status='success',
        results=[dict(name=names[i], result=r) for i, r in results_items],
    ))

def main():
    app = web.Application()
    app.add_routes([
        web.get('/gender', gender)
    ])
    web.run_app(app, port=9901)

if __name__ == '__main__':
    main()


# -*- coding: utf-8 -*-
import json
import re

import scrapy

from Jovi.items import JoviLonglasttimeItem

class XinaRollSpiderSpider(scrapy.Spider):
    name = 'sina_roll_spider'
    pid = '153'
    col = [
        {
            'name': "全部",
            'lid': "2509",
            'page': 9669
        },
        {
            'name': "国内",
            'lid': "2510",
            'page': 14550

        },
        {
            'name': "国际",
            'lid': "2511",
            'page': 488

        },
        {
            'name': "社会",
            'lid': "2669",
            'page': 597
        },
        {
            'name': "体育",
            'lid': "2512",
            'page': 4215
        },
        {
            'name': "娱乐",
            'lid': "2513",
            'page': 1212
        },
        {
            'name': "军事",
            'lid': "2514",
            'page': 1156

        },
        {
            'name': "科技",
            'lid': "2515",
            'page': 2148
        },
        {
            'name': "财经",
            'lid': "2516",
            'page': 6529
        },
        {
            'name': "股市",
            'lid': "2517",
            'page': 3507
        },
        {
            'name': "美股",
            'lid': "2518",
            'page': 12854
        }
    ]
    meta = dict()

    def start_requests(self):
        meta = self.meta
        for i in self.col:
            meta['third_tag'] = i['name']
            for j in range(1, i['page'] + 1):
                url = 'https://feed.mix.sina.com.cn/api/roll/get?pageid=153&lid={}&k=&num=50&page={}'.format(i['lid'],
                                                                                j)
                yield scrapy.Request(url, meta=meta, callback=self.get_urls)

    def get_urls(self, response):
        meta = response.meta
        data = json.loads(response.text)
        for i in data['result']['data']:
            url = i['url']
            meta['title'] = i['title']
            yield scrapy.Request(url, callback=self.get_content, meta=meta)

    def get_content(self, response):
        item = JoviLonglasttimeItem()
        meta = response.meta
        article = response.xpath('//div[@class="article"]/p[not(@class)]//text()').extract()
        content = ''
        pattern = r'原标题：|特别声明：|{}'.format(meta['title'])
        for i in article:
            if re.search(pattern, i):
                continue
            else:
                content += i.strip()
        item['article_content'] = content
        item['article_title'] = meta['title']
        item['article_url'] = response.url
        item['first_tag'] = '新浪滚动'
        item['second_tag'] = '新浪滚动'
        item['third_tag'] = meta['third_tag']
        yield item


import numpy as np
from gensim import corpora, models, similarities, downloader
from keybert import KeyBERT
import os
# from theme_wc import WordCloudGenerator

def load_embeddings(embeddings_file):
    # Detect the model format by its extension:
        emb_model = models.KeyedVectors.load_word2vec_format(embeddings_file, binary=True,                                                             unicode_errors='replace')
        key_list = emb_model.index_to_key  # list
        key_index_dict = emb_model.key_to_index  # dict
        embeddings = emb_model.vectors        # print(embeddings.shape)  #(199430, 300)
        return emb_model, embeddings, key_list, key_index_dict

def get_similar_words(theme, emb_model, embeddings, key_list, key_index_dict):
    word_dict = [(key, value) for key, value in key_index_dict.items() if key.startswith(theme)]    # print(word_dict)
    # [('covid-19_PROPN', 3894), ('covid-19_NOUN', 9583), ('covid-19_ADJ', 12940), ('covid-19_NUM', 16412)]    # get embedding of theme word
    emb1 = embeddings[word_dict[0][1]]    # compute the similarities
    similarities = emb_model.cosine_similarities(emb1, embeddings)
    sorted_similarities_index = np.argsort(similarities)[::-1]  # large->small
    # get the similar words
    similar_text = [key_list[idx].split('_')[0] for idx in sorted_similarities_index[1:10]]
    similar_text = list(dict.fromkeys(similar_text))  # remove duplicates    #
    # print(similar_text)
    # compute the frequency of these words
    similar_text_dict = {}
    for text in similar_text:
        text_frequency = sum([emb_model.get_vecattr(key, "count") for key, value in key_index_dict.items() if key.startswith(text)])
        similar_text_dict[text] = text_frequency
    similar_text_dict = sorted(similar_text_dict.items(), key=lambda x: x[1], reverse=True)
    if len(similar_text_dict) >= 5:
        similar_text_dict = similar_text_dict[:4]
    similar_text_list = list(list(zip(*similar_text_dict))[0])
    return similar_text_list

def extract_kw_similar(title):
    kw_model = KeyBERT(model='all-mpnet-base-v2')
    # title = 'Number of police officers in crimeville'
    keywords = kw_model.extract_keywords(title,
                                        keyphrase_ngram_range=(1,1),
                                        stop_words='english',
                                        highlight=False,
                                        top_n=3)
    keywords_list = list(dict(keywords).keys())
    # print(keywords_list)

    # load model
    emb_model, embeddings, key_list, key_index_dict = load_embeddings('D:/speak/theme_extract/model.bin')
    # find all words containing "xx"
    theme = keywords_list[0]
    theme_and_text = {}
    for theme in keywords_list:
        try:
            similar_text_list = get_similar_words(theme, emb_model, embeddings, key_list, key_index_dict)
            theme_and_text[theme] = similar_text_list
        except:
            pass
            # theme_and_text[theme] = []
    result_list = []
    for key, value in theme_and_text.items():
        result_list.append(key)
        result_list.extend(value)
    my_dict = {key: 20 - 1.5*i + 10*(i//5) for i,key in enumerate(result_list)}
    return my_dict

# title = "Date of cherry blossom in High Park"
# my_dict = extract_kw_similar(title)
# # print(my_dict)
# wordcloud_gen = WordCloudGenerator(font_path='D:/speak/frontend/src/assets/fonts/TiltNeon-Regular.ttf',
#                                     background_color='#F5F5F5', colormap="binary",
#                                     prefer_horizontal=1,
#                                     max_font_size=45, min_font_size=12,
#                                     width=420, height=200,
#                                     margin=50, d=my_dict)
# img_path2 = wordcloud_gen.generate_wordcloud()


'''
Created on 07.06.2020
@author: Abdul
plotting tool for microplane models
'''

from math import \
    cos, sin, pi

from numpy import \
    array, zeros, trace, \
    einsum, zeros_like,\
    identity, linspace, hstack,\
    sqrt, ones

from traits.api import \
    Constant, \
    HasTraits, \
    Property, cached_property

import matplotlib.pyplot as plt

import numpy as np

class MATS2DMicroplane(HasTraits):

    #-----------------------------------------------
    # number of microplanes
    #-----------------------------------------------
    n_mp = Constant(360)

    #-----------------------------------------------
    # get the normal vectors of the microplanes
    #-----------------------------------------------
    _MPN = Property(depends_on='n_mp')

    @cached_property
    def _get__MPN(self):
        # microplane normals:

        alpha_list = linspace(0, 2 * pi, self.n_mp)

        MPN = array([[cos(alpha), sin(alpha)] for alpha in alpha_list])

        return MPN

    #-------------------------------------
    # get the weights of the microplanes
    #-------------------------------------
    _MPW = Property(depends_on='n_mp')

    @cached_property
    def _get__MPW(self):
        # Note that the values in the array must be multiplied by 6 (cf. [Baz05])!
        # The sum of of the array equals 0.5. (cf. [BazLuz04]))
        # The values are given for an Gaussian integration over the unit
        # hemisphere.
        MPW = ones(self.n_mp) / self.n_mp * 2

        return MPW

    #-------------------------------------------------------------------------
    # Cached elasticity tensors
    #-------------------------------------------------------------------------

    elasticity_tensors = Property(
        depends_on='E, nu, dimensionality, stress_state')

    @cached_property
    def _get_elasticity_tensors(self):
        '''
        Intialize the fourth order elasticity tensor for 2D or 2D plane strain or 2D plane stress
        '''
        # ----------------------------------------------------------------------------
        # Lame constants calculated from E and nu
        # ----------------------------------------------------------------------------

        # first Lame paramter
        la = self.E * self.nu / ((1 + self.nu) * (1 - 2 * self.nu))
        # second Lame parameter (shear modulus)
        mu = self.E / (2 + 2 * self.nu)

        # -----------------------------------------------------------------------------------------------------
        # Get the fourth order elasticity and compliance tensors for the 2D-case
        # -----------------------------------------------------------------------------------------------------

        # construct the elasticity tensor (using Numpy - einsum function)
        delta = identity(2)
        D_ijkl = (einsum(',ij,kl->ijkl', la, delta, delta) +
                  einsum(',ik,jl->ijkl', mu, delta, delta) +
                  einsum(',il,jk->ijkl', mu, delta, delta))

        return D_ijkl

    #-------------------------------------------------------------------------
    # Setup for computation within a supplied spatial context
    #-------------------------------------------------------------------------
    D4_e = Property

    def _get_D4_e(self):
        # Return the elasticity tensor
        return self.elasticity_tensors

    #-------------------------------------------------------------------------
    '''Kinematic constraint N-T split '''
    #-------------------------------------------------------------------------

    # get the dyadic product of the microplane normals
    _MPNN = Property(depends_on='n_mp')

    @cached_property
    def _get__MPNN(self):
        # dyadic product of the microplane normals

        MPNN_nij = einsum('ni,nj->nij', self._MPN, self._MPN)
        return MPNN_nij

    # get the third order tangential tensor (operator) for each microplane
    _MPTT = Property(depends_on='n_mp')

    @cached_property
    def _get__MPTT(self):
        # Third order tangential tensor for each microplane
        delta = identity(2)
        MPTT_nijr = 0.5 * (einsum('ni,jr -> nijr', self._MPN, delta) +
                           einsum('nj,ir -> njir', self._MPN, delta) - 2 *
                           einsum('ni,nj,nr -> nijr', self._MPN, self._MPN, self._MPN))
        return MPTT_nijr

    def _get_e_N_arr(self, eps_eng):
        return einsum('nij,ij->n', self._MPNN, eps_eng)

    def _get_e_T_vct_arr(self, eps_eng):
        MPTT_ijr = self._get__MPTT()
        return einsum('nijr,ij->nr', MPTT_ijr, eps_eng)

    #-------------------------------------------------------------------------
    '''Kinematic constraint V-D-T split '''
    #-------------------------------------------------------------------------

    # get the dyadic product of the microplane normals
    _MPVV_1 = Property(depends_on='n_mp')

    @cached_property
    def _get__MPVV_1(self):
        # dyadic product of the microplane normals
        I_ij = identity(2)
        MPVV_ij = 1/3 * I_ij
        return MPVV_ij

    # get the dyadic product of the microplane normals
    _MPDD_1 = Property(depends_on='n_mp')

    @cached_property
    def _get__MPDD_1(self):
        # dyadic product of the microplane normals
        I_ij = identity(2)
        MPVV_ij = 1/3 * I_ij

        MPNN_nij = einsum('ni,nj->nij', self._MPN, self._MPN)

        MPDD_ij = einsum('nij->nij', MPNN_nij - MPVV_ij)

        return MPDD_ij

    # get the third order tangential tensor (operator) for each microplane
    _MPTT_1 = Property(depends_on='n_mp')

    @cached_property
    def _get__MPTT_1(self):
        # Third order tangential tensor for each microplane
        delta = identity(2)
        MPTT_nijr = 0.5 * (einsum('ni,jr -> nijr', self._MPN, delta) +
                           einsum('nj,ir -> njir', self._MPN, delta) - 2 *
                           einsum('ni,nj,nr -> nijr', self._MPN, self._MPN, self._MPN))
        return MPTT_nijr

    def _get_e_V1_arr(self, eps_eng):
        return einsum('ij,ij->', self._MPVV_1, eps_eng)

    def _get_e_D1_arr(self, eps_eng):
        return einsum('nij,ij->n', self._MPDD_1, eps_eng)

    def _get_e_T1_vct_arr(self, eps_eng):
        MPTT_ijr = self._get__MPTT_1()
        return einsum('nijr,ij->nr', MPTT_ijr, eps_eng)

    #-------------------------------------------------------------------------
    '''Kinematic constraint V-D split '''
    #-------------------------------------------------------------------------

    # get the dyadic product of the microplane normals
    _MPVV = Property(depends_on='n_mp')

    @cached_property
    def _get__MPVV(self):
        # dyadic product of the microplane normals
        I_ij = identity(2)
        MPVV_ij = 1/3 * I_ij
        return MPVV_ij

    # get the third order tangential tensor (operator) for each microplane
    _MPDD = Property(depends_on='n_mp')

    @cached_property
    def _get__MPDD(self):
        # Third order tangential tensor for each microplane
        delta = identity(2)
        MPDD_nijr = 0.5 * (einsum('ni,jr -> nijr', self._MPN, delta) +
                           einsum('nj,ir -> njir', self._MPN, delta)) -\
                             1/3. * einsum('nk,ki,jr -> nijr', self._MPN, delta, delta)
        return MPDD_nijr

    def _get_e_V_arr(self, eps_eng):
        return einsum('ij,ij->', self._MPVV, eps_eng)

    def _get_e_D_vct_arr(self, eps_eng):
        MPDD_ijr = self._get__MPDD()
        return einsum('nijr,ij->nr', MPDD_ijr, eps_eng)

if __name__ == '__main__':
    #==========================================================================
    # Check the model behavior at the single material point
    #==========================================================================

    model = MATS2DMicroplane()

    n_mp = model.n_mp

    p = 1.0  # ratio of strain eps_11 (for bi-axial loading)
    m = -0.2  # ratio of strain eps_22 (for bi-axial loading)

    # monotonic loading - comp
    n = 25  # number of increments
    s_levels = linspace(0, 0.001, 2)
    #s_levels[0] = 0
    eps_max = 0.001

    s_levels.reshape(-1, 2)[:, 0] = eps_max
    s_levels[0] = 0
    #s_levels.reshape(-1, 2)[:, 1] = eps_min
    s_history_1 = s_levels.flatten()
    s_arr_1 = hstack([linspace(s_history_1[i], s_history_1[i + 1], n)
                      for i in range(len(s_levels) - 1)])

    eps_1 = array([array([[0 * s_arr_1[i],  p* s_arr_1[i]],
                          [ p* s_arr_1[i] , 0 * s_arr_1[i]]]) for i in range(0, len(s_arr_1))])

    idx = np.where(eps_1[:, 0, 0] == eps_max)
    print(idx[0])

    #--------------------------------------
    # construct the arrays
    #--------------------------------------

    sigma_kk_1 = zeros(len(s_arr_1) + 1)

    eps_N_1 = zeros((len(eps_1[:, 0]), n_mp))
    eps_V_1 = zeros((len(eps_1[:, 0]), n_mp))
    eps_D_1 = zeros((len(eps_1[:, 0]), n_mp))

    eps_TT_1 = zeros((len(eps_1[:, 0]), n_mp, 2))
    eps_DD_1 = zeros((len(eps_1[:, 0]), n_mp, 2))

    for i in range(0, len(eps_1[:, 0])):

        eps_N_1[i, :] = model._get_e_N_arr(eps_1[i, :])
        eps_TT_1[i, :, :] = model._get_e_T_vct_arr(eps_1[i, :])

        eps_V_1[i, :] = model._get_e_V1_arr(eps_1[i, :])
        eps_D_1[i, :] = model._get_e_D1_arr(eps_1[i, :])

        eps_V_1[i, :] = model._get_e_V_arr(eps_1[i, :])
        eps_DD_1[i, :, :] = model._get_e_D_vct_arr(eps_1[i, :])

#     '''====================================================
#     plotting
#     ===================================================='''

    rads = np.arange(0, (2 * np.pi), (2 * np.pi) / n_mp)

    '=================================================================='
    'Plotting in increments'
    '=================================================================='

    #===================
    # Normal strain
    #===================
    plt.subplot(111)

    for i in range(0, len(eps_1[:, 0])):
        plt.polar(rads, eps_N_1[i, :])
    plt.title(' Normal strain for all microplanes')
    plt.show()

    #===================
    # Tangential  strain
    #===================
    plt.subplot(111)
    for i in range(0, len(eps_1[:, 0])):

        norm = sqrt(
            einsum('...i,...i->... ', eps_TT_1[i, :], eps_TT_1[i, :]))

        plt.polar(rads, norm)
    plt.title('Tangential strain for all microplanes')
    plt.show()

    #===================
    # Volumetric strain
    #===================
    plt.subplot(111)

    for i in range(0, len(eps_1[:, 0])):
        plt.polar(rads, eps_V_1[i, :])
    plt.title(' Volumetric strain for all microplanes')
    plt.show()

    #===================
    # Deviatoric strain (V-D-T)
    #===================
    plt.subplot(111)

    for i in range(0, len(eps_1[:, 0])):
        plt.polar(rads, eps_D_1[i, :])
    plt.title(' Deviatoric (V-D-T) strain for all microplanes')
    plt.show()

    #===================
    # Deviatoric  strain
    #===================
    plt.subplot(111)
    for i in range(0, len(eps_1[:, 0])):

        norm = sqrt(
            einsum('...i,...i->... ', eps_DD_1[i, :], eps_DD_1[i, :]))

        plt.polar(rads, norm)
    plt.title('Deviatoric (V-D) strain for all microplanes')
    plt.show()

    plt.show()


#-*-coding:utf-8-*-

'''
Description:
    Ce fichier est le script du test fonctionnel. Il dessiner les courbes de la qualité
    des meilleures solution et la qualité moyenne des solutions dans la figure

Version: 1.0

Auteur: Peng BI
'''

import matplotlib.pyplot as plt

class TestParameters:
    '''
    Description:
        Cette classe est pour déterminer le nombre d'itérations

    Attribut: rien
    '''

    def drawFigure(self):
        '''
        Description:
            Cette méthode est pour dessiner la courbe de qualité des meilleures solutions de chaque
            itérations et dessiner la courbe de qualité moyenne de solutions de chaque itérations

        :return: rien
        '''

        bestQualityOfSolutionForEachIterationList = []
        averageQualityOfSolutionForEachIterationList = []

        # lire le fichire de qualité, et extraire la colonne de meilleure qualité et la colonne de qualité moyenne
        counter = 0
        with open('../../files/quality.txt', 'rt') as qualities:
            for quality in qualities:
                if counter != 0:
                    bestQualityOfSolutionForEachIterationList.append(float(quality.split('\t')[1]))
                    averageQualityOfSolutionForEachIterationList.append(float(quality.split('\t')[2]))
                counter += 1

        # chercher l'id d'itération où la meilleure qualité est maximum
        maxQualityIteration = bestQualityOfSolutionForEachIterationList.index(max(bestQualityOfSolutionForEachIterationList))
        print("La meilleure solution est dans itération %d" % int(maxQualityIteration))

        # dessiner la figure, l'axe x est l'itération, l'axe y est la qualité
        iteration = len(bestQualityOfSolutionForEachIterationList)
        x = [x for x in range(0,iteration)]
        y1 = bestQualityOfSolutionForEachIterationList
        y2 = averageQualityOfSolutionForEachIterationList

        plt.figure()
        plt.plot(x, y1, 'b', linewidth=0.5, marker='*')
        plt.plot(x, y2, 'r', linewidth=2, marker='+')

        plt.fill_between(x, y1, y2, color='g', alpha=0.5)
        plt.legend(['bestSolution', 'averageSolution'])
        plt.xlabel('Iteration')
        plt.ylabel('Quality')

        plt.show()

if __name__ == '__main__':
    testParameter = TestParameters()
    testParameter.drawFigure()


import cantera as ct
import numpy as np
import matplotlib.pyplot as plt

CCl4_X_0 = float(1000)
pressure_0 = 12.4
reaction_mech="~/EDC/FPC/KM/2009_Schirmeister_EDC/chem_annotated_irreversible.cti"
mass_flow_rate = float(36)
length = 18
n_steps = 1000
area = 0.03225097679
n_pfr=18
# T_list = [322, 350, 375, 399, 424, 451, 461, 466, 471, 477, 479, 479, 480, 481, 482, 483, 484, 485, 486]

temp_T = 750
if CCl4_X_0 > 1 :  #ppm
        CCl4_X_0 = CCl4_X_0 /1000000
# T_0 = 273.15 + T_list[0]  # inlet temperature [K]
pressure_0 *= ct.one_atm
spcs = ct.Species.listFromFile(reaction_mech)
for spc in spcs[::-1]:
    if spc.composition == {'C': 2.0, 'Cl': 2.0, 'H': 4.0} and spc.charge == 0:
        EDC_label = spc.name
    if spc.composition == {'C': 1.0, 'Cl': 4.0} and spc.charge == 0:
        CCl4_label = spc.name
EDC_X_0 = 1 - CCl4_X_0
composition_0 = '{}:{}, {}:{}'.format(EDC_label, EDC_X_0, CCl4_label, CCl4_X_0)
mass_flow_rate *= 1000 / 3600  # T/H to kg/s

# import the gas model and set the initial conditions
gas = ct.Solution(reaction_mech)
gas.TPX = temp_T, pressure_0, composition_0
dz = length / n_steps
r_vol = area * dz

# create a new reactor
r = ct.IdealGasConstPressureReactor(gas)
r.volume = r_vol

gas.set_multiplier(10)

# # create a reservoir to represent the reactor immediately upstream. Note
# # that the gas object is set already to the state of the upstream reactor
# upstream = ct.Reservoir(gas, name='upstream')

# # create a reservoir for the reactor to exhaust into. The composition of
# # this reservoir is irrelevant.
# downstream = ct.Reservoir(gas, name='downstream')

# # The mass flow rate into the reactor will be fixed by using a
# # MassFlowController object.
# m = ct.MassFlowController(upstream, r, mdot=mass_flow_rate)

# # We need an outlet to the downstream reservoir. This will determine the
# # pressure in the reactor. The value of K will only affect the transient
# # pressure difference.
# v = ct.PressureController(r, downstream, master=m, K=1e-5)

sim = ct.ReactorNet([r])

rxn = gas.reaction_equations()
n_rxn = len(rxn)

for i in range(n_rxn):
    r.add_sensitivity_reaction(i)

max_s = [0] * n_rxn
max_s_abs = [0]* n_rxn
sim.rtol = 1e-6 # Relative tolerance
sim.atol = 1e-15 # Absolute tolerance

sim.rtol_sensitivity = 1e-6 # Relative tolerance for sensitivity
sim.atol_sensitivity - 1e-6 # absolute tolerance for sensitivity

# define time, space, and other information vectors
z = (np.arange(n_steps) + 1) * dz
t = np.zeros(n_pfr)  # residence time in each PFR reactor
compositions = [None] * n_pfr  # compositions of output stream in each PFR reactor
states = ct.SolutionArray(gas,extra = ['t'])

tot_time = 2e-3
dt = 5e-6

print(r.component_index('VCM(10)'))
for time in np.arange(0,tot_time,dt):
    sim.advance(time)
    states.append(r.thermo.state,t = time*1000)

    for j in range(n_rxn):
        s = sim.sensitivity('EDC(1)',j)

        if np.abs(s) > np.abs(max_s[j]):
            max_s[j] = s
            max_s_abs[j] = abs(s)
sen_zip = zip(max_s_abs,max_s,range(n_rxn))
sen_tuple = tuple(sen_zip)
sen_tuple_sorted = sorted(sen_tuple,reverse=True)

top_n = 10
top_rxn_index = [0]*top_n
top_rxn = [0]*top_n
top_sen = [0]*top_n

for i in range(top_n):
    top_rxn_index[i] = int(sen_tuple_sorted[i][2])
    top_rxn[i] = rxn[top_rxn_index[i]]
    top_sen[i] = float(sen_tuple_sorted[i][1])

print("The top %d EDC sensitive reactions are:" %(top_n))
print("-----------------------------------------------------------")
print("%10s  %s %18s %12s %12s" % ('Reaction Index','|','Reaction','|','Sensitivity'))
print("-----------------------------------------------------------")
for i in range(top_n):
    print("%7d %8s %26s %4s %10.8f" % (top_rxn_index[i],'|',top_rxn[i],'|',top_sen[i]))
print("-----------------------------------------------------------")

top_rxn_index.reverse()
top_rxn.reverse()
top_sen.reverse()

plt.figure(1)
plt.barh(range(top_n),top_sen,0.75,align= 'center')
plt.yticks(range(top_n),top_rxn)
plt.xlabel('')
plt.title('{0} Most EDC Sensitivity Reactions' .format(top_n), fontweight= 'bold')
plt.grid(which='major')
plt.minorticks_on()
plt.grid(which='minor',alpha=0.2)
plt.tight_layout()
plt.savefig('sensitivity.png')

# for i, T in enumerate(T_list[1:]):
#     Ti = T_list[i] + 273.15
#     Te = T + 273.15
#     dT = (Te - Ti) / n_steps
#     T = Ti
#     t_r = np.zeros_like(z)  # residence time in each CSTR reactor
#     # iterate through the PFR cells
#     for n in range(n_steps):
#         # simulate the linear T-profile in each reactor
#         T = Ti + (n + 1) * dT
#         gas.TP = T, None
#         r.syncState()
#         # Set the state of the reservoir to match that of the previous reactor
#         gas.TPX = r.thermo.TPX
#         upstream.syncState()
#         # integrate the reactor forward in time until steady state is reached
#         sim.reinitialize()
#         sim.set_initial_time(0)
#         sim.advance_to_steady_state()
#         # compute velocity and transform into time
#         t_r[n] = r.mass / mass_flow_rate  # residence time in this reactor
#         # write output data
#         states.append(r.thermo.state)


#!/usr/bin/env python
from faws.util import assert_pyversion
assert_pyversion()

def get_args():
    import argparse
    parser = argparse.ArgumentParser(
        description='List launch AMI for each instance ID',
        epilog='Demo tool that demonstrates concurrent API access',
        formatter_class=argparse.RawDescriptionHelpFormatter,
        )
    parser.add_argument('-r', '--region',
                        help='EC2 region')
    return parser.parse_args()

if '__main__' == __name__:
    from faws import Agent
    agent = Agent()
    instances_f = agent.callf('DescribeInstances')
    images_f = agent.callf('DescribeImages')
    # First make map of the AMIs of each instance
    instances = instances_f.result()
    instance_amis = dict()
    for instance_item in instances.tree().xpath('//instancesSet/item'):
        instance_id = instance_item.find('instanceId').text
        image_id = instance_item.find('imageId').text
        instance_amis[instance_id] = image_id
    # Now get the names of each
    ami_names = dict()
    amis_to_check = set(instance_amis.values())
    images = images_f.result()
    for image_item in images.tree().xpath('//imagesSet/item'):
        if len(amis_to_check) == 0:
            break
        image_id = image_item.find('imageId').text
        if image_id in amis_to_check:
            ami_names[image_id] = image_item.find('name').text
            amis_to_check.remove(image_id)
    # Now cross-reference and report
    print('\t'.join(['instanceId', 'amiName']))
    for instance_id in sorted(instance_amis.keys()):
        image_id = instance_amis[instance_id]
        image_name = ami_names[image_id]
        print('\t'.join([instance_id, image_name]))


import asyncio
import io
import sys

import pytest
from httpx import AsyncClient
from PIL import Image
from sqlalchemy.ext.asyncio import AsyncSession

from backend.config import settings
from backend.main import app
from backend.models import ImageModel, TweetModel, UserModel
from backend.models.base import Base
from backend.models.db_helper import db_helper
from backend.services.medias_services import add_image_path_to_db, get_image, save_image
from backend.tests.factories import TweetFactory, UserFactory

@pytest.fixture(scope="session")
async def db() -> AsyncSession:
    async for session in db_helper.session_dependency():
        yield session

@pytest.fixture(scope="session", autouse=True)
async def prepare_db():
    assert settings.mode == "TEST"

    async with db_helper.engine.begin() as conn:
        await conn.run_sync(Base.metadata.create_all)
    yield
    async with db_helper.engine.begin() as conn:
        await conn.run_sync(Base.metadata.drop_all)

@pytest.fixture(scope="session")
def event_loop(request):
    if sys.platform == "win32":
        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

    loop = asyncio.get_event_loop_policy().new_event_loop()
    yield loop
    loop.close()

@pytest.fixture
async def client(user: UserModel) -> AsyncClient:
    async with AsyncClient(
        app=app,
        base_url="http://127.0.0.1:5000/api",
        headers={"api-key": str(user.api_key)},
    ) as ac:
        yield ac
        await ac.aclose()

@pytest.fixture
async def user() -> UserModel:
    user: UserModel = await UserFactory()
    return user

@pytest.fixture
async def tweet(user) -> TweetModel:
    tweet = await TweetFactory(author=user)
    return tweet

@pytest.fixture
async def image_bytes() -> bytes:
    image = Image.new("RGB", (100, 100))
    io_obj = io.BytesIO()
    image.save(io_obj, format="JPEG")
    io_obj.seek(0)

    return io_obj.read()

@pytest.fixture
async def image(image_bytes: bytes) -> ImageModel:
    async for session in db_helper.session_dependency():
        path = await save_image(image_bytes)
        image_id = await add_image_path_to_db(session=session, photo_path=path)

        return await get_image(session=session, image_id=image_id)


import io
import requests

from flask import jsonify, Response
from flask_restful import Resource, reqparse
from PyPDF2 import PdfFileMerger

parser = reqparse.RequestParser()
parser.add_argument('pdf_urls', type=str, required=True, location='form', action='append')

class MergeResource(Resource):
    def post(self):
        args = parser.parse_args()

        merger = PdfFileMerger()

        failed_urls = []
        for pdf_url in args['pdf_urls']:
            if pdf_url == "":
                continue
            try:
                pdf_response = requests.get(pdf_url)
                pdf_bytes = pdf_response.content
                merger.append(fileobj=io.BytesIO(pdf_bytes))
            except Exception:
                failed_urls.append(pdf_url)
                continue

        if len(failed_urls) > 0:
            response = jsonify({'failed_urls': failed_urls})
            response.status_code = 400

            return response

        combined_pdf = io.BytesIO()
        merger.write(combined_pdf)
        combined_pdf.seek(0)

        response = Response(combined_pdf, mimetype='application/pdf')
        response.headers['Content-Disposition'] = "attachment; filename=%s.pdf" % 'pdf_name'

        return response


import torch
import torch.nn as nn
import numpy as np
import torch.optim as optim
from torch.utils.data import DataLoader
from torch.utils.data import sampler
from .tracker import Tracker

class Flatten(nn.Module):
    def forward(self, x):
        N = x.shape[0]
        return x.view(N,-1)

class TrackedModel:
    model = None
    tracker = None
    data = None

    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    dtype = torch.float32

    def __init__(self, model, data, val_data):
        self.model = model
        if torch.cuda.device_count() > 1:
            print("Let's use", torch.cuda.device_count(), "GPUs!")
            self.model = nn.DataParallel(self.model)
        self.model.to(self.device)
        self.tracker = Tracker()
        self.data = data
        self.val_data = val_data
        self.criterion = nn.CrossEntropyLoss()

    def load_model(self, param_file):
        self.model.load_state_dict(torch.load(param_file))

    def reset_data(self, data):
        self.data = data

    def train(self, optimizer, BATCH=64, MAX_EPOCH=80, MILESTONES=[40,60], GAMMA=0.1, MAX_ACCURACY=0.85, USE_VAL=False):
        NUM = self.data.shape[0]
        VAL = self.val_data.shape[0]

        loader_train = DataLoader(self.data, batch_size=BATCH,
                                  shuffle=True)
        loader_valid = DataLoader(self.val_data, batch_size=BATCH,
                                  shuffle=True)

        scheduler = optim.lr_scheduler.MultiStepLR(optimizer, milestones=MILESTONES, gamma=GAMMA)

        train_history = None
        val_history = None
        class_history = None

        train_accuracy = []
        val_accuracy = []

        for e in range(MAX_EPOCH):
            scheduler.step()
            self.model.train()
            epoch_train_history = None
            epoch_class_history = None

            epoch_train_correct = 0

            print("training epoch " + str(e) + " starts")
            for param_group in optimizer.param_groups:
                print("learning rate is ", param_group['lr'])
            for i, batch in enumerate(loader_train):
                X = (batch[:, :-2]).to(device=self.device, dtype=self.dtype)
                y = (batch[:, -2]).to(device=self.device, dtype=torch.long)
                c = (batch[:, -1]).to(device=self.device, dtype=torch.long)
                optimizer.zero_grad()
                scores = self.model(X)
                # index = np.argmax(scores.cpu().detach().numpy(), axis=1) - y.cpu().detach().numpy()
                # mask = np.where(index == 0)
                # correct = len(mask[0])

                _, predicted = torch.max(scores.data, 1)
                correct = predicted.eq(y.data).cpu().sum().numpy()

                accuracy = correct / X.shape[0]
                epoch_train_correct += correct

                if epoch_train_history is None:
                    epoch_train_history = self.tracker.track(scores.detach(), y)
                    epoch_class_history = c
                else:
                    epoch_train_history = np.hstack((epoch_train_history, self.tracker.track(scores.detach(), y)))
                    epoch_class_history = np.hstack((epoch_class_history, c))
                loss = self.criterion(scores, y)
                if i % 100 == 0:
                    # print(i)
                    # print('X is ', X)
                    # print(scores)
                    print("epoch is ", e, ", training loss is ", loss.item())
                    print("epoch is ", e, ", training accuracy is ", accuracy)
                loss.backward()
                optimizer.step()

            epoch_train_history = epoch_train_history.reshape(NUM, 1)
            epoch_class_history = epoch_class_history.reshape(NUM, 1)

            epoch_train_accuracy = epoch_train_correct / NUM
            train_accuracy.append(epoch_train_accuracy)

            if train_history is None:
                train_history = epoch_train_history
                class_history = epoch_class_history
            else:
                train_history = np.hstack((train_history, epoch_train_history))
                class_history = np.hstack((class_history, epoch_class_history))

            if not USE_VAL:
                continue

            epoch_val_history = None

            epoch_val_correct = 0
            epoch_val_total = 0
            # best_test = 0

            for i, batch in enumerate(loader_valid):
                self.model.eval()  # put model to evaluation mode
                X = (batch[:, :-1]).to(device=self.device, dtype=self.dtype)
                y = (batch[:, -1]).to(device=self.device, dtype=torch.long)
                with torch.no_grad():
                    scores = self.model(X)

                    # index = np.argmax(scores.cpu().detach().numpy(), axis=1) - y.cpu().detach().numpy()
                    # mask = np.where(index == 0)
                    # correct = len(mask[0])

                    _, predicted = torch.max(scores.data, 1)
                    correct = predicted.eq(y.data).cpu().sum().numpy()

                    accuracy = correct / X.shape[0]
                    epoch_val_total += X.shape[0]
                    epoch_val_correct += correct
                    loss = self.criterion(scores, y)
                    # print("epoch is ", e, ", test loss is ", loss.item())
                    # print("epoch is ", e, ", test accuracy is ", accuracy)
                    # if accuracy > best_test:
                    #    best_test = accuracy
                    if i % 100 == 0:
                        print("epoch is ", e, ", test loss is ", loss.item())
                        print("epoch is ", e, ", test accuracy is ", accuracy)
                    if epoch_val_history is None:
                        epoch_val_history = self.tracker.track(scores.detach(), y)
                    else:
                        epoch_val_history = np.hstack((epoch_val_history, self.tracker.track(scores.detach(), y)))

            # print(epoch_train_history.shape)
            # print(epoch_val_history.shape)

            epoch_val_accuracy = epoch_val_correct / VAL
            print('Epoch Val Total is ', epoch_val_total, ' VAL is ', VAL)

            epoch_val_history = epoch_val_history.reshape(VAL, 1)
            val_accuracy.append(epoch_val_accuracy)

            if val_history is None:
                val_history = epoch_val_history
            else:
                val_history = np.hstack((val_history, epoch_val_history))

            print('')
            print('epoch train accuracy is ', epoch_train_accuracy)
            print('epoch test accuracy is ', epoch_val_accuracy)
            # print('epoch best accuracy is ', best_test)
            if epoch_val_accuracy > MAX_ACCURACY:
                break
        #print(train_history.shape)
        #print(val_history.shape)

        return train_history, val_history, class_history, train_accuracy, val_accuracy


"""
pyape.uwsgiproxy
~~~~~~~~~~~~~~~~~~~
代理 uwsgi 模块的方法
"""
import warnings
import pickle
import importlib

in_uwsgi = False
uwsgi = None

try:
    uwsgi = importlib.import_module('uwsgi')
    in_uwsgi = True
except:
    in_uwsgi = False

def cache_get(key):
    if in_uwsgi:
        return uwsgi.cache_get(key)
    return None

def cache_set(key, value):
    if in_uwsgi:
        return uwsgi.cache_set(key, value)
    return None

def cache_del(key):
    if in_uwsgi:
        return uwsgi.cache_del(key)
    return None

def cache_exists(key):
    if in_uwsgi:
        return uwsgi.cache_exists(key)
    return None

def cache_update(key, value):
    if in_uwsgi:
        return uwsgi.cache_update(key, value)
    return None

def mule_msg(msg, mule_id=1):
    if in_uwsgi:
        try:
            uwsgi.mule_msg(pickle.dumps(msg, protocol=pickle.HIGHEST_PROTOCOL), mule_id)
        except Exception as e:
            warnings.warn(str(e))
    return None

def worker_id():
    if in_uwsgi:
        return uwsgi.worker_id()
    return -1

def register_signal(signum, target, func):
    """ 注册一个 uwsgi 信号
    :param signum: 信号量
    :param target: 字符串
        worker/worker0 将发送信号给第一个可用worker。如果你指定过一个空字符串，那么这是默认值。
        workers 会发送信号给每个worker。
        workerN (N > 0) 会发送信号给worker N。
        mule/mule0 会发送信号给第一个可用mule。 (见 uWSGI Mule)
        mules 会发送信号给所有mule。
        muleN (N > 0) 会发送信号给mule N。
    """
    if in_uwsgi:
        return uwsgi.register_signal(signum, target, func)
    return -1

def signal_registered(signum):
    """ 一个信号是否被注册
    """
    if not in_uwsgi:
        return None
    return uwsgi.signal_registered(signum)

def get_free_signal():
    """ 获取没有被注册的信号量，否则抛出一个错误
    """
    if not in_uwsgi:
        return None
    for signum in range(0, 256):
        if not uwsgi.signal_registered(signum):
            return signum
    raise IndexError("No free uwsgi signal available!")

def add_timer(signum, seconds):
    """ 注册一个定时器
    """
    if not in_uwsgi:
        return None
    return uwsgi.add_timer(signum, seconds)

class signal(object):
    """ register_signal 的装饰器模式
    """
    def __init__(self, signum, **kwargs):
        self.signum = signum
        self.target = kwargs.get('target', '')

    def __call__(self, f):
        uwsgi.register_signal(self.signum, self.target, f)
        return f

class timer(object):
    """ add_timer 的装饰器模式
    """
    def __init__(self, secs, **kwargs):
        self.signum = kwargs.get('signum', get_free_signal())
        self.secs = secs
        self.target = kwargs.get('target', '')

    def __call__(self, f):
        uwsgi.register_signal(self.signum, self.target, f)
        uwsgi.add_timer(self.signum, self.secs)
        return f


import matplotlib.pyplot
from sklearn.cluster import KMeans
import numpy
image = matplotlib.pyplot.imread("kmeans.jpg")
img_shape = image.shape
print (img_shape)
w = img_shape[0]
h = img_shape[1]
image = image.reshape(w*h,3)
print(image)
K = int(input("Enter K: "))
run = KMeans(n_clusters = K).fit(image)
labels = run.predict(image)

clusters = run.cluster_centers_

print(clusters)
print(labels)
# zero: 0, like: dimension like image
# new_image = numpy.zeros_like(image)
new_image = numpy.zeros((w,h,3), dtype=numpy.uint8)
x = 0
# reshape by self
for i in range(w):
    for j in range(h):
        new_image[i][j] = clusters[labels[x]]
        x += 1
# for i in range(len(new_image)):
#     new_image[i] = clusters[labels[i]]
# new_image = new_image.reshape(w, h, 3)
matplotlib.pyplot.imshow(new_image)
matplotlib.pyplot.show()


import discord
import os
import json
import datetime
import random
from discord.ext import commands
from core.classes import cog_ext

options = ("大吉", "吉", "小吉", "平", "小凶", "凶", "大凶", "你命由你不由天，自己幸福自己拼")

class luck (cog_ext):
  @commands.command ()
  async def 今日運勢 (self, ctx):
    f = open ("./datas/luck.json", "r", encoding = "utf-8")
    last_time = json.load (f)
    f.close ()

    f = open ("./datas/luck.json", "w", encoding = "utf-8")
    if (str (ctx.author.id) not in last_time):
      today_luck = random.choice (options)
      await ctx.reply (today_luck)
      last_time[str (ctx.author.id)] = [str (ctx.message.created_at.date ()), today_luck]

      json.dump (last_time, f)
      f.close ()
      return

    delta = ctx.message.created_at.date () - datetime.date.fromisoformat (last_time[str (ctx.author.id)][0])

    if (delta.days == 0):
      today_luck = last_time[str (ctx.author.id)][1]
      await ctx.reply (f"你是要問幾次啦，就跟你說今天是 {today_luck} 了")
    else:
      today_luck = random.choice (options)
      await ctx.reply (today_luck)
      last_time[str (ctx.author.id)] = [str (ctx.message.created_at.date ()), today_luck]

    # print (datetime.date.today () - datetime.date.fromisoformat (last_time[ctx.author.id]))
    json.dump (last_time, f)
    f.close ()

def setup (bot):
  bot.add_cog (luck (bot))


import requests # Import library that allows us to request data from API
import json # Import library that allows us to work with JSON files
from csv import writer #Import library that allows us to work with CSV files
def append_list_as_row(file_name, list_of_elem): #We create a function that allows us to save lists in seperate rows of CSV file

    with open(file_name, 'a+', newline='') as write_obj:

        csv_writer = writer(write_obj)
        csv_writer.writerow(list_of_elem)

apiendpoint="https://api.spacexdata.com/v3/launches" #API URL
response = requests.get(apiendpoint) #We request data from API
data = response.json() #We convert data that we received from API to a JSON file

for row in response.json(): #We convert the rows from JSON file into strings
    f_number = row.get('flight_number', None)
    name = row.get('mission_name', None)
    craft = row.get('rocket', None)
    patch=row.get("links",None)

    date_utc = row.get('launch_date_utc', None)

    data_list=[f_number,name,craft.get('rocket_id',None),craft.get('rocket_name',None),patch.get('video_link',None),date_utc] #We put the strings into a list
    append_list_as_row('flights.csv', data_list) #We save the list as a row in CSV
#Made by Jakub Kapidura with the help of resources from the Internet


import os
import csv
import shutil
from PIL import Image
from src.datasets import labels, compute_split_weights
from src.datasets.datagen.loader import load_from_split

def copy_img_to_ds(src, dst, size=(600, 600)):
    img = Image.open(src).convert('L')
    img = img.resize(size)
    img.save(dst)

def create_split_dir(split, split_name, labels, data_dir):
    split_dir = os.path.sep.join([data_dir, split, split_name])

    labels = ['unknown'] if split_name == 'test' else labels

    # create dirs for labels into {split_dir}
    for label in labels:
        label_dir = os.path.sep.join([split_dir, label])
        if not os.path.exists(label_dir):
            os.makedirs(label_dir)

    return split_dir

def generate_split(split, data_dir, sets=[]):
    dataset_paths = {}

    for (x_split, y_split), split_name in sets:
        split_dir = create_split_dir(split, split_name, labels, data_dir)

        # labels counter to determine file name based on split and label
        labels_counter = {'normal': 0, 'covid': 0, 'pneumonia': 0}

        X, y = [], []

        for img, label in zip(x_split, y_split):
            y.append(label)

            # str representation of the label
            label = labels[label]

            i = labels_counter[label]
            dest = os.path.sep.join(
                [split_dir, label, "{0:04d}.jpg".format(i)])
            copy_img_to_ds(img, dest)
            X.append(dest)
            labels_counter[label] += 1

        dataset_paths[split_name] = (X, y)

    return dataset_paths

def create_dataset(dataset, version, data_dir, split, splits_dir, **kwargs):
    data_dir = data_dir if data_dir else os.path.sep.join(
        ["./data", dataset, "data"])

    # Load splits and save those into a new dataset called {dataset}
    train_split_path = os.path.sep.join([splits_dir, split, "train.txt"])
    test_split_path = os.path.sep.join([splits_dir, split, "test.txt"])
    val_split_path = os.path.sep.join([splits_dir, split, "val.txt"])
    train_split = (load_from_split(
        version, data_dir, train_split_path), 'train')
    val_split = (load_from_split(version, data_dir, val_split_path), 'val')
    test_split = (load_from_split(version, data_dir, test_split_path), 'test')

    # splits to iterate
    train_val_test = [train_split, val_split, test_split]
    train_val = [train_split, val_split]

    # generate labeled train and val sets
    generate_split(split, data_dir, sets=train_val)

    # generate all datasets in one
    sets = ([], [])
    for (X, y), _ in train_val_test:
        sets = (X + sets[0], y + sets[1])
    paths = generate_split(split, data_dir, sets=[(sets, 'dataset')])
    (X, y) = paths['dataset']

    # weights = compute_split_weights(X, y)

    # generate test with unknown label
    (x_split, y_split), split_name = test_split
    split_dir = create_split_dir(split, split_name, labels, data_dir)

    # labels counter to determine file name based on split and label
    i = 0
    filenames, y_test = [], []

    for img, label in zip(x_split, y_split):
        dest = os.path.sep.join(
            [split_dir, 'unknown', "{0:04d}.jpg".format(i)])
        copy_img_to_ds(img, dest)
        filenames.append("{0:04d}.jpg".format(i))
        y_test.append(label)
        i += 1

    # save test labels for kaggle
    with open(os.path.sep.join([data_dir, split, 'derived.csv']), mode='w') as f:
        writer = csv.writer(f, delimiter=',', quotechar='"',
                            quoting=csv.QUOTE_MINIMAL)
        # writer.writerow(['Id', 'Expected', 'Weight'])
        writer.writerow(['Id', 'Expected'])
        for f, y in zip(filenames, y_test):
            # weight = weights[y]
            # writer.writerow([f, str(y), str(weight)])
            writer.writerow([f, str(y)])


import sys
import math
from dataclasses import dataclass

dirs = {"R": (1, 0), "U": (0, 1), "L": (-1, 0), "D": (0, -1)}

@dataclass
class Knot:
    x: int = 0
    y: int = 0

    def follow(self, r):
        hx, hy = r.pos()
        mx = abs(self.x - hx)
        my = abs(self.y - hy)
        mult = 1
        if my == 2 and mx == 2:
            mult = 2
        if my == 2 and mx == 1:
            self.x = hx
        if my == 1 and mx == 2:
            self.y = hy

        dist = abs(self.x - hx) + abs(self.y - hy)

        if dist > 1:
            angle = math.atan2(self.x - hx, self.y - hy)
            move_by_cos = -math.cos(angle) * mult
            move_by_sin = -math.sin(angle) * mult
            self.move(int(move_by_sin), int(move_by_cos))

    def move(self, dx, dy):
        self.x += dx
        self.y += dy

    def pos(self):
        return (self.x, self.y)

def solve(data, times):
    locations = set()
    rope = [Knot() for _ in range(times)]
    for d in data:
        dirt, t = d.split()
        for _ in range(int(t)):
            rope[0].move(*dirs[dirt])
            for i, r in enumerate(rope[1:]):
                r.follow(rope[i])
            locations.add(rope[-1].pos())

    return len(locations)

if __name__ == "__main__":
    d = sys.stdin.read().split("\n")
    print("part 1:", solve(d, 2))
    print("part 2:", solve(d, 10))


"""
Update manager for ReaCoMa
"""
import toga
from toga.style import Pack
from toga.style.pack import COLUMN, ROW
from pathlib import Path

class Grim(toga.App):

    def startup(self):
        main_box = toga.Box(style=Pack(direction=COLUMN))

        # Row for Directory pointing
        self.find = toga.Button(
            'ReaCoMa location',
            on_press = self.find_reacoma,
            style=Pack(padding=5)
        )
        self.dir_label = toga.TextInput(
            readonly=True,
            style=Pack(padding=5, width=500)
        )
        dir_box = toga.Box(style=Pack(direction=ROW))
        dir_box.add(self.find)
        dir_box.add(self.dir_label)

        # Add things to main box
        main_box.add(dir_box)

        self.main_window = toga.MainWindow(title=self.formal_name)
        self.main_window.content = main_box
        self.main_window.show()

    def get_me(self, btn):
        print(self.rand_label.value)

    def find_reacoma(self, btn):
        """pass the button that was pressed into the function"""
        p = self.main_window.select_folder_dialog('ReaCoMa location')

        if len(p) != 0:
            self.reacoma_dir = Path(p[0]).resolve()
            self.dir_label.value = str(self.reacoma_dir)

def main():
    return Grim()


import matplotlib.pyplot as plt

def show_img(img_hr, img_lr):
    plt.figure(figsize=(14,10))
    plt.subplot(1,2,1)
    plt.xticks([])
    plt.yticks([])
    plt.title("high resolution image")
    plt.imshow(img_hr)
    plt.subplot(1,2,2)
    plt.xticks([])
    plt.yticks([])
    plt.title("low resolution image")
    plt.imshow(img_lr)
    plt.show()


import sys
from datetime import datetime

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

if option=='add':
    try:
        with open('todo.txt','a') as todoFile:
            todoFile.write(str(sys.argv[2])+"\n")
            print('Added todo: "{}"'.format(sys.argv[2]))
            todoFile.close()
    except IndexError:
        print('Error: Missing todo string. Nothing added!')

elif option=='ls':
    try:
        with open('todo.txt','r') as todoFile:
            todoItems=list(todoFile)
            if len(todoItems)>0:
                for i in range(len(todoItems),0,-1):
                    print("[{}] {}".format(i,todoItems[i-1]),end="")
            else:
                raise FileNotFoundError()
    except FileNotFoundError:
        print('There are no pending todos!')

elif option=='help':
    help = """Usage :-\n$ ./todo add \"todo item\"  # Add a new todo\n$ ./todo ls               # Show remaining todos\n$ ./todo del NUMBER       # Delete a todo\n$ ./todo done NUMBER      # Complete a todo\n$ ./todo help             # Show usage\n$ ./todo report           # Statistics"""
    print (help)

elif option=='del':
    try:
        index = int(sys.argv[2])
        with open('todo.txt','r') as oldTodo:
            todoItems=list(oldTodo)
            try:
                if index<=0: raise IndexError
                del todoItems[index-1]
                with open('todo.txt','w') as newTodo:
                    for item in todoItems:
                        newTodo.write(item)
                    newTodo.close()
                    print("Deleted todo #{}".format(index))
            except IndexError:
                print('Error: todo #{} does not exist. Nothing deleted.'.format(index))
            oldTodo.close()
    except IndexError:
        print("Error: Missing NUMBER for deleting todo.")
    except FileNotFoundError:
        print('There are no pending todos!')

elif option=='done':
    try:
        index = int(sys.argv[2])
        with open('todo.txt','r') as todoFile:
            todoItems=list(todoFile)
            try:
                if index<=0: raise IndexError
                todo=todoItems[index-1]
                del todoItems[index-1]
                with open('done.txt','a') as doneFile:
                    doneFile.write('x {} {}'.format(datetime.today().strftime('%Y-%m-%d'),todo))
                with open('todo.txt','w') as newTodo:
                    for item in todoItems:
                        newTodo.write(item)
                    newTodo.close()
                print("Marked todo #{} as done.".format(index))

            except IndexError:
                print('Error: todo #{} does not exist.'.format(index))

    except IndexError:
        print('Error: Missing NUMBER for marking todo as done.')
    except FileNotFoundError:
        print('There are no pending todos!')

elif option=='report':
    try:
        with open('todo.txt','r') as pendingTodo:
            pending=len(list(pendingTodo))
        with open('done.txt','r') as completedTodo:
            completed=len(list(completedTodo))
        date=datetime.today().strftime('%Y-%m-%d')
        print("{} Pending : {} Completed : {}".format(date,pending,completed))
    except FileNotFoundError:
        print('There are no pending todos!')


import datetime

from django.test import TestCase

from autofixture import AutoFixture

from teamlogic.models import Cup
from teamlogic.models import Match
from teamlogic.models import MatchInLeague
from teamlogic.models import MatchPair
from teamlogic.models import Tournament

class TestUtils(object):
    @staticmethod
    def create_match(home_goal, away_goal,
                     home_goal_first=None, away_goal_first=None):
        home_goal_first = home_goal_first or 0
        away_goal_first = away_goal_first or 0
        fixture_match = AutoFixture(
            Match, generate_fk=True,
            field_values={'home_goal': home_goal,
                          'away_goal': away_goal,
                          'home_goal_first': home_goal_first,
                          'away_goal_first': home_goal_first})
        return fixture_match.create(1)[0]

    @staticmethod
    def create_tournament(beginDate=None, endDate=None):
        beginDate = beginDate or datetime.date(2007, 4, 24)
        endDate = endDate or datetime.date(2010, 4, 22)
        fixture_tournament = AutoFixture(
            Tournament, generate_fk=True,
            field_values={'begin_date': beginDate,
                          'end_date': endDate})
        return fixture_tournament.create(1)[0]

    @staticmethod
    def create_cup(beginDate=None, endDate=None):
        beginDate = beginDate or datetime.date(2007, 4, 25)
        endDate = endDate or datetime.date(2008, 1, 1)
        fixture_cup = AutoFixture(
            Cup, generate_fk=True,
            field_values={'begin_date': beginDate,
                          'end_date': endDate})
        return fixture_cup.create(1)[0]

class TestMatches(TestCase):
    def test_drawn_result(self):
        match = TestUtils.create_match(1, 1, 0, 0)
        self.assertTrue(match.is_drawn())

    def test_home_winner_result_positive(self):
        match = TestUtils.create_match(1, 0, 0, 0)
        self.assertTrue(match.is_home_winner())

    def test_home_winner_result_negative(self):
        match = TestUtils.create_match(0, 1, 0, 0)
        self.assertFalse(match.is_home_winner())

    def test_away_winner_result_positive(self):
        match = TestUtils.create_match(0, 1, 0, 0)
        self.assertTrue(match.is_away_winner())

    def test_away_winner_result_negative(self):
        match = TestUtils.create_match(1, 0, 0, 0)
        self.assertFalse(match.is_away_winner())

    def test_getWinner(self):
        match = TestUtils.create_match(1, 0, 0, 0)
        self.assertEqual(match.getWinner(), match.home)

        match = TestUtils.create_match(0, 1, 0, 0)
        self.assertEqual(match.getWinner(), match.away)

        match = TestUtils.create_match(0, 0, 0, 0)
        self.assertEqual(match.getWinner(), None)

    def test_this_team(self):
        match = TestUtils.create_match(1, 0, 0, 0)
        self.assertTrue(match.this_team(match.home))
        self.assertTrue(match.this_team(match.away))
        other_match = TestUtils.create_match(1, 0, 0, 0)
        self.assertFalse(match.this_team(other_match.home))

class TestTournament(TestCase):
    def test_get_season(self):
        for result, end_year in [('2007/2008', 2008), ('2007', 2007)]:
            tournament = TestUtils.create_tournament(
                beginDate=datetime.date(2007, 4, 22),
                endDate=datetime.date(end_year, 11, 23)
            )
            self.assertEqual(result, tournament.get_season())

class TestMatchPair(TestCase):
    def test_getWinner(self):
        # For two match in pair
        first_match = TestUtils.create_match(1, 0, 0, 0)
        second_match = TestUtils.create_match(2, 0, 0, 0)
        second_match.home = first_match.away
        second_match.away = first_match.home

        pair = MatchPair.objects.create(
            first_match=first_match,
            second_match=second_match,
            cup=TestUtils.create_cup(),
            only_one_match=False,
            is_penalty=False)

        self.assertEqual(pair.getWinner(), second_match.home)
        self.assertEqual(pair.getWinner(), first_match.away)

        # For two match in pair with penalty
        second_match = TestUtils.create_match(1, 0, 0, 0)
        second_match.home = first_match.away
        second_match.away = first_match.home

        pair.second_match = second_match
        pair.first_penalty = 5
        pair.second_penalty = 6

        self.assertEqual(pair.getWinner(), first_match.away)
        self.assertEqual(pair.getWinner(), second_match.home)

        pair.only_one_match = True
        self.assertEqual(pair.getWinner(), first_match.home)

        pair.first_match.away_goal = 1
        self.assertEqual(pair.getWinner(), first_match.away)
        # For one match in pair with penalty

    def test_unicode(self):
        first_match = TestUtils.create_match(1, 0, 0, 0)
        second_match = TestUtils.create_match(2, 0, 0, 0)
        second_match.home = first_match.away
        second_match.away = first_match.home

        pair = MatchPair.objects.create(
            first_match=first_match,
            second_match=second_match,
            cup=TestUtils.create_cup(),
            only_one_match=False,
            is_penalty=False)

        self.assertEqual(unicode('%s - %s' % (first_match.home.name,
                                               second_match.home.name)),
                         pair.__unicode__())


"""消息链处理器用到的工具函数, 类"""
import argparse
import inspect
import re
from contextvars import ContextVar
from typing import (
    TYPE_CHECKING,
    Callable,
    ClassVar,
    Dict,
    Final,
    List,
    Literal,
    NoReturn,
    Optional,
    Type,
    TypeVar,
    Union,
    overload,
)

from graia.amnesia.message.chain import MessageChain

from avilla.core.elements import Element, Notice, NoticeAll, Text
from avilla.core.utilles import identity

from .typing import T

if TYPE_CHECKING:
    from .twilight import Twilight

Element_T = TypeVar("Element_T", bound=Element)
elem_mapping_ctx: ContextVar[Dict[str, Element]] = ContextVar("elem_mapping_ctx")

def split(string: str, keep_quote: bool = False) -> List[str]:
    """尊重引号与转义的字符串切分

    Args:
        string (str): 要切割的字符串
        keep_quote (bool): 是否保留引号, 默认 False.

    Returns:
        List[str]: 切割后的字符串, 可能含有空格
    """
    result: List[str] = []
    quote = ""
    cache: List[str] = []
    for index, char in enumerate(string):
        if char in {"'", '"'}:
            if not quote:
                quote = char
            elif char == quote and index and string[index - 1] != "\\":  # is current quote, not transfigured
                quote = ""
            else:
                cache.append(char)
                continue
            if keep_quote:
                cache.append(char)
        elif not quote and char == " ":
            result.append("".join(cache))
            cache = []
        elif char != "\\":
            cache.append(char)
    if cache:
        result.append("".join(cache))
    return result

def gen_flags_repr(flags: re.RegexFlag) -> str:
    """通过 RegexFlag 生成对应的字符串

    Args:
        flags (re.RegexFlag): 正则表达式的标记

    Returns:
        str: 对应的标记字符串
    """
    flags_list: List[str] = []

    if re.ASCII in flags:
        flags_list.append("a")
    if re.IGNORECASE in flags:
        flags_list.append("i")
    if re.LOCALE in flags:
        flags_list.append("L")
    if re.MULTILINE in flags:
        flags_list.append("m")
    if re.DOTALL in flags:
        flags_list.append("s")
    if re.UNICODE in flags:
        flags_list.append("u")
    if re.VERBOSE in flags:
        flags_list.append("x")

    return "".join(flags_list)

def transform_regex(flag: re.RegexFlag, regex_pattern: str) -> str:
    """生成嵌套正则表达式字符串来达到至少最外层含有一个捕获组的效果

    Args:
        flag (re.RegexFlag): 正则表达式标记
        regex_pattern (str): 正则表达式字符串

    Returns:
        str: 转换后的正则表达式字符串
    """
    return f"(?{gen_flags_repr(flag)}:({regex_pattern}))" if flag else f"({regex_pattern})"

class MessageChainType:
    """用于标记类型为消息链, 在 ArgumentMatch 上使用"""

    @staticmethod
    def __call__(string: str) -> MessageChain:
        return _from_mapping_string(string, elem_mapping_ctx.get())

class ElementType:
    """用于标记类型为消息链元素, 在 ArgumentMatch 上使用"""

    def __init__(self, pattern: Type[Element_T]):
        self.regex = re.compile(f"\x02(\\d+)_{identity(pattern)}\x03")

    def __call__(self, string: str) -> Element:
        if not self.regex.fullmatch(string):
            raise ValueError(f"{string} not matching {self.regex.pattern}")
        return _from_mapping_string(string, elem_mapping_ctx.get())[0]

class UnmatchedClass:
    __slots__ = ()

    def __repr__(self) -> str:
        return "<Unmatched>"

    def __bool__(self) -> bool:
        return False

Unmatched = UnmatchedClass()

class TwilightParser(argparse.ArgumentParser):
    """适于 Twilight 使用的 argparse.ArgumentParser 子类
    移除了报错时自动退出解释器的行为
    """

    def error(self, message) -> NoReturn:
        raise ValueError(message)

    def accept_type(self, action: Union[str, type]) -> bool:
        """检查一个 action 是否接受 type 参数

        Args:
            action (Union[str, type]): 检查的 action

        Returns:
            bool: 是否接受 type 参数
        """
        if action is ...:
            action = "store"
        if isinstance(action, str):
            action_cls: Type[argparse.Action] = self._registry_get("action", action, action)
        elif isinstance(action, type) and issubclass(action, argparse.Action):
            action_cls = action
        else:
            return False
        action_init_sig = inspect.signature(action_cls.__init__)
        if "type" not in action_init_sig.parameters:
            return False
        return True

class TwilightHelpManager:
    AUTO_ID: Final[str] = "&auto_id" + hex(id("&auto_id"))
    _manager_ref: ClassVar[Dict[str, "TwilightHelpManager"]] = {}

    name: str
    display_name: Optional[str]
    help_map: Dict[str, "Twilight"]

    def __init__(self, name: str, display_name: Optional[str] = AUTO_ID):
        self.name: str = name
        self.help_map: Dict[str, Twilight] = {}
        if display_name == self.AUTO_ID:
            self.display_name = None if name.startswith(("global", "local", "_")) else name
        else:
            self.display_name = display_name
        if name in TwilightHelpManager._manager_ref:
            global_ref = TwilightHelpManager._manager_ref[name]
            global_ref.display_name = global_ref.display_name or display_name
            self.help_map = global_ref.help_map
        else:
            TwilightHelpManager._manager_ref[name] = self

    def register(self, twilight: "Twilight") -> None:
        if twilight.help_id == self.AUTO_ID:
            from .twilight import ElementMatch, ParamMatch, RegexMatch, UnionMatch

            extracted_ids: List[str] = []
            for match in twilight.matcher.origin_match_list:
                if isinstance(match, UnionMatch):
                    extracted_ids.extend(match.pattern)
                elif isinstance(match, ElementMatch):
                    extracted_ids.append(match.type.__name__)
                elif isinstance(match, RegexMatch) and not isinstance(match, ParamMatch):
                    extracted_ids.append(match.pattern)
            if not extracted_ids:
                raise ValueError(f"Unable to extract help_id from {twilight}")
            help_id = extracted_ids[0]
        else:
            help_id = twilight.help_id
        if help_id in self.help_map and self.help_map[help_id] is not twilight:
            raise ValueError(
                f"Help Manager {self.name}'s help id {help_id} has been registered", self.help_map[help_id]
            )
        self.help_map[help_id] = twilight

    @classmethod
    def get_help_mgr(cls, mgr: Union["TwilightHelpManager", str]) -> "TwilightHelpManager":
        return TwilightHelpManager(mgr) if isinstance(mgr, str) else mgr

    @overload
    def get_help(
        self,
        description: str = "",
        epilog: str = "",
        *,
        prefix_src: Literal["brief", "usage", "description"] = "brief",
        fmt_cls: Type[argparse.HelpFormatter] = argparse.HelpFormatter,
    ) -> str:
        ...

    @overload
    def get_help(
        self,
        description: str = "",
        epilog: str = "",
        *,
        prefix_src: Literal["brief", "usage", "description"] = "brief",
        fmt_func: Callable[[str], T],
        fmt_cls: Type[argparse.HelpFormatter] = argparse.HelpFormatter,
    ) -> T:
        ...

    def get_help(
        self,
        description: str = "",
        epilog: str = "",
        *,
        prefix_src: Literal["brief", "usage", "description"] = "brief",
        fmt_func: Optional[Callable[[str], T]] = None,
        fmt_cls: Type[argparse.HelpFormatter] = argparse.HelpFormatter,
    ) -> Union[T, str]:
        """获取本管理器总的帮助信息

        Args:
            fmt_func (Optional[Callable[[str], T]]): 如果指定, 则使用该函数来转换帮助信息格式
            fmt_cls (Type[argparse.HelpFormatter], optional): 如果指定, 则使用该类来格式化帮助信息. \
                默认为 argparse.HelpFormatter
        """
        formatter = fmt_cls("")
        formatter.add_usage(self.display_name or "", [], [], "")

        formatter.add_text(description)

        if self.help_map:
            formatter.start_section(f"共有 {len(self.help_map)} 个子匹配")
            for help_id, twilight in self.help_map.items():
                if twilight.help_data is not None:
                    prefixes: Dict[str, str] = {
                        "brief": twilight.help_brief,
                        "usage": twilight.help_data["usage"],
                        "description": twilight.help_data["description"],
                    }
                    formatter.add_text(f"{help_id} - {prefixes[prefix_src]}")
                else:
                    formatter.add_text(f"{help_id}")
            formatter.end_section()

        formatter.add_text(epilog)

        help_string: str = formatter.format_help()
        return fmt_func(help_string) if fmt_func else help_string

def _to_mapping_str(
    chain: MessageChain,
    *,
    remove_source: bool = True,
    remove_quote: bool = True,
    remove_extra_space: bool = False,
) -> tuple[str, Dict[str, Element]]:
    """转换消息链为映射字符串与映射字典的元组.
    Args:
        remove_source (bool, optional): 是否移除消息链中的 Source 元素. 默认为 True.
        remove_quote (bool, optional): 是否移除消息链中的 Quote 元素. 默认为 True.
        remove_extra_space (bool, optional): 是否移除 Quote At AtAll 的多余空格. 默认为 False.
    Returns:
        Tuple[str, Dict[str, Element]]: 生成的映射字符串与映射字典的元组
    """
    elem_mapping: Dict[str, Element] = {}
    elem_str_list: List[str] = []
    for i, elem in enumerate(chain.content):
        if not isinstance(elem, Text):
            elem_mapping[str(i)] = elem
            elem_str_list.append(f"\x02{i}_{identity(elem)}\x03")
        elif (
            remove_extra_space
            and i  # not first element
            and isinstance(
                chain.content[i - 1], (Notice, NoticeAll)
            )  # following elements which have an dumb trailing space
            and elem.text.startswith("  ")  # extra space (count >= 2)
        ):
            elem_str_list.append(elem.text[1:])
        else:
            elem_str_list.append(elem.text)
    return "".join(elem_str_list), elem_mapping

__element_pattern = re.compile("(\x02\\w+\x03)")

def gen_subclass(cls: type[T]):  # pyright: ignore
    """生成某个类的所有子类 (包括其自身)

    Args:
        cls (Type[T]): 类

    Yields:
        Type[T]: 子类
    """
    yield cls
    for sub_cls in cls.__subclasses__():
        if TYPE_CHECKING:
            assert issubclass(sub_cls, cls)
        yield from gen_subclass(sub_cls)

ELEMENT_MAPPING: Dict[str, Type[Element]] = {identity(i): i for i in gen_subclass(Element)}

def _from_mapping_string(string: str, mapping: Dict[str, Element]) -> MessageChain:
    """从映射字符串与映射字典的元组还原消息链.
    Args:
        string (str): 映射字符串
        mapping (Dict[int, Element]): 映射字典.
    Returns:
        MessageChain: 构建的消息链
    """
    elements: List[Element] = []
    for x in __element_pattern.split(string):
        if x:
            if x[0] == "\x02" and x[-1] == "\x03":
                index, class_name = x[1:-1].split("_")
                if not isinstance(mapping[index], ELEMENT_MAPPING[class_name]):
                    raise ValueError("Validation failed: not matching element type!")
                elements.append(mapping[index])
            else:
                elements.append(Text(x))
    return MessageChain(elements)

{'ElementMatch': 'twilight.ElementMatch', 'ParamMatch': 'twilight.ParamMatch', 'RegexMatch': 'twilight.RegexMatch', 'UnionMatch': 'twilight.UnionMatch'}


import os
import re

import bpy

def getsequences():
    return list(bpy.context.scene.sequence_editor.sequences_all)

def getnearbysequences(clip, range):
    """
    get clips above clip and within time boundaries of clip
    """
    returnlist = []
    clipparent = clip.parent_meta()
    for i in getsequences():
        if i.parent_meta() != clipparent.parent_meta():
            continue
        if (
            i.channel >= (clip.channel - range)
            and i.channel < clip.channel
            and i.frame_start >= clip.frame_start
            and i.frame_final_end <= clip.frame_final_end
        ):
            returnlist.append(i)
            if len(returnlist) >= range:
                break
    returnlist.sort(key=lambda x: x.channel, reverse=True)
    return returnlist

# TODO comment difference between this and getsequences
def gettopsequences():
    return list(bpy.context.scene.sequence_editor.sequences)

# some things don't have a good API so proceditor needs to emulate a user by
# selecting and doing stuff with the clips
# This is needed to restore the selection afterwards
def saveselection():
    returnlist = []
    for i in getsequences():
        if i.select:
            returnlist.append(i)
    return returnlist

# restore clip selection after emulating a user due to lack of good API
def restoreselection(selectlist):
    bpy.ops.sequencer.select(deselect_all=True)
    for i in selectlist:
        i.select = True

def savesequences():
    returnlist = []
    for i in gettopsequences():
        returnlist.append(i.name)
    return returnlist

# return newly added sequences
def getnewsequences(sequencelist):
    returnlist = []
    for i in sequencelist:
        if i not in returnlist:
            returnlist.append(bpy.context.scene.sequence_editor.sequences[i])
    return returnlist

# get sequences witout the compiler marker _c$, optionally filter through regex
def getmarkupsequences(regex="", compiled=False):
    sequences = bpy.context.scene.sequence_editor.sequences
    returnlist = []
    # compiled sequences have a _c at the end but may also have an auto assigned
    # number
    tpattern = re.compile(".*(_c|_c\\.[0-9]*)$")
    if not regex == "":
        fpattern = re.compile(regex)
    for i in sequences:
        if type(i) == bpy.types.TextSequence and (
            not compiled
            and not tpattern.match(i.name)
            or (compiled and tpattern.match(i.name))
        ):
            # with custom search string
            if not regex == "":
                if not fpattern.match(i.text):
                    continue
            returnlist.append(i)
    return returnlist

# get template clip with format template.name
def gettemplate(tname):
    templatename = "template_" + tname
    for i in gettopsequences():
        if i.name.startswith(templatename):
            os.system("echo " + i.name + " >> /tmp/test.txt")
            return i

    return False

# get all sequeces that match the given regex
def getresequences(regex, stype=0):
    retsequences = []
    pattern = re.compile(regex)
    for i in getsequences():
        if pattern.match(i.name):
            if stype == 0:
                retsequences.append(i)
            elif type(i) == stype:
                retsequences.append(i)
    return retsequences

# restore graphical clip highlight
def activateselection():
    for i in getsequences():
        if i.select:
            bpy.context.scene.sequence_editor.active_strip = i
            return

# replace markup clip with matching template
def replacemarkupclip(clip: bpy.types.TextSequence, templatename: str):

    sequences = bpy.context.scene.sequence_editor.sequences
    if not templatename or templatename == "":
        return False

    markupcontent = clip.text
    startframe = clip.frame_final_start
    markupduration = clip.frame_final_duration
    markupchannel = clip.channel
    clipname = clip.name

    removeclip(clip)

    templateclip = gettemplate(templatename)
    templatelength = templateclip.frame_final_duration

    if not templateclip:
        return False

    bpy.ops.sequencer.select_all(action="DESELECT")

    sequences[templateclip.name].select = True

    # maybe replace ops with api
    bpy.ops.sequencer.duplicate_move(
        SEQUENCER_OT_duplicate={},
        TRANSFORM_OT_seq_slide={
            "value": (
                startframe - templateclip.frame_final_start,
                markupchannel - templateclip.channel,
            ),
            "release_confirm": False,
            "use_accurate": False,
        },
    )

    newclip = list(
        filter(
            lambda element: element.select,
            list(bpy.context.scene.sequence_editor.sequences),
        )
    )[0]
    newclip.frame_final_duration = markupduration
    newclip.name = clipname + "_c"
    newclip["pcontent"] = markupcontent
    newclip["templatelength"] = templatelength

    return newclip

def getkeyframes(clipname):
    returnlist = []
    matchpath = 'sequence_editor.sequences_all["' + clipname + '"]'
    for action in bpy.data.actions:
        for curve in list(action.fcurves):
            if curve.data_path.startswith(matchpath):
                returnlist += list(curve.keyframe_points)
    return returnlist

def removeclip(clip):
    bpy.ops.sequencer.select(deselect_all=True)
    clip.select = True
    bpy.ops.sequencer.delete()

# move keyframes at the end of the clip towards the end

def adjustkeyframes(clip, oldduration):
    frames = getkeyframes(clip.name)

    if len(frames) == 0:
        return

    beginframes = []
    endframes = []

    for i in frames:
        frametime = i.co[0]
        if frametime > (clip.frame_final_start + oldduration / 2):
            endframes.append(i)
        else:
            beginframes.append(i)

    if len(endframes) == 0:
        return

    endoffset = clip.frame_final_duration - oldduration
    for i in endframes:
        i.co[0] += endoffset

def gettopchannel(frame):
    channel = 0
    for i in getsequences():
        if i.frame_final_start <= frame and i.frame_final_end >= frame:
            if i.channel > channel:
                channel = i.channel
    return channel + 1


import sys
from PyQt5.QtWidgets import *
import pyautogui
from PyQt5.QtGui import QIcon, QPixmap, QFont
from PyQt5.QtCore import QCoreApplication, QTimer

class 생선자동포장프로그램(QWidget):
    def __init__(self):
        super().__init__()
        self.UI초기화()

    def UI초기화(self):

        self.포장카운트 = 0
        self.클릭횟수카운트 = 0

        self.대표이미지()
        self.생선포장수()
        self.포장버튼()

        self.setWindowTitle('생선자동포장')
        self.setWindowIcon(QIcon('png_sample/20211026_150102.png'))
        self.setGeometry(800,300,1000,540)
        self.show()

    def 대표이미지(self):
        self.대표이미지라벨 = QLabel(self)
        self.대표이미지라벨.setPixmap(QPixmap('').scaled(35,44))
        self.대표이미지라벨.move(10,10)

    def 생선포장수(self):
        self.생선포장수라벨 = QLabel('00마리가 포장됨',self)
        self.생선포장수라벨.setFont(QFont('halvetica', pointSize=22, weight=2))
        self.생선포장수라벨.move(30,70)

    def 포장버튼(self):
        self.생선준비버튼 = QPushButton('생선준비',self)
        self.생선준비버튼.move(30,150)
        self.생선준비버튼.setFixedSize(250,40)

        self.생선다듬기버튼 = QPushButton('다듬기',self)
        self.생선다듬기버튼.move(300,150)
        self.생선다듬기버튼.setFixedSize(250,40)

        self.생선포장버튼 = QPushButton('포장',self)
        self.생선포장버튼.move(30,200)
        self.생선포장버튼.setFixedSize(520,40)
        self.생선포장버튼.clicked.connect(self.countClick)

        self.생선시작버튼 = QPushButton('시작',self)
        self.생선시작버튼.move(300,300)
        self.생선시작버튼.setFixedSize(250,40)
        self.생선포장버튼.clicked.connect(self.startClick)

        self.간격입력창 = QLineEdit(self)
        self.간격입력창.setPlaceholderText('클릭간격 (초)')
        self.간격입력창.move(30,300)

        self.간격입력창설명라벨 = QLabel('몇초간격으로 포장할지 입력',self)
        self.간격입력창설명라벨.setFont(QFont('halvetica', pointSize=7, weight=2))
        self.간격입력창설명라벨.move(30,340)

        self.횟수입력창 = QLineEdit(self)
        self.횟수입력창.setPlaceholderText('클릭\횟수')
        self.횟수입력창.move(30,400)

        self.횟수입력창설명라벨 = QLabel('몇초간격으로 포장할지 입력',self)
        self.횟수입력창설명라벨.setFont(QFont('halvetica', pointSize=7, weight=2))
        self.횟수입력창설명라벨.move(30,440)

    def countClick(self):
        self.포장카운트 += 1
        self.생선포장수라벨.setText(f'{str(self.포장카운트)}마리가 포장됨')

    def startClick(self):
        self.timer = QTimer()
        self.x = 550
        self.y = 510
        self.delay = int(self.간격입력창.text())

        self.timer.start(self.delay*1000)
        self.timer.timeout.connect(self.mouseClick)

    def mouseClick(self):
        pyautogui.click(self.x, self.y)
        self.클릭횟수카운트 += 1

        if self.클릭횟수카운트 == int(self.횟수입력창.text()):
            self.timer.stop()

프로그램무한반복 = QApplication(sys.argv)
실행인스턴스 = 생선자동포장프로그램()
프로그램무한반복.exec_()