import graphene
import json
from collections import namedtuple
from elasticsearch import Elasticsearch
import urllib.parse

client = Elasticsearch()

def _json_object_hook(d):
    return namedtuple('X', d.keys())(*d.values())

def json2obj(data):
    as_python = json.loads(data, object_hook=_json_object_hook)
    return as_python

class Form(graphene.ObjectType):
    form_id = graphene.String()
    orth = graphene.String()
    gram = graphene.String()
    usgs = graphene.List(graphene.String)

class Sense(graphene.ObjectType):
    sense_id = graphene.String()
    definition = graphene.String()
    usgs = graphene.List(graphene.String)

class DictEntry(graphene.ObjectType):
    id = graphene.String()
    forms = graphene.List(Form)
    senses = graphene.List(Sense)

def select_from_elastic_response(elastic_raw):
    from_elastic = []
    for e in elastic_raw:
        elastic_result = {}
        elastic_result['id'] = e['_id']
        elastic_result['forms'] = e['_source']['forms']
        elastic_result['senses'] = e['_source']['senses']
        from_elastic.append(elastic_result)
    return from_elastic

def get_from_elastic(dict_id, query, query_type, field):
    query = urllib.parse.unquote(query)
    query_type = urllib.parse.unquote(query_type)
    field = urllib.parse.unquote(field)

    res = ''

    if field == 'form':
        res = client.search(index=dict_id,
                            body={
                                "query": {
                                    "nested": {
                                        "path": "forms",
                                        "query": {
                                            query_type: {
                                                "forms.orth": query
                                            }
                                        }
                                    }
                                }})
    if field == 'sense':
        res = client.search(index=dict_id,
                            body={
                                "query": {
                                    "nested": {
                                        "path": "senses",
                                        "query": {
                                            query_type: {
                                                "senses.definition": query
                                            }
                                        }
                                    }
                                }})

    return res

class DictQuery(graphene.ObjectType):
    entries = graphene.List(DictEntry, dict_id=graphene.String(), query=graphene.String(), query_type=graphene.String(),
                            field=graphene.String())

    def resolve_entries(self, info, query, query_type, field):
        res = get_from_elastic('beo', query=query, query_type=query_type, field=field)
        parsed_results = select_from_elastic_response(res['hits']['hits'])
        return json2obj(json.dumps(parsed_results))


import numpy as np
import torch
import pickle
from ogb.nodeproppred.dataset_pyg import PygNodePropPredDataset
import scipy.sparse as sp
from torch_geometric.utils import to_undirected
from torch_sparse import SparseTensor

def preprocess_features(features):
    """Row-normalize feature matrix and convert to tuple representation"""
    rowsum = np.array(features.sum(1))
    rowsum = (rowsum==0)*1+rowsum
    r_inv = np.power(rowsum, -1).flatten()
    r_inv[np.isinf(r_inv)] = 0.
    r_mat_inv = sp.diags(r_inv)
    features = r_mat_inv.dot(features)
    return features

def sys_normalized_adjacency_i(adj):
   adj = sp.coo_matrix(adj)
   adj = adj + sp.eye(adj.shape[0])
   row_sum = np.array(adj.sum(1))
   row_sum=(row_sum==0)*1+row_sum
   d_inv_sqrt = np.power(row_sum, -0.5).flatten()
   d_inv_sqrt[np.isinf(d_inv_sqrt)] = 0.
   d_mat_inv_sqrt = sp.diags(d_inv_sqrt)
   return d_mat_inv_sqrt.dot(adj).dot(d_mat_inv_sqrt).tocoo()

def sys_normalized_adjacency(adj):
   adj = sp.coo_matrix(adj)
   #adj = adj + sp.eye(adj.shape[0])
   row_sum = np.array(adj.sum(1))
   row_sum=(row_sum==0)*1+row_sum
   d_inv_sqrt = np.power(row_sum, -0.5).flatten()
   d_inv_sqrt[np.isinf(d_inv_sqrt)] = 0.
   d_mat_inv_sqrt = sp.diags(d_inv_sqrt)
   return d_mat_inv_sqrt.dot(adj).dot(d_mat_inv_sqrt).tocoo()

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 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)

#Load dataset
dataset = PygNodePropPredDataset('ogbn-papers100M')
data = dataset[0]
split_idx = dataset.get_idx_split()

#get split indices
train_idx, valid_idx, test_idx = split_idx['train'], split_idx['valid'], split_idx['test']

edge_index = data.edge_index
N = data.num_nodes

#Load edges and create adjacency
row,col = edge_index
adj = SparseTensor(row=row,col=col,sparse_sizes=(N,N))
adj = adj.to_scipy(layout='csr')
print("Getting undirected matrix...")
adj = adj + adj.transpose()
print("Saving unnormalized adjacency matrix")
sp.save_npz('100M_undirected_adj.npz',adj)

#adj = sp.load_npz('100M_undirected_adj.npz')

feat = data.x.numpy()

feat = torch.from_numpy(feat).float()
print("Normalizing matrix A...")
adj_mat = sys_normalized_adjacency(adj)
sp.save_npz('normalized_adj.npz',adj_mat)
adj_mat = sparse_mx_to_torch_sparse_tensor(adj_mat)
print("Normalizing matrix A_i...")
adj_mat_i =  sys_normalized_adjacency_i(adj)
sp.save_npz('normalized_adj_i.npz',adj_mat_i)
adj_mat_i = sparse_mx_to_torch_sparse_tensor(adj_mat_i)

#creating 3-hop features

list_mat_train = []
list_mat_valid = []
list_mat_test = []
#Adding just features X
list_mat_train.append(feat[train_idx,:])
list_mat_valid.append(feat[valid_idx,:])
list_mat_test.append(feat[test_idx,:])

agg_feat = feat
agg_feat_i = feat

#Calculate features for 3 hops
for i in range(4):
    agg_feat = torch.spmm(adj_mat,agg_feat)
    agg_feat_i = torch.spmm(adj_mat_i,agg_feat_i)
    list_mat_train.append(agg_feat[train_idx,:])
    list_mat_valid.append(agg_feat[valid_idx,:])
    list_mat_test.append(agg_feat[test_idx,:])
    list_mat_train.append(agg_feat_i[train_idx,:])
    list_mat_valid.append(agg_feat_i[valid_idx,:])
    list_mat_test.append(agg_feat_i[test_idx,:])

with open('training.pickle',"wb") as fopen:
    pickle.dump(list_mat_train,fopen)

with open('validation.pickle',"wb") as fopen:
    pickle.dump(list_mat_valid,fopen)

with open('test.pickle',"wb") as fopen:
    pickle.dump(list_mat_test,fopen)

#save labels
labels = data.y.data
print(f"Type: {type(labels)},{labels.shape}")

labels_train = labels[train_idx].reshape(-1).long()
labels_valid = labels[valid_idx].reshape(-1).long()
labels_test = labels[test_idx].reshape(-1).long()

with open('labels.pickle',"wb") as fopen:
    pickle.dump([labels_train,labels_valid,labels_test],fopen)


import pygame
import os
import sys
import random as rm

FPS = 50
WIDTH, HEIGHT = 800, 900
clock = pygame.time.Clock()
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
# Создание группы, содержащей границы
vertical_borders = pygame.sprite.Group()

# Обработка изображения

def load_image(name, colorkey=None):
    # локальное имя
    fullname = os.path.join('data', name)
    # если файл не существует, то выходим
    if not os.path.isfile(fullname):
        print(f"Файл с изображением '{fullname}' не найден")
        sys.exit()
    # загрузка изображения
    image = pygame.image.load(fullname)

    if colorkey is not None:
        image = image.convert()
        if colorkey == -1:
            # первый пиксель
            colorkey = image.get_at((0, 0))
        # прозрачность фона
        image.set_colorkey(colorkey)
    else:
        #  сохранение прозрачности
        image = image.convert_alpha()
    # возвращение картинки
    return image

class Meteorite(pygame.sprite.Sprite):
    # подгрузка картинки
    image = load_image("meteorite.png")

    def __init__(self, *group):
        # НЕОБХОДИМО вызвать конструктор родительского класса Sprite.
        # Это очень важно!!!
        super().__init__(*group)
        # получение переменной из класса
        self.image = Meteorite.image
        # получение размеров изображения
        self.rect = self.image.get_rect()
        # изначальное расположение
        self.rect.x = rm.randint(0, 630)
        self.rect.y = -150
        # Скорости
        self.x_speed = rm.randint(-10, 10)
        self.y_speed = rm.randint(1, 10)
        # Скорость поворота и угол
        self.angle = 0
        self.change = rm.randint(-5, 5)

    def update(self):
        # перемещение
        self.rect = self.rect.move(self.x_speed, self.y_speed)
        if pygame.sprite.spritecollideany(self, vertical_borders):
            self.x_speed = -self.x_speed

class Border(pygame.sprite.Sprite):
    # строго вертикальный отрезок
    def __init__(self, x1, y1, x2, y2, group):
        # вертикальная стенка
        super().__init__(group)
        self.image = pygame.Surface([1, y2 - y1])
        self.rect = pygame.Rect(x1, y1, 1, y2 - y1)


# encoding:utf-8

"""二叉树"""

class Node(object):
    """节点类"""
    def __init__(self, item):
        self.item = item
        self.left_child = None
        self.right_child = None

class BinaryTree(object):
    """二叉树"""
    def __init__(self, node=None):
        self.root = node

    def add(self, item):
        """
        广度优先遍历方式添加节点
        :param item:
        :return:
        """
        if self.root is None:
            self.root = Node(item)
        else:
            queue = [self.root]
            while len(queue) > 0:
                node = queue.pop(0)
                if not node.left_child:
                    node.left_child = Node(item)
                    return
                else:
                    queue.append(node.left_child)
                if not node.right_child:
                    node.right_child = Node(item)
                    return
                else:
                    queue.append(node.right_child)

    def breath_travel(self):
        """广度优先遍历"""
        if self.root is None:
            return
        else:
            queue = [self.root]
            while len(queue) > 0:
                node = queue.pop(0)
                print(node.item, end=" ")
                if node.left_child:
                    queue.append(node.left_child)
                if node.right_child:
                    queue.append(node.right_child)

    def preorder_travel(self, root):
        """先序 根 左 右"""
        if root:
            print(root.item, end=" ")
            self.preorder_travel(root.left_child)
            self.preorder_travel(root.right_child)

    def inorder_travel(self, root):
        """中序 左 根 右"""
        if root:
            self.inorder_travel(root.left_child)
            print(root.item, end=" ")
            self.inorder_travel(root.right_child)

    def postorder_travel(self, root):
        """后序 左 右 根"""
        if root:
            self.postorder_travel(root.left_child)
            self.postorder_travel(root.right_child)
            print(root.item, end=" ")

if __name__ == "__main__":
    node = BinaryTree()
    node.add(0)
    node.add(1)
    node.add(2)
    node.add(3)
    node.add(4)
    node.add(5)
    node.add(6)
    node.add(7)
    node.add(8)
    node.add(9)
    node.breath_travel()
    print(" ")
    node.preorder_travel(node.root)
    print(" ")
    node.inorder_travel(node.root)
    print(" ")
    node.postorder_travel(node.root)
    print(" ")


'''

Altere o programa anterior de forma a perguntar também o valor depositado mensalmente. Esse valor será
depositado no início de cada mês, e você deve considerá-lo para o cálculo de juros do mês seguinte.

>>Questão anterior: Escreva um programa que pergunte o depósito inicial e a taxa de juros de uma
poupança. Exiba os valores mês a mês para os 12 primeiros meses. Escreva o total ganho com juros no
período.

'''

taxa_juros = float(input("Informe o valor da taxa de juros: "))
deposito_inicial = float(input("Informe o valor do primeiro deposito: "))

taxa_juros = taxa_juros / 100

total = 0
mensal = 0

for i in range(12):
    mensal = deposito_inicial * taxa_juros
    total += mensal
    deposito_inicial = deposito_inicial + mensal
    print("O saldo do mes", i+1, "eh de: %.2f" %deposito_inicial)
    if i+1 != 12:
        deposito_mensal = float(input("Informe o valor que deseja depositar nesse mes: "))
        deposito_inicial = deposito_inicial + deposito_mensal
print("O total de ganho com os juros foi de: %.2f" %total, "R$")


#!/usr/bin/python3
def pow(a, b):
    """return nth power result"""
    if b == 0:
        return 1
    elif b < 0:
        c = 1 / a
        for x in range((b * -1) - 1):
            c = c * 1 / a

        if 'e' in str(c):
            return "{0:.15e}".format(c)
        return c
    else:
        c = a
        for x in range(b - 1):
            c = c * a

        if 'e' in str(c):
            return "{0:.15e}".format(c)
        return c

    return None


import tkinter as tk
import time

def go_to_first():
    f1.pack()
    f2.pack_forget()
def go_to_second():
    f1.pack_forget()
    f2.pack()
def stoplight():
    f1.pack()
    f2.pack_forget()
    print("hello")
def triangle():
    exit()
def diamond():
    exit()

master = tk.Tk()

#STARTING PAGE
f1 = tk.Frame(master)
l1 = tk.Label(f1, text="")
l1.pack()
b1 = tk.Button(f1, text="Rerack", command=go_to_second)
b1.pack()

#RERACK PAGE
f2 = tk.Frame(master)
l2 = tk.Button(f2, text="Stoplight", command =stoplight )
l2.pack()
l3 = tk.Button(f2, text="Triangle", command = triangle )
l3.pack()
l4 = tk.Button(f2, text="Diamond", command = diamond )
l4.pack()
b2 = tk.Button(f2, text="Return Home", command=go_to_first)
b2.pack()

master.geometry("320x200")
# show first frame
f1.pack()

master.mainloop()


import os
from pathlib import Path

import pandas as pd

from src.dcr_to_petri_readable import Dcr2PetriTransport
from pm4py.objects.dcr.importer import importer as dcr_importer
from pm4py.objects.petri_net.importer import importer as pnml_importer

from concurrent.futures import ThreadPoolExecutor,wait

def run_analysis_on_pnmls(datasets_folder):

    pnml_res = []

    for root, dirs, files in os.walk(datasets_folder):
        for file in files:
            if file.endswith(".dcrxml"):
                pnml_res.append(os.path.join(root, file))

    analysis_results = {}
    for pnml in pnml_res:
        path_without_extension = os.path.splitext(pnml)[0]
        name_with_extension = os.path.basename(pnml)
        name = Path(pnml).stem
        version = name.split('_')[-1]
        # analysis
        tapn = pnml_importer.apply(pnml)
        analysis_results[name] = {}
        analysis_results[name]['version'] = version
        analysis_results[name]['#places'] = len(tapn.places)
        analysis_results[name]['#transitions'] = len(tapn.transitions)
        analysis_results[name]['#arcs'] = len(tapn.arcs)
    df = pd.DataFrame(analysis_results).T
    df.to_csv('models/analysis/optimization_analysis.csv')

def run_dcrxml_files(folder_with_dcr_xmls,override=False):
    dcrxml_res = []

    for root, dirs, files in os.walk(folder_with_dcr_xmls):
        for file in files:
            if file.endswith(".dcrxml"):
                dcrxml_res.append(os.path.join(root, file))
    dcrxml_res2 = []
    for dcrxml in dcrxml_res:
        if dcrxml.count('/')>4:
            dcrxml_res2.append(dcrxml)

    with ThreadPoolExecutor(16) as tpe:
            # futures = [tpe.submit(print, dcrxml) for dcrxml in dcrxml_res]
            futures = [tpe.submit(run_one_dcrxml_all_optimizations_file, dcrxml,override,2*60) for dcrxml in dcrxml_res]
    # with ThreadPoolExecutor(16) as tpe:
    #         # futures = [tpe.submit(print, dcrxml) for dcrxml in dcrxml_res]
    #         futures = [tpe.submit(run_one_dcrxml_all_optimizations_file, dcrxml,override,2*60) for dcrxml in dcrxml_res2]
    #         # for future in futures:
    #             # res = future.result(timeout=10*60)
    #             # print(f'[i] res: {res}')
    # exceptions = ['/home/vco/Datasets/12688511/CoSeLoG WABO 2.dcrxml',
    #               '/home/vco/Datasets/12681647/XES-files/event_log_choice_2_10000.dcrxml',
    #               '/home/vco/Datasets/12681647/XES-files/event_log_sequence_100_10000.dcrxml'
    #               ]
    # for dcrxml in dcrxml_res2:
    #     if dcrxml not in exceptions:
    #         run_one_dcrxml_all_optimizations_file(dcrxml, False, 2*60)

def run_one_dcrxml_all_optimizations_file(input_dcrxml_path, override=False, reachability_timeout=None):
    '''

    :param input_dcrxml_path: full path with extension
    :param reachability_timeout: timeout in seconds to search the reachability graph.
    :return:
    '''
    path_without_extension = os.path.splitext(input_dcrxml_path)[0]
    name_with_extension = os.path.basename(input_dcrxml_path)
    name = Path(input_dcrxml_path).stem

    dcrxml_files = [
        [input_dcrxml_path, f'{path_without_extension}_unoptimized.pnml', False, False, True,'unoptimized'],
        [input_dcrxml_path, f'{path_without_extension}_dcranalysis.pnml', True, False, False,'dcranalysis'],
        [input_dcrxml_path, f'{path_without_extension}_pnreachability.pnml', False, True, False,'pnreachability'],
        [input_dcrxml_path, f'{path_without_extension}_fulloptimization.pnml', True, True, False,'fulloptimization'],
    ]
    for mapping_call in dcrxml_files:
        if os.path.isfile(mapping_call[1]) and not override:
            print(f'[i] File {Path(mapping_call[1]).stem} already exists.')
            pass
        else:
            d2p = Dcr2PetriTransport(preoptimize=mapping_call[2], postoptimize=mapping_call[3],
                                     map_unexecutable_events=mapping_call[4],debug=False)
            d2p.print_steps = True
            d2p.reachability_timeout = 60*10 #10 minutes
            if reachability_timeout:
                d2p.reachability_timeout = reachability_timeout
            print(f'[i] Import {mapping_call[0]}')
            dcr = dcr_importer.apply(mapping_call[0])
            print(f'[i] Converting {mapping_call[0]} as {mapping_call[5]}')
            tapn, m = d2p.dcr2tapn(dcr, tapn_path=mapping_call[1])
            print(f'[i] Done for: {mapping_call[0]}!')

if __name__ == '__main__':
    # run_one_dcrxml_all_optimizations_file('/home/vco/Datasets/Hospital_log.dcrxml')
    # run_one_dcrxml_all_optimizations_file('/home/vco/Datasets/12683249/Road_Traffic_Fine_Management_Process.dcrxml',override=True)
    #run_one_dcrxml_all_optimizations_file('/home/vco/Projects/dcr-to-tapn/models/results/Road_Traffic_Fine_Management_Process.dcrxml', override=True)
    # run_one_dcrxml_all_optimizations_file('/home/vco/Projects/dcr-to-tapn/models/debug/Road_Traffic_Fine_Management_Process_test.dcrxml', override=True)
    # run_dcrxml_files('/home/vco/Datasets/')

    run_dcrxml_files('models/results/',override=True)
    print('[i] Done!')


'''
Name: EECS 210 - Programming Assignment 8 - main.py
Description: This program is a collection of algorithms that solve various graph and game theory problems.

Author: Jacob Wilkus
Date Created: November 14th, 2022

Dependencies: None

Preconditions for Graph():
    - edges: a list of tuples of vertices that are connected by an edge
    - name: a string that is the name of the graph
Postconditions for Graph():
    - self.edges: a list of tuples of vertices that are connected by an edge
    - self.vertices: a list of vertices that are in the graph
    - self.name: a string that is the name of the graph
    - self.circuit: a list of vertices that is the Euler circuit of the graph
Pre- and Postconditions for functions in Graph():
    - has_eulerian_circuit(): returns True if the graph has an Euler circuit, False otherwise
    - find_eulerian_circuit(): finds the Euler circuit of the graph
    - has_hamiltonian_circuit_dirac(): returns True if the graph has a Hamilton circuit according to Dirac's Theorem, False otherwise
    - has_hamiltonian_circuit_ore(): returns True if the graph has a Hamilton circuit according to Ore's Theorem, False otherwise
    - circ_to_str(): returns a string of the vertices in the Euler circuit

Preconditions for Vertex():
    - label: a string that is the label of the vertex
Postconditions for Vertex():
    - self.label: a string that is the label of the vertex
    - self.degree: an integer that is the degree of the vertex
    - self.edges: a list of tuples of vertices that are connected by an edge
'''

#the Graph class
class Graph:
    def __init__(self, edges, name=""): #constructor
        #General graph properties as instance variables
        self.vertices = []
        self.edges = []
        self.circuit = []
        self.name = name

        #Append every instance of a vertex to self.vertices
        for edge in edges:
            self.vertices.append(edge[0])
            self.vertices.append(edge[1])

        #Remove duplicates from self.vertices and sort it.
        self.vertices = list(set(self.vertices))
        self.vertices.sort()

        #Turn every vertex in self.vertices into a Vertex object
        for x in range(0,len(self.vertices)):
            self.vertices[x] = Vertex(self.vertices[x])

        #Append every edge to self.edges
        for edge in edges:
            self.edges.append(Edge(edge[0], edge[1]))

        #For every edge in self.edges, make sure the values are refering to the Vertex objects in self.vertices
        for edge in self.edges: #iterates over every edge in self.edges
            for vertex in self.vertices: #iterates over every vertex in self.vertices
                if edge.pair[0] == vertex.label: #if the first value in the edge is the same as the label of the vertex
                    edge.pair = (vertex, edge.pair[1]) #replace the first value in the edge with the vertex object
                elif edge.pair[1] == vertex.label: #if the second value in the edge is the same as the label of the vertex
                    edge.pair = (edge.pair[0], vertex) #replace the second value in the edge with the vertex object

        #Based on every edge, make sure each respective vertex has the correct degree and neighbors
        for vertex in self.vertices: #iterates over every vertex in self.vertices
            for edge in self.edges: #iterates over every edge in self.edges
                if vertex == edge.pair[0]: #if the vertex is the first value in the edge
                    vertex.neighbors.append(edge.pair[1]) #add the second value in the edge to the vertex's neighbors
                    vertex.degree += 1 #increase the vertex's degree by 1
                elif vertex == edge.pair[1]: #if the vertex is the second value in the edge
                    vertex.neighbors.append(edge.pair[0]) #add the first value in the edge to the vertex's neighbors
                    vertex.degree += 1 #increase the vertex's degree by 1

    #Function for determining if the graph has an Euler circuit
    def has_eulerian_circuit(self):
        for vertex in self.vertices: #iterates over every vertex in self.vertices
            if vertex.degree % 2 != 0: #if the degree of the vertex is not even
                return False #return False
        return True #else, return True

    #Function for finding the Euler circuit of the graph
    def find_eulerian_circuit(self, vertex):
        for vert in self.vertices: #iterates over every vertex in self.vertices
            if vertex == vert: #if the vertex is the same as the vertex in self.vertices
                self.circuit.append(vert) #add the vertex to the Euler circuit
                self.vertices.remove(vert) #remove the vertex from self.vertices
                break #break out of the loop

        for neighbor in vertex.neighbors: #iterates over every neighbor of the vertex
            if neighbor in self.vertices: #if the neighbor is in self.vertices
                self.find_eulerian_circuit(neighbor) #call the function again with the neighbor as the vertex
                break #break out of the loop

    #Function for converting the Euler circuit to a string
    def circ_to_str(self):
        cric_to_str = "" #create an empty string
        for x in range(0,len(self.circuit)): #iterates over every vertex in the Euler circuit
            if x < len(self.circuit) - 1: #if the index is less than the length of the Euler circuit - 1
                cric_to_str += self.circuit[x].label + "-" #add the label of the vertex and a dash to the string
            else:
                cric_to_str += self.circuit[x].label #add the label of the vertex to the string

        return cric_to_str #return the string

    #Function for determining if the graph has a Hamilton circuit according to Dirac's Theorem
    def has_hamiltonian_circuit_dirac(self):
        if len(self.vertices) < 3: #if the number of vertices is less than 3 return False
            return False
        else:
            for vertex in self.vertices: #iterates over every vertex in self.vertices
                if vertex.degree < len(self.vertices)/2: #if the degree of the vertex is less than the number of vertices divided by 2, return False
                    return False
            return True #else, return True

    #Function for determining if the graph has a Hamilton circuit according to Ore's Theorem
    def has_hamiltonian_circuit_ore(self):
        if len(self.vertices) < 3: #if the number of vertices is less than 3 return False
            return False
        else:
            for vertex1 in self.vertices: #iterates over every vertex in self.vertices
                for vertex2 in self.vertices: #iterates over every vertex in self.vertices again
                    if vertex1 != vertex2: #if the two vertices are not the same
                        if not vertex2 in vertex1.neighbors: #if the second vertex is not in the first vertex's neighbors
                            if vertex1.degree + vertex2.degree < len(self.vertices): #if the sum of the degrees of the two vertices is less than the number of vertices, return False
                                return False
            return True #else, return True

#the Vertex class
class Vertex:
    def __init__(self, label):
        #General vertex properties as instance variables
        self.label = label
        self.neighbors = []
        self.degree = 0

    #The list representation of the vertex
    def __repr__(self):
        return self.label

#the Edge class
class Edge:
    def __init__(self, vertex1, vertex2):
        self.pair = (vertex1, vertex2) #the pair of vertices that the edge connects


def romanToInt(self, s: str) -> int:
    roman = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
    result = 0
    pre = ''
    for c in s:
        if pre != '' and roman[pre] < roman[c]:
            result -= (roman[pre] * 2)
        result += roman[c]
        pre = c
    return result


# -*- coding: utf-8 -*-
"""
Created on Sun Feb 23 09:36:24 2020

@author: Richie Bao-caDesign设计(cadesign.cn).Chicago
"""
import rasterio,os,gc,h5py,datetime,scipy
from rasterio.windows import Window
from tqdm import tqdm
import numpy as np
from numba import jit, cuda,njit
import datetime
import numba
from joblib import Memory
import tables
from numba import jit,cuda,njit
from tempfile import mkdtemp
import os.path as path
import scipy.ndimage

#读取栅格，并查看属性值，返回需要的属性
def rasterProperties(rasterFp):
    raster=rasterio.open(rasterFp)
    print("type:",type(raster))
    print("transform:",raster.transform)
    print("[width,height]:", raster.width, raster.height)
    print("number of bands:",raster.count)
    print("bounds:",raster.bounds)
    print("driver:", raster.driver)
    print("no data values:",raster.nodatavals)
    print("_"*50)
    # print("meta:",raster.meta)
    # print("_"*50)
    # print("profile:",raster.profile)
    return raster.width, raster.height

# Yield successive n-sized
# chunks from l.
#递归分组列表数据
def divide_chunks(l,n):
    # looping till length l
    for i in range(0, len(l), n):
        yield l[i:i + n]
#建立用于rasterio库分批读取一个较大Raster数据的windows列表（如果内存溢出，而要处理较大的单独raster数据时）
#关于rasterio的window数据格式可以查看其官方网站
def rasterio_windows(totalWidth,totalHeight,subWidth,subHeight):
    w_n=list(divide_chunks(list(range(totalWidth)), subWidth))
    h_n=list(divide_chunks(list(range(totalHeight)), subHeight))
    wins=[Window(w[0],h[0],len(w),len(h)) for h in h_n for w in w_n]
    # print(wins)
    print("raster windows amount:",len(wins))
    return wins

# @njit(parallel=True)
# @cuda.jit(debug=True)
def ArrayCoordi(rasterArray):
    relativeCellCoords=np.indices(rasterArray.shape)
    relativeCellCoords2D=np.stack(relativeCellCoords,axis=2).reshape(-1,2)
    del relativeCellCoords
    # print(relativeCellCoords2D_O)
    return relativeCellCoords2D

#计算首尾坐标，用到三角函数
# @profile #内存监测所标识的函数
# @cuda.jit(debug=True)
# @njit(parallel=True)
#计算首尾坐标，用到三角函数
# @profile #内存监测所标识的函数
def equalCircleDivide(originalCoordiArray,radious,lineProfileAmount):
    # print(originalCoordiArray.shape)
    angle_s=360/lineProfileAmount
    angle_array=np.array([i*angle_s for i in range(lineProfileAmount)],dtype=np.float32)
    #.astype(np.float16)
    opposite=np.sin(np.radians(angle_array),dtype=np.float16)*radious
    opposite=opposite.astype(np.float32)
    # print(opposite.dtype)
    yCoordi=np.add(opposite,originalCoordiArray[:,1].reshape(-1,1),dtype=np.float32)
    del opposite
    # print(yCoordi.dtype)

    adjacent=np.cos(np.radians(angle_array),dtype=np.float16)*radious
    xCoordi=np.add(adjacent,originalCoordiArray[:,0].reshape(-1,1),dtype=np.float32)
    del adjacent,angle_array
    # print(xCoordi.dtype)

    CoordiArray=np.stack((xCoordi,yCoordi),axis=-1)
    # print(CoordiArray.dtype)
    # del xCoordi,yCoordi
    return CoordiArray

#计算障碍角度和高度,以及SVF值。参考文献：城区复杂下垫面天空视域因子参数化方法——以北京鸟巢周边地区为例
# @profile #内存监测所标识的函数
# @cuda.jit(debug=True)
# @njit(parallel=True)
def SVF(radious,equalDistance,ziList,j):
    segment=radious/equalDistance
    distanceList=np.array([i*segment for i in range(equalDistance+1)],dtype=np.float32)
    distanceList=distanceList[1:]

    ziListSub=ziList[:,:,1:]
    ziListOrigin=ziList[:,:,0]

    sinValues=np.true_divide(np.subtract(ziListSub,np.expand_dims(ziListOrigin, axis=2)),np.sqrt(np.add(np.power(distanceList,2),np.power(np.subtract(ziListSub,np.expand_dims(ziListOrigin, axis=2)),2))))

    sinMaxValue=np.amax(sinValues,axis=2)
    del sinValues
    SVFValue=1-np.true_divide(np.sum(sinMaxValue, axis=1),sinMaxValue.shape[-1])

    # SVFValueFn=os.path.join(saveFp,"SVFValue_%d"%(j))
    # np.save(SVFValueFn, SVFValue)
    # del SVFValue
    # print("SVF Value saved:%d"%i)
    # with open(os.path.join(saveFp,"SVFValue_filenames.txt"), "a") as text_file:
    #     text_file.write("%s\n"%SVFValueFn)

    return SVFValue.astype(np.float32)

#数组延直线截面提取单元值
# @profile #内存监测所标识的函数
# @cuda.jit(debug=True)
# @njit(parallel=True)
def lineProfile(zValue,originalPoint,endPoint):
    num=equalDistance+1

    x0=originalPoint[:,0].reshape(-1,1)
    x1=endPoint[:,:,0]
    # print(x0.dtype)
    # print(x1.dtype)
    x=np.linspace(x0, x1, num,dtype=np.int) #可以不用修改数组类型。出于内存优化考虑,会加快后续np.stack计算速度
    del x0,x1
    # fp[:]=np.linspace(x0, x1, num,dtype=np.int)[:]

    y0=originalPoint[:,1].reshape(-1,1)
    y1=endPoint[:,:,1]
    y=np.linspace(y0, y1, num,dtype=np.int)
    del y0,y1

    xStack=np.stack(x,axis=-1)
    # xStackSplit=np.array_split(xStack,saveN) #为减缓单次数组计算量，切分数组为saveN个单个数组，切分量越大，单个数组越小，计算所占用内存越小
    # del xStack #清空该变量，释放内存.关于numpy array占据内存的大小，查找确认
    # print("xStack finished!")

    yStack=np.stack(y,axis=-1)
    # yStackSplit=np.array_split(yStack,saveN)
    # del yStack
    del x,y

    zi = scipy.ndimage.map_coordinates(zValue,[xStack,yStack],cval=0,mode="nearest",order=0) #根据数组索引值，提取实际值
    del xStack,yStack

    # #记录每次存储的数据路径为.txt文件，最后通过该文件读取所有数据，组合与写入raster格式文件
    # with open(os.path.join(saveFp,"SVFValue_filenames.txt"), "a") as text_file:
    #     text_file.write("%s\n"%SVFValueFn)
    return zi

#read raster blocks 分批读取较大栅格数据，并计算
def SVF_Wins(rasterFp,dataSave_fp, windowsList):
    i=0
    for win in tqdm(windowsList):
        with rasterio.open(rasterFp,"r+") as src:
            src.nodata=-1
            w = src.read(1, window=win)
            # print("_"*50)
            # print(w.shape)
            profile=src.profile
            win_transform=src.window_transform(win)
        # print("_"*50)
        # print(w.shape)
        # print(ok)
        '''计算部分'''
        # coordiArray=equalCircleDivide(T,radious,lineProfileAmount)
        relativeCellCoords2D=ArrayCoordi(w)
        # print(relativeCellCoords2D)
        # print("+"*50)
        a_T = datetime.datetime.now()
        coordiArray=equalCircleDivide(relativeCellCoords2D,radious,lineProfileAmount)
        b_T= datetime.datetime.now()
        print("qualCircleDivide time span:", b_T-a_T)
        # print(coordiArray)
        gc.collect()

        # print(coordiArray.shape)
        # print(relativeCellCoords2D.shape)
        c_T=datetime.datetime.now()
        zi=lineProfile(w,relativeCellCoords2D,coordiArray)
        d_T=datetime.datetime.now()
        print("lineProfile time span:",d_T-c_T)
        gc.collect()
        del coordiArray

        e_T=datetime.datetime.now()
        SVFValue=SVF(radious,equalDistance,zi,i)
        f_T=datetime.datetime.now()
        print("SVF time span:",d_T-c_T)
        # print(SVFValue.shape)
        gc.collect()
        del zi

        profile.update(
            width=win.width,
            height=win.height,
            count=1,
            transform=win_transform,
            compress='lzw',
            dtype=rasterio.float32
            )
        # with rasterio.open(os.path.join(saveRasterByBlock_fp,"testingBlock.tif"), 'w', driver='GTiff' width=512, height=256, count=1,dtype=w.dtype,**profile) as dst:

        with rasterio.open(os.path.join(saveFp,"SVF3_%d.tif"%i), 'w', **profile) as dst:
            dst.write(SVFValue.reshape(w.shape), window=Window(0,0,win.width,win.height), indexes=1)

        del SVFValue

        g_T=datetime.datetime.now()
        print("total time span:",g_T-a_T)

        i+=1
        #在正式计算前，通过break，仅对部分数据编写与调整代码
        # if i ==1:
        #     break

if __name__=="__main__":
    tables.file._open_files.close_all() #关闭文件。该程序可忽略
    gc.collect() #释放缓存，IPython console 命令：%reset -f
    # rasterFp=r"D:\data\lidar\pdal_data\d.tif" #待计算SVF的栅格
    # rasterFp=r"D:\data\data_01_Chicago\pdal_data\chicago_loop_tile_0_0.tif"
    # rasterFp=r"F:\data_02_Chicago\parkNetwork\height_DSM-DTMInter.tif"
    rasterFp=r"F:\data_02_Chicago\ArcGisPro\parkNetwork\height_DSMDTMInter_3_a.tif"
    saveFp=r"F:\data_02_Chicago\parkNetwork\SVF"
    rasterFn=r"F:\data_02_Chicago\parkNetwork\SVF"

    # mem_filename = path.join(saveFp, 'newfile.dat')
    # if os.path.exists(mem_filename):
    #     os.remove(mem_filename)
    # else:
    #     print("Can not delete the file as it doesn't exists,built new one!")
    # fp = np.memmap(mem_filename, dtype='float16', mode='w+', shape=(51, 25000000, 36))
    # print(fp.filename == path.abspath(mem_filename))

    totalWidth,totalHeight=rasterProperties(rasterFp)
    #根据不同的栅格大小，自行调整subWidth和subHeight，满足内存要求
    subWidth=3000
    subHeight=3000
    rasterio_wins=rasterio_windows(totalWidth,totalHeight,subWidth,subHeight)
    # print(ok)

    # hdf5Fn=os.path.join(saveFp,"cacheSVF.hdf5")
    # if os.path.exists(hdf5Fn):
    #     os.remove(hdf5Fn)
    # else:
    #     print("Can not delete the file as it doesn't exists,built new one!")
    # f=h5py.File(hdf5Fn, "a")

    #参数配置
    rasterResolution=3 #计算栅格的分辨率
    radious=100*rasterResolution #扫描半径
    lineProfileAmount=8#扫描截面数量36
    equalDistance=30 #每条扫描线的等分数量  50
    # saveN=12 #配置每块计算时，numpy数组一次性计算量，数值越大，单次数组计算量越小，单次计算占用内存越小。numpy 数组大小在1，000，000量时，内存16G，测试达到最大，如果超过该量值，则需要增加该参数值，即降低单次数组的大小。

    SVF=SVF_Wins(rasterFp, saveFp,rasterio_wins[:100])


import os

from django.core.management.base import BaseCommand

from couchdbkit.exceptions import ResourceNotFound

from dimagi.utils.couch.database import get_db

# possible expansion: allow this to accept doc ids on the command line
# for use like `cat doc_ids.txt | ./manage.py get_doc_domains `xargs echo`
class Command(BaseCommand):
    help = "Takes a file with one doc id per line and outputs their domains"

    def add_arguments(self, parser):
        parser.add_argument(
            '--full',
            action='store_true',
            dest='full',
            default=False,
            help="Output a full list of doc ids, followed by their domain",
        )

    def handle(self, filename, **options):
        self.full = options.get('full')
        if not os.path.exists(filename):
            return "File %s not found" % filename
        with open(filename) as file:
            doc_ids = file.readlines()
        self.domains = set()
        self.db = get_db()
        for id in doc_ids:
            self.handle_doc(id.strip())

    def handle_doc(self, id):
        try:
            doc = self.db.get(id)
        except ResourceNotFound:
            doc = {}
        domain = doc.get('domain', None)
        if self.full:
            doc_type = doc.get('doc_type', None)
            print("{0},{1},{2}".format(id, domain, doc_type))
        elif domain and domain not in self.domains:
            self.domains.add(domain)
            print(domain)


from ast import literal_eval
from base64 import b64decode
from logging import getLogger
from time import time
from typing import Union, Optional
from .models import UserProfile
from .exceptions import MojangError
from utils.http import session
# THIS IS A MODIFIED VERSION OF summer's wrapper
# This one is async
from ast import literal_eval
from base64 import b64decode
from logging import getLogger
from time import time
from typing import Union, Optional

from utils.http import session
from .exceptions import MojangError
from .models import UserProfile

log = getLogger(__name__)

class MojangAPI:
    # NOTE: Names are held for exactly 37 days after being released.
    # Update this value (by converting days to seconds) if the duration is ever changed.
    _NAME_HOLD_DURATION = 3196800000

    @classmethod
    async def get_uuid(cls, username: str, timestamp: Optional[int] = None) -> Union[str, None]:
        """Convert a Minecraft name to a UUID.

        Args:
            username:  The Minecraft username to be converted.
            timestamp (optional): Get the username's UUID at a specified UNIX timestamp.
                You can also get the username's first UUID by passing 0.
                However, this only works if the name was changed at least once, or if the account is legacy.

        Returns:
            str: The UUID. Otherwise, None if the username does not exist.
        """

        if timestamp is None:
            timestamp_now = int(time() * 1000.0)
            timestamp = int((timestamp_now - cls._NAME_HOLD_DURATION) / 1000)

        resp = await session.get(f"https://api.mojang.com/users/profiles/minecraft/{username}?at={timestamp}")
        if resp.ok:
            try:
                json = await resp.json()
                return json["id"]
            except Exception:
                return None
        return None

    @staticmethod
    async def get_uuids(names: list) -> dict:
        """Convert up to 10 usernames to UUIDs in a single network request.

        Args:
            names: The Minecraft username(s) to be converted.
                If more than 10 are included, only the first 10 will be parsed.

        Returns:
            dict: username:uuid pairs of the converted usernames. Names are also case-corrected.
                If a username does not exist, it will not be included in the returned dictionary.
        """
        if len(names) > 10:
            names = names[:10]
        async with session.post("https://api.mojang.com/profiles/minecraft", data=names) as ses:
            data = await ses.json()

        if not isinstance(data, list):
            if data.get("error"):
                raise ValueError(data["errorMessage"])
            else:
                raise MojangError(data)

        sorted_names = dict()
        for name_data in data:
            sorted_names[name_data["name"]] = name_data["id"]

        return sorted_names

    @staticmethod
    async def get_username(uuid: str) -> Union[str, None]:
        """Convert a UUID to a username.

        Args:
            uuid: The Minecraft UUID to be converted to a username.

        Returns:
            str: UUID if username exists. None otherwise.
        """
        resp = await session.get(f"https://sessionserver.mojang.com/session/minecraft/profile/{uuid}")
        if resp.ok:
            json = await resp.json()
            return json["name"]
        return None

    @classmethod
    async def get_drop_timestamp(cls, username: str) -> Union[int, None]:
        """Get the timestamp of when a username drops

        Args:
            username: Minecraft name to get drop date of

        Returns:
            int: The drop timestamp. Otherwise, None if the username is not being released/dropped.
        """
        uuid = cls.get_uuid(username)
        if not uuid:
            raise ValueError("Username is invalid. Failed to convert username to UUID")
        resp = await session.get(f"https://api.mojang.com/user/profiles/{uuid}/names")
        name_changes = [name_change for name_change in reversed(await resp.json())]
        for i, name_info in enumerate(name_changes):
            if name_info["name"].lower() == username.lower():
                try:
                    name_changed_timestamp = name_changes[i - 1]["changedToAt"]
                    drop_timestamp = (name_changed_timestamp + cls._NAME_HOLD_DURATION) / 1000
                    return int(drop_timestamp)
                except KeyError:
                    return None

    @staticmethod
    async def get_profile(uuid: str) -> Union[UserProfile, None]:
        """Returns a `UserProfile` object

        `UserProfile` Attributes:
            id (str): UUID of the profile
            name (str): Name of the profile
            cape_url (str or None): URL to the profile's cape
            skin_url (str or None): URL to the profile's skin
            skin_model (str): Skin model of the profile
            is_legacy_profile (bool): Check if the profile is legacy
            timestamp (int): Timestamp of when the profile was retrieved
        """
        resp = await session.get(f"https://sessionserver.mojang.com/session/minecraft/profile/{uuid}")
        try:
            js = await resp.json()
            value = js["properties"][0]["value"]
        except KeyError:
            return None
        user_profile = literal_eval(b64decode(value).decode())
        return UserProfile(user_profile)
    @staticmethod
    async def get_name_history(uuid: str) -> list:
        """Get a user's name history

        Args:
            uuid: The user's UUID.

        Returns:
            list: A list of dictionaries, each of which contains a name:changed_to_at pair.
                If changed_to_at is set to 0, it is because it is the profile's first name.
        """
        ses = await session.get(f"https://api.mojang.com/user/profiles/{uuid}/names")
        name_history = await ses.json()

        name_data = list()
        for data in name_history:
            name_data_dict = dict()
            name_data_dict["name"] = data["name"]
            if data.get("changedToAt"):
                name_data_dict["changed_to_at"] = data["changedToAt"]
            else:
                name_data_dict["changed_to_at"] = 0
            name_data.append(name_data_dict)
        return name_data

    @staticmethod
    async def get_api_status() -> dict:
        """Get the API / network status of various Mojang services

        Returns:
            dict: Returns dictionary with status of various Mojang services.
                Possible values are green (no issues), yellow (some issues), red (service unavailable).
        """
        re = await session.get("https://status.mojang.com/check")
        data = await re.json()

        servers = dict()
        for server_data in data:
            for k, v in server_data.items():
                servers[k] = v
        return servers

    @staticmethod
    async def get_blocked_servers() -> list:
        """Returns a list of SHA1 hashes of current blacklisted servers that do not follow EULA.
        These servers have to abide by the EULA or be shut down forever. The hashes are not cracked.
        """
        return await session.get("https://sessionserver.mojang.com/blockedservers").text.splitlines()

    @staticmethod
    async def get_sale_statistics(item_sold_minecraft: bool = True,
                            prepaid_card_redeemed_minecraft: bool = True,
                            item_sold_cobalt: bool = False,
                            item_sold_scrolls: bool = False,
                            prepaid_card_redeemed_cobalt: bool = False,
                            item_sold_dungeons: bool = False
                            ):
        """Get statistics on the sales of Minecraft.
        You will receive a single object corresponding to the sum of sales of the requested type(s)
        At least one type of sale must be set to True.

        Returns:
            dict: the sales metrics. Possible keys include `total`, `last24h` and `sale_velocity_per_seconds`
        """
        options = [k for k, v in locals().items() if v]

        if not options:
            raise MojangError("Invalid parameters supplied. Include at least one metric key.")

        sepo = await session.post("https://api.mojang.com/orders/statistics", data={"metricKeys": options})
        data = await sepo.json()
        metrics = dict()
        metrics["total"] = data["total"]
        metrics["last24h"] = data["last24h"]
        metrics["sale_velocity_per_seconds"] = data["saleVelocityPerSeconds"]
        return metrics


import typing as T

import numpy as np

import megengine as mge
import megengine.functional as F
from megengine import Parameter

from ..logger import get_logger
from .init import ones_, zeros_
from .module import Module

class GroupNorm(Module):
    r"""Applies Group Normalization over a mini-batch of inputs
    Refer to `Group Normalization <https://arxiv.org/abs/1803.08494>`__

    .. math::
            y = \frac{x - \mathrm{E}[x]}{ \sqrt{\mathrm{Var}[x] + \epsilon}} * \gamma + \beta

    The mean and standard-deviation are calculated separately over the each group.
    :math:`\\gamma` and :math:`\\beta` are learnable affine transform parameters of
    attr:`num_channels` if :attr:`affine` is ``True``.

    Args:
        num_groups (int): number of groups that divided from channels.
        num_channels (int): number of channels expected in input
        eps: a value added to the denominator for numerical stability. Default: 1e-5
        affine: this module has learnable affine parameters (weight, bias) when affine is set to be True.

    Shape:
        - Input: :math:`(N, C, H, W)` (now only support NCHW format tensor)
        - Output: :math:`(N, C, H, W)` (same shape as input)

    Examples:
        >>> import numpy as np
        >>> inp = Tensor(np.arange(2 * 3 * 4 * 4).astype(np.float32).reshape(2, 3, 4, 4))
        >>> m = M.GroupNorm(3, 3)
        >>> out = m(inp)
        >>> out.numpy().shape
        (2, 3, 4, 4)
    """

    def __init__(self, num_groups, num_channels, eps=1e-5, affine=True, **kwargs):
        super().__init__(**kwargs)
        assert num_channels % num_groups == 0
        self.num_groups = num_groups
        self.num_channels = num_channels
        self.eps = eps
        self.affine = affine
        if self.affine:
            self.weight = Parameter(np.ones(num_channels, dtype=np.float32))
            self.bias = Parameter(np.zeros(num_channels, dtype=np.float32))
        else:
            self.weight = None
            self.bias = None
        self.reset_parameters()

    def reset_parameters(self):
        if self.affine:
            ones_(self.weight)
            zeros_(self.bias)

    def forward(self, x):
        x = F.nn.group_norm(
            x, self.num_groups, self.affine, self.weight, self.bias, self.eps
        )
        return x

    def _module_info_string(self) -> str:
        s = (
            "groups={num_groups}, channels={num_channels}, "
            "eps={eps}, affine={affine}"
        )
        return s.format(**self.__dict__)

class InstanceNorm(Module):
    r"""Applies Instance Normalization over a mini-batch of inputs
    Refer to `Instance Normalization <https://arxiv.org/abs/1607.08022>`__

    .. math::
            y = \frac{x - \mathrm{E}[x]}{ \sqrt{\mathrm{Var}[x] + \epsilon}} * \gamma + \beta

    The mean and standard-deviation are calculated per-dimension separately for each object in a mini-batch.
    :math:`\\gamma` and :math:`\\beta` are learnable affine transform parameters of
    attr:`num_channels` if :attr:`affine` is ``True``.
    Note that InstanceNorm equals using GroupNorm with num_groups = num_channels.

    Args:
        num_channels (int): number of channels expected in input
        eps: a value added to the denominator for numerical stability. Default: 1e-5
        affine: this module has learnable affine parameters (weight, bias) when affine is set to be True.

    Shape:
        - Input: :math:`(N, C, H, W)` (now only support NCHW format tensor)
        - Output: :math:`(N, C, H, W)` (same shape as input)

    Examples:
        >>> import numpy as np
        >>> inp = Tensor(np.arange(2 * 3 * 4 * 4).astype(np.float32).reshape(2, 3, 4, 4))
        >>> m = M.InstanceNorm(3)
        >>> out = m(inp)
        >>> out.numpy().shape
        (2, 3, 4, 4)
    """

    def __init__(self, num_channels, eps=1e-05, affine=True, **kwargs):
        super().__init__(**kwargs)
        self.num_channels = num_channels
        self.eps = eps
        self.affine = affine
        if self.affine:
            self.weight = Parameter(np.ones(num_channels, dtype="float32"))
            self.bias = Parameter(np.zeros(num_channels, dtype="float32"))
        else:
            self.weight = None
            self.bias = None
        self.reset_parameters()

    def reset_parameters(self):
        if self.affine:
            ones_(self.weight)
            zeros_(self.bias)

    def forward(self, x):
        x = F.nn.instance_norm(x, self.affine, self.weight, self.bias, self.eps)
        return x

    def _module_info_string(self) -> str:
        s = "channels={num_channels}, eps={eps}, affine={affine}"
        return s.format(**self.__dict__)

class LayerNorm(Module):
    r"""Applies Layer Normalization over a mini-batch of inputs
    Refer to `Layer Normalization <https://arxiv.org/pdf/1607.06450v1.pdf>`_

    .. math::
            y = \frac{x - \mathrm{E}[x]}{ \sqrt{\mathrm{Var}[x] + \epsilon}} * \gamma + \beta

    The mean and standard-deviation are calculated separately over the last
    certain number dimensions which have to be of the shape specified by
    :attr:`normalized_shape`.
    :math:`\\gamma` and :math:`\\beta` are learnable affine transform parameters of
    :attr:`normalized_shape` if :attr:`affine` is ``True``.
    The standard-deviation is calculated via the biased estimator.

    .. note::

        Unlike Batch Normalization and Instance Normalization, which applies
        scalar scale and bias for each entire channel/plane,
        Layer Normalization applies per-element scale and bias.

    Args:
        normalized_shape(int or tuple): input shape from an expected input of size
            size :math:`[*, normalized\_shape[0], normalized\_shape[1], ..., normalized\_shape[-1]]`.
            If it is a single integer, this module will normalize over the last dimension
            which is expected to be of that specific size.
        eps: a value added to the denominator for numerical stability. Default: 1e-5
        affine: this module has learnable affine parameters (weight, bias) when affine is set to be True.

    Shape:
        - Input: :math:`(N, *)` (2-D, 3-D, 4-D or 5-D tensor)
        - Output: :math:`(N, *)` (same shape as input)

    Examples:
        >>> import numpy as np
        >>> inp = Tensor(np.arange(2 * 3 * 4 * 4).astype(np.float32).reshape(2, 3, 4, 4))
        >>> m = M.LayerNorm((4, 4))
        >>> out = m(inp)
        >>> out.numpy().shape
        (2, 3, 4, 4)
    """

    def __init__(self, normalized_shape, eps=1e-05, affine=True, **kwargs):
        super().__init__(**kwargs)
        if isinstance(normalized_shape, int):
            normalized_shape = (normalized_shape,)
        self.normalized_shape = tuple(normalized_shape)
        self.eps = eps
        self.affine = affine
        if self.affine:
            self.weight = Parameter(np.ones(self.normalized_shape, dtype="float32"))
            self.bias = Parameter(np.zeros(self.normalized_shape, dtype="float32"))
        else:
            self.weight = None
            self.bias = None

        self.reset_parameters()

    def reset_parameters(self):
        if self.affine:
            ones_(self.weight)
            zeros_(self.bias)

    def forward(self, x):
        x = F.nn.layer_norm(
            x, self.normalized_shape, self.affine, self.weight, self.bias, self.eps
        )
        return x

    def _module_info_string(self) -> str:
        s = "normalized_shape={normalized_shape}, eps={eps}, affine={affine}"
        return s.format(**self.__dict__)

class GeneralNorm(Module):
    r"""Applies General Normalization over a mini-batch of inputs

    .. math::
            y = \frac{x - \mathrm{E}[x]}{ \sqrt{\mathrm{Var}[x] + \epsilon}} * \gamma + \beta

    The mean and standard-deviation are calculated separately according to the axis
    given by :attr:`normalized_axis`.
    :math:`\\gamma` and :math:`\\beta` are learnable affine transform parameters
    if :attr:`affine` is ``True``.
    The standard-deviation is calculated via the biased estimator.

    Args:
        normalized_shape(int, list or tuple): the shape of input needs to be normalized, normalized_shape must be specified when affine is true. When affine=true, we will directly use this shape to initialize weight/bias. Please ensure that the order is correct. Default: None
        normalized_axis(int, list or tuple): the axis of input needs to be normalized, one-to-one correspondence between normalized_axis and normalized_shape. Default: -1
        eps: a value added to the denominator for numerical stability. Default: 1e-5
        affine: this module has learnable affine parameters (weight, bias) when affine is set to be True.

    Shape:
        - Input: :math:`(N, *)` (2-D, 3-D, 4-D or 5-D tensor)
        - Output: :math:`(N, *)` (same shape as input)

    Examples:
        >>> import numpy as np
        >>> inp = Tensor(np.arange(2 * 3 * 4 * 4).astype(np.float32).reshape(2, 3, 4, 4))
        >>> m = M.GeneralNorm((2, 3), (0, 1))
        >>> out = m(inp)
        >>> out.numpy().shape
        (2, 3, 4, 4)
        >>> m = M.GeneralNorm((3, 4), (1, -2)) # Please be careful.
        >>> out = m(inp)
        >>> out.numpy().shape
        (2, 3, 4, 4)
        >>> m = M.GeneralNorm((2, 4, 3), (0, 2, 1)) # Incorrect initialization, the order of normalized_axis is incorrect, should be adjusted to m = M.GeneralNorm((2, 3, 4), (0, 1, 2)).
        >>> m = M.GeneralNorm((2, 4, 3), (0, -2, 1)) # Incorrect initialization, the order of normalized_axis is incorrect, should be adjusted to m = M.GeneralNorm((2, 3, 4), (0, 1, -2)).
        >>> m = M.GeneralNorm((3, 4), (3, -1)) # Incorrect initialization, because axis=-1 and axis=3 are the same axis, namely axis=3.
    """

    def __init__(
        self, normalized_shape=None, normalized_axis=0, eps=1e-05, affine=True, **kwargs
    ):
        super().__init__(**kwargs)

        self.eps = eps
        self.affine = affine

        if self.affine:
            assert (
                normalized_shape is not None
            ), "normalized_shape must be specified when affine is true"
            assert (
                normalized_axis is not None
            ), "normalized_axis must be specified when affine is true"
            if not isinstance(normalized_axis, T.Sequence):
                normalized_axis = [normalized_axis]
            if not isinstance(normalized_shape, T.Sequence):
                normalized_axis = [normalized_shape]
            assert isinstance(normalized_axis, (list, tuple))
            assert isinstance(normalized_shape, (list, tuple))

            assert len(normalized_axis) == len(
                normalized_shape
            ), "The size of normalized_axis and normalized_shape are different"
            assert len(set(normalized_axis)) == len(
                normalized_axis
            ), "there are duplicate axis in list normalized_axis"

            self.weight = Parameter(np.ones(normalized_shape, dtype="float32"))
            self.bias = Parameter(np.zeros(normalized_shape, dtype="float32"))
        else:
            self.weight = None
            self.bias = None

        self.normalized_shape = normalized_shape
        self.normalized_axis = normalized_axis
        self.reset_parameters()

    def reset_parameters(self):
        if self.affine:
            ones_(self.weight)
            zeros_(self.bias)

    def forward(self, x):
        self.normalized_axis = [
            num + x.ndim if num < 0 else num for num in self.normalized_axis
        ]
        assert self.normalized_axis == sorted(
            self.normalized_axis
        ), "The order of normalized_axis is incorrect, should be {}, but got {}. Please specify the values of axis in the correct order in normalized_axis".format(
            sorted(self.normalized_axis), self.normalized_axis
        )
        inp_shape = x.shape
        for i in range(len(self.normalized_axis)):
            assert (
                inp_shape[self.normalized_axis[i]] == self.normalized_shape[i]
            ), "inp.shape={}, normalized_axis={}, normalized_shape={}, inp.shape[normalized_axis[{}]]({}) != normalized_shape[{}]({})".format(
                x.shape,
                self.normalized_axis,
                self.normalized_shape,
                i,
                inp_shape[self.normalized_axis[i]],
                i,
                self.normalized_shape[i],
            )

        x = F.nn.general_norm(
            x, self.normalized_axis, self.affine, self.weight, self.bias, self.eps
        )
        return x

    def _module_info_string(self) -> str:
        s = "normalized_shape={normalized_shape}, normalized_axis={normalized_axis}, eps={eps}, affine={affine}"
        return s.format(**self.__dict__)


from shapely.geometry import Polygon

from tests import csv_point_input_location, union_polygon_input_location
from tests.test_base import TestBase

class TestConstructors(TestBase):

    def test_st_envelope_aggr(self):
        point_csv_df = self.spark.read.format("csv").\
            option("delimiter", ",").\
            option("header", "false").\
            load(csv_point_input_location)

        point_csv_df.createOrReplaceTempView("pointtable")
        point_df = self.spark.sql("select ST_Point(cast(pointtable._c0 as Decimal(24,20)), cast(pointtable._c1 as Decimal(24,20))) as arealandmark from pointtable")
        point_df.createOrReplaceTempView("pointdf")
        boundary = self.spark.sql("select ST_Envelope_Aggr(pointdf.arealandmark) from pointdf")

        coordinates = [
            (1.1, 101.1),
            (1.1, 1100.1),
            (1000.1, 1100.1),
            (1000.1, 101.1),
            (1.1, 101.1)
        ]

        polygon = Polygon(coordinates)

        assert boundary.take(1)[0][0] == polygon

    def test_st_union_aggr(self):
        polygon_csv_df = self.spark.read.format("csv").\
            option("delimiter", ",").\
            option("header", "false").\
            load(union_polygon_input_location)

        polygon_csv_df.createOrReplaceTempView("polygontable")
        polygon_csv_df.show()
        polygon_df = self.spark.sql("select ST_PolygonFromEnvelope(cast(polygontable._c0 as Decimal(24,20)),cast(polygontable._c1 as Decimal(24,20)), cast(polygontable._c2 as Decimal(24,20)), cast(polygontable._c3 as Decimal(24,20))) as polygonshape from polygontable")
        polygon_df.createOrReplaceTempView("polygondf")
        polygon_df.show()
        union = self.spark.sql("select ST_Union_Aggr(polygondf.polygonshape) from polygondf")

        assert union.take(1)[0][0].area == 10100


# Bu uygulamada argparse kütüphanesinin kullanımını gösteriyoruz
# programa gelen argümanları daha iyi kontrol etmek için kullanılıyor.

import argparse

#parser nesnesi oluşturuluyor
parser = argparse.ArgumentParser()

#parser nesnesine kullanıcıdan alınacak bir argüman tanıtılıyor
#ilk parametre argümanın alacağı değişken ismi
#ikinci parametre argümanın yanında çıkacak olan yardım mesajı

parser.add_argument("ilk_arguman",help="ilk arguman yardım");

#argümanlar yakalanıyor
args = parser.parse_args()

#ilk argümanın değeri ekrana çıkartılıyor
print(args.ilk_arguman)


from urllib.request import Request, urlopen
from bs4 import BeautifulSoup as soup
import re
import random as r

Foods = []	# This array will store all our Food objects

# This is our Food class, we will use this to store all the required data from
# a recipe as its own object.
class Food:
	def __init__(self, name, calorie, summary, img_url, bluePoint, greenPoint, purplePoint, recipeKeys):

		self.name = name
		self.calorie = calorie
		self.summary = summary
		self.img_url = img_url
		self.bluePoint = bluePoint
		self.greenPoint = greenPoint
		self.purplePoint = purplePoint
		self.recipeKeys = recipeKeys

def slice_summary(summary):	#slice_summary is used to slice the summaries into
	whitespaceCount = 0		# a more readable form with multiple lines.
	i = 0
	for char in summary:

		if(char == " "):
			whitespaceCount = whitespaceCount + 1
		if(whitespaceCount == 7):
			summary = summary[:i] + "\n" + summary[i:]
			whitespaceCount = 0
			i = i + 1

		i = i + 1

	return summary

def parseData(url):
	client = urlopen(url)
	html = client.read()
	client.close
	page_soup = soup(html, "html.parser")

	posts = []
	# Getting all posts from site
	posts.extend(page_soup.findAll("article",{"class":"post teaser-post even"}))
	posts.extend(page_soup.findAll("article",{"class":"post teaser-post odd"}))

	# Creating a Food object out of every post
	for post in posts:
		# Getting the name of the recipe
		name = post.find("h2",{"class":"title"}).get_text()

		# Getting the calorie amount for the recipe, if we fail then that means
		# that the post in question is not a recipe, so we just skip it
		# and move on. This way we get rid of posts like
		# "7 DAY HEALTHY MEAL PLAN (NOV 16-22)" that are not recipes
		try:
			calorie = float(post.find("span",{"class":"icon-star"}).get_text())
			calorie = int(round(calorie))
		except(AttributeError):
			continue

		# Getting the summary for the recipe
		summary = post.find("p",{"class":"excerpt"}).get_text()
		summary = slice_summary(summary)

		# Getting the image for the recipe
		# Notice how we only get the url for later use
		# and wont download the image right away.
		image = post.find("img")
		img_url = (image["src"])

		# Getting the blue, green and purple point values, if there are none
		# assign -1.
		try:
			greenPoint = int(post.find("span",{"class":"smart-points green"}).get_text())
			bluePoint = int(post.find("span",{"class":"smart-points blue"}).get_text())
			purplePoint = int(post.find("span",{"class":"smart-points purple"}).get_text())

		except(AttributeError):
			greenPoint = -1
			bluePoint = -1
			purplePoint = -1

		# Getting the recipekeys for each recipe
		tmp = []
		icons = post.find("div",{"class":"post-meta"})
		recipeKey = icons.findAll("img")

		for i in recipeKey:
			tmp.append(i["alt"])

		# Casting the list as a dictionary to remove duplicate recipekeys
		recipeKeys = list(dict.fromkeys(tmp))

		Foods.append(Food(name, calorie, summary, img_url, bluePoint, greenPoint, purplePoint, recipeKeys))

def scrape():
		# Scraping the first 30 pages
	for i in range(1,31):
		print("{0}/30  pages scraped".format(i))
		# Utilizing a user-agent so that our requests will go through
		url = Request("https://skinnytaste.com/page/{0}".format(i), headers={'User-Agent': 'Mozilla/5.0'})
		parseData(url)
	print("Done!")

def get_list(minimum,maximum):
	arr = []
	for i in Foods:
		if(i.calorie >= minimum and i.calorie <= maximum):
			arr.append(i)
		if(len(arr) == 5):
			return arr
	return arr

def get_data():
	scrape()
	return Foods


# -*- coding: utf-8 -*-
# @Time    : 2021/3/6
# @Author  : Мэн Цзянин
# @FileName: KP15.py
# @Software: Pycharm
# @Versions: v0.3
# @Github  ：https://github.com/NekoSilverFox
# ~~~~~~~~~~~~~~~~~~~

import cv2 as cv
import numpy as np
from stackImages import stackImages

# Определяет некоторые из необходимых констант
CAM_WIDTH = 640
CAM_HEIGHT = 480
CAM_BRIGHTNESS = 150
CAM_ID = 0
PRINT_SIZE = 5
PRINT_COLOR = (255, 0, 0)
gl_path_mask = np.zeros((CAM_HEIGHT, CAM_WIDTH, 3), dtype=np.uint8)

def empty(none):
    pass

# Для цветного экранирования
def color_picker():
    # 设置摄像头的大小
    # Настройка размера камеры
    cam = cv.VideoCapture(CAM_ID)
    cam.set(3, CAM_WIDTH)
    cam.set(4, CAM_HEIGHT)
    cam.set(10, CAM_BRIGHTNESS)

    # 跟踪杆
    # Создание трекер-бара
    cv.namedWindow("HSY-TrackBars")
    cv.resizeWindow("HSY-TrackBars", CAM_WIDTH, CAM_HEIGHT)

    cv.createTrackbar("Hue Min", "HSY-TrackBars", 0, 179, empty)
    cv.createTrackbar("Sat Min", "HSY-TrackBars", 0, 255, empty)
    cv.createTrackbar("Val Min", "HSY-TrackBars", 0, 255, empty)

    cv.createTrackbar("Hue Max", "HSY-TrackBars", 179, 179, empty)
    cv.createTrackbar("Sat Max", "HSY-TrackBars", 255, 255, empty)
    cv.createTrackbar("Val Max", "HSY-TrackBars", 255, 255, empty)

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

    while True:
        is_success, img = cam.read()
        img_HSV = cv.cvtColor(img, cv.COLOR_BGR2HSV)

        h_min = cv.getTrackbarPos("Hue Min", "HSY-TrackBars")
        h_max = cv.getTrackbarPos("Hue Max", "HSY-TrackBars")

        s_min = cv.getTrackbarPos("Sat Min", "HSY-TrackBars")
        s_max = cv.getTrackbarPos("Sat Max", "HSY-TrackBars")

        v_min = cv.getTrackbarPos("Val Min", "HSY-TrackBars")
        v_max = cv.getTrackbarPos("Val Max", "HSY-TrackBars")
        print(h_min, h_max, s_min, s_max, v_min, v_max)

        # 将我们不需要的颜色设为黑色，需要的设为白色
        # Установите нежелательные цвета на черный, а желаемые - на белый
        lower = np.array([h_min, s_min, v_min])
        upper = np.array([h_max, s_max, v_max])
        mask = cv.inRange(img_HSV, lower, upper)
        img_result = cv.bitwise_and(img, img, mask=mask)
        mask = cv.cvtColor(mask, cv.COLOR_GRAY2BGR)

        img_stack = stackImages(0.6, ([img, mask, img_result]))
        cv.imshow("Stack images", img_stack)
        cv.waitKey(1)

# Путь для рисования цветных блоков
def print_path(x, y):
    cv.circle(gl_img_result, (x, y), PRINT_SIZE, PRINT_COLOR, -1)
    cv.circle(gl_path_mask, (x, y), PRINT_SIZE, PRINT_COLOR, -1)

# Используется для поиска цветового блока заданного цвета.
def find_color(img_input, prick_colors_list):
    img_HSV = cv.cvtColor(img_input, cv.COLOR_BGR2HSV)
    index_color = 0

    for color in prick_colors_list:
        lower = np.array(color[0:3])
        upper = np.array(color[3:6])
        mask = cv.inRange(img_HSV, lower, upper)

        x, y = get_contours(mask)
        print_path(x, y)

        index_color += 1
        if index_color > 3:
            print("[ERROR] In dead loop!")

        # print(mask)
        cv.imshow("Mask", mask)

def get_contours(img):
    contours, hierarchy = cv.findContours(img, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_NONE)
    x = 0
    y = 0
    w = 0
    h = 0
    for event in contours:
        area_img = cv.contourArea(event)
        if area_img > 500:
            cv.drawContours(gl_img_result, event, -1, PRINT_COLOR, 3)
            peri_img = cv.arcLength(event, True)
            approx = cv.approxPolyDP(event, 0.02 * peri_img, True)
            x, y, w, h = cv.boundingRect(approx)
            print("Print point on [%d, %d]" % (x, y))
    return (x + w // 2), (y + h // 2)

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

# color_picker()

# 设置摄像头的大小
# Настройка размера камеры
cam = cv.VideoCapture(CAM_ID)
cam.set(3, CAM_WIDTH)
cam.set(4, CAM_HEIGHT)
cam.set(10, CAM_BRIGHTNESS)
output = cv.VideoWriter("output.avi", cv.VideoWriter_fourcc("M", "J", "P", "G"), 29, (CAM_WIDTH, CAM_HEIGHT))

# Используйте список для записи цветов, которые могут быть сопоставлены
picker_colors_list = [  # [0, 103, 255, 179, 255, 255],  # Red
    [97, 34, 93, 179, 255, 255]]  # Blue

while True:
    is_success, img_row = cam.read()
    if not is_success:
        print("[ERROR] Can not read camera!")
        break

    gl_img_result = img_row.copy()

    find_color(img_row, picker_colors_list)
    img_result_with_path = cv.addWeighted(img_row, 1, gl_path_mask, 1, 0)

    # Отображение изображений в виде окна
    # cv.imshow("Row camera", img)
    cv.imshow("Catch contours", gl_img_result)
    cv.imshow("Result path on black canvas", gl_path_mask)
    cv.imshow("Result camera with path", img_result_with_path)
    output.write(img_result_with_path)

    # Выход из программы с помощью клавиши `q` на клавиатуре
    if cv.waitKey(1) & 0xFF == ord('q'):
        break

cam.release()
output.release()

080 - 虚拟绘画/虚拟识别-KP优化版.py

虚拟识别-KP优化版.py


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

import numpy
from cv2 import cv2

class Image:
    def __init__(self, image):
        self.image = cv2.imread(image, cv2.IMREAD_UNCHANGED)

    @property
    def width(self):
        return self.image.shape[1]

    @property
    def height(self):
        return self.image.shape[0]

class MatchImg(object):
    def __init__(self, source, template, threshod=0.95):
        """
        匹配一个图片，是否是另一个图片的局部图。source是大图，template是小图。即判断小图是否是大图的一部分。
        :param source:
        :param template:
        :param threshod: 匹配程度，值越大，匹配程度要求就越高，最好不要太小
        """
        self.source_img = source
        self.template_img = template
        self.threshod = threshod

    def set_confidence(self, confidence):
        self.threshod = confidence

    def match_template(self, method=cv2.TM_CCOEFF_NORMED):
        """
        返回小图左上角的点，在大图中的坐标。
        :param method:
        :return: list[tuple(x,y),...]
        """
        try:
            result = cv2.matchTemplate(self.source_img.image, self.template_img.image, method)
            locations = numpy.where(result >= self.threshod)
            res = list(zip(locations[1], locations[0]))  # 返回的是匹配到的template左上角那个坐标点在image中的位置，可能有多个值
            return res
        except cv2.error as e:
            print(e)

    def get_template_position(self):
        """
        获取小图在大图中，左上角和右下角的坐标
        :return: List[list[x,y,x,y],...]
        """
        res = self.match_template()
        new_pos = []
        for r in res:
            r = list(r)
            r.append(r[0] + self.template_img.width)
            r.append(r[1] + self.template_img.height)
            new_pos.append(r)
        return new_pos

    def get_img_center(self):
        """
        获取大图中，每个小图中心点所在的坐标
        :return:
        """
        pos = self.match_template()
        points = []
        for p in pos:
            x, y = p[0] + int(self.template_img.width / 2), p[1] + int(self.template_img.height / 2)
            points.append((x, y))
        return points

def load_image_file(path):
    path = path
    image = Image(path)
    return image

if __name__ == "__main__":
    img1 = load_image_file(r'E:\PyAutoProject\img\img.png')
    img2 = load_image_file(r'E:\PyAutoProject\img\img.png')

    process = MatchImg(img1, img2, 0.96)
    points = process.get_img_center()
    print(points)


import requests
import json
import telebot

# Chave do bot no Telegram
bot_key = 'BOT KEY AQUI'

# Chave da API da OpenAI
openai_key = 'OPENAI KEY AQUI'

# URL da API
api_url = 'https://api.openai.com/v1/chat/completions'

# Função para enviar mensagem para a API
def send_message(messages, message):
    headers = {
        'Content-Type': 'application/json',
        'Authorization': f'Bearer {openai_key}'
    }

    data = {
        'model': 'gpt-3.5-turbo',
        'messages': messages + [{"role": "user", "content": message}]
    }

    response = requests.post(api_url, headers=headers, data=json.dumps(data))

    if response.status_code == 200:
        return json.loads(response.text)['choices'][0]['message']['content']
    else:
        return None

# Inicializa o bot
bot = telebot.TeleBot(bot_key)

# Armazena as mensagens da conversa
conversation = []

@bot.message_handler(commands=['start'])
def start(message):
    bot.send_message(message.chat.id, "Olá! Eu sou o ChatPEO. Me envie uma mensagem e eu tentarei respondê-lo da melhor forma possível.")

# Função para responder as mensagens
@bot.message_handler(func=lambda message: True)
def echo_all(message):
    # Adiciona a mensagem atual à lista
    conversation.append({"role": "user", "content": message.text})

    # Envia a mensagem para a API
    response = send_message(conversation, message.text)

    if response is not None:
        # Adiciona a mensagem da API à lista
        conversation.append({"role": "assistant", "content": response})

        # Envia a resposta do bot
        bot.reply_to(message, response)
    else:
        bot.reply_to(message, 'Desculpe, não consegui entender.')

# Inicia o bot
bot.polling()


from mastermind import *
from DQN import *

mastermind = Mastermind()
stateDim = len(mastermind.color_code)*len(mastermind.colors) + 3*len(mastermind.color_code)
actionDim = len(mastermind.colorPairs)
dqn = DQN(stateDim=stateDim,actionDim=actionDim)

print("Color options: ",mastermind.colors)

print("The correct code:",mastermind.color_code)
guessedCode = random.sample(mastermind.colors,4) # Inital guess is randomized

feedback = mastermind.guess(guessedCode)
print("AI guess:",guessedCode,"Feedback:",feedback)

curState = mastermind.code2state(guessedCode, feedback)

maxAttempt = 20
while (not mastermind.win) and (mastermind.attempts <= maxAttempt):
    # make a guess
    action = dqn.chooseAction(curState, True)
    guessedCode = mastermind.colorPairs[action]
    # Get feedback based on the rules
    feedback = mastermind.guess(guessedCode)
    print("AI guess:", guessedCode, "Feedback:", feedback)

    reward = np.sum(feedback)
    # Keep the current state of the game for the network
    nextState = mastermind.code2state(guessedCode, feedback)

    curState = nextState
print("Game over,AI attempted %d times"%mastermind.attempts)


import sys

s1 = input().strip()
s2 = input().strip()
n = len(s1)
m = len(s2)

memo = [([-1] * (m + 1)) for i in range(0, n + 1)]

for i in range(0, n + 1):
    for j in range(0, m + 1):
        if i == 0 or j == 0:
            memo[i][j] = 0

        elif s1[i - 1] == s2[j - 1]:
            memo[i][j] = memo[i - 1][j - 1] + 1
        else:
            memo[i][j] = max(memo[i - 1][j], memo[i][j - 1])

print(memo[n][m])
"""
def lcs(s1, s2, n, m, memo):
    if n == 0 or m == 0:
        return 0

    if memo[n][m] != -1:
        return memo[n][m]

    if s1[n - 1] == s2[m - 1]:
        memo[n][m] = 1 + lcs(s1, s2, n - 1, m - 1, memo)

        return memo[n][m]
    else:
        memo[n][m] = max(lcs(s1, s2, n, m - 1, memo), lcs(s1, s2, n - 1, m, memo))

        return memo[n][m]

def lcs_dp(s1, s2, n, m):
    for i in range(0, n + 1):
        for j in range(0, m + 1):
            if i == 0 or j == 0:
                memo[i][j] = 0

            elif s1[i - 1] == s2[j - 1]:
                memo[i][j] = memo[i - 1][j - 1] + 1
            else:
                memo[i][j] = max(memo[i - 1][j], memo[i][j - 1])

    return memo[n][m]
def commonChild(s1, s2):
    n = len(s1)
    m = len(s2)

    for i in range(0, n + 1):
        for j in range(0, m + 1):
            if i == 0 or j == 0:
                memo[i][j] = 0

            elif s1[i - 1] == s2[j - 1]:
                memo[i][j] = memo[i - 1][j - 1] + 1
            else:
                memo[i][j] = max(memo[i - 1][j], memo[i][j - 1])

    return memo[n][m]

result = commonChild(s1, s2)

print(result)"""


# estrutura de repetição while()

"""
Por algum motivo, não estou conseguindo encontrar a documentação desse comando, portanto, farei o material dele com o meu conhecimento prévio.

Resumidamente, o while() é uma estrutura de repetição que recebe uma condição como parâmetro (tanto para iniciar a execução do código, quanto para finalizar a execução).

E cuidado, caso você insira uma condição que nunca será satisfeita, o código entrará em loop infinito! Exemplo:

```
var = 10

while(var > 5):
  print(var)
```

Nesse trecho mencionado acima, o interpretador do Python irá imprimir o número 10 eternamente (a menos que você cancele o processo). Vamos a um exemplo mais dinâmico:
"""

quantia = int(input("Insira quanto dinheiro tens no momento: "))
cont_notas = 0

while(quantia >= 100):
    quantia -= 100
    cont_notas += 1

print(f"Você precisara de {cont_notas} de R$100")

# zerar contador para reutilizar
cont_notas = 0

while(quantia >= 50):
    quantia -= 50
    cont_notas += 1

print(f"Você precisara de {cont_notas} de R$50")

# zerar contador para reutilizar
cont_notas = 0

while(quantia >= 20):
    quantia -= 20
    cont_notas += 1

print(f"Você precisara de {cont_notas} de R$20")

# zerar contador para reutilizar
cont_notas = 0

while(quantia >= 10):
    quantia -= 10
    cont_notas += 1

print(f"Você precisara de {cont_notas} de R$10")

# zerar contador para reutilizar
cont_notas = 0

while(quantia >= 5):
    quantia -= 5
    cont_notas += 1

print(f"Você precisara de {cont_notas} de R$5")

# zerar contador para reutilizar
cont_notas = 0

while(quantia >= 2):
    quantia -= 2
    cont_notas += 1

print(f"Você precisara de {cont_notas} de R$2")

# OBS.: Esse codigo eu tirei de uma questão da lista 02.

# No momento, só colocarei isso, agora verei como proceder na sessao 02!!


# To Do List (Delete one after finishing it)
# TODO: Make the HT and VT more object-oriented
# TODO: Evaluate the effect of the winglet in terms of fuel required for a certain mission
# TODO: Fix the output 3D model
# TODO: Output pdf
# TODO: EMWET

import os
from Geometry.ref_frame import Frame
from Geometry.fuselage import Fuselage
from Geometry.wing import Wing
from Geometry.HT import HorizontalTail
from Geometry.VT import VerticalTail
from HelperFunction.readGeometry import ReadGeometry
from Geometry.winglet import *
from parapy.exchange.step import STEPWriter
from HelperFunction.analysis import Analysis

DIR = os.path.dirname(__file__)

class Aircraft(GeomBase):
    input = ReadGeometry("A320")

    winglet_ON = Input(True)
    TYPE_wing_airfoil = Input(1)
    TYPE_winglet = Input(0)
    M_cruise = Input(input.M_cruise)  # cruise mach number

    # -------- FUSELAGE -----------#
    ln_d = Input(1.22)  # nose slenderness ratio
    lt_d = Input(2.724)  # tail slenderness ratio

    # --------- WING --------------#
    name = Input("wing")
    airfoil_root = Input(input.w_af_root)
    airfoil_kink = Input(input.w_af_kink)
    airfoil_tip = Input(input.w_af_tip)
    wing_span = Input(input.wing_span)
    incidence = Input(input.incidence)
    twist = Input(input.twist)
    wing_c_root = Input(input.wing_c_root)
    wing_taper_ratio_inboard = Input(input.wing_taper_ratio_inboard)

    # ---------- Horizontal Tail -------------#
    htp_root_airfoil = Input("Boeing29root")
    htp_tip_airfoil = Input("lockheedtip")
    htp_area = Input(31)
    htp_taper = Input(0.3)
    htp_dihedral = Input(5)

    # ----------- VERTICAL TAIL ---------------#
    vtp_root_airfoil = Input("NACA0012")
    vtp_tip_airfoil = Input("NACA0012")
    vtp_aspect_ratio = Input(1.82)
    vtp_sweep = Input(35)
    vtp_area = Input(21.5)

    # -------------- Winglet -------------------#
    # --------TYPE 0 Canted Winglet-------------
    ct_name = "Canted Winglet"
    ct_airfoil_root = Input(input.ct_airfoil_root)
    ct_airfoil_tip = Input(input.ct_airfoil_tip)

    ct_chord_root_ratio = Input(input.ct_chord_root_ratio)
    ct_taper_ratio = Input(input.ct_taper_ratio)
    ct_height_ratio = Input(input.ct_height_ratio)
    ct_sweep = Input(input.ct_sweep)
    ct_cant = Input(input.ct_cant, validator=Range(0, 90))
    ct_twist_tip = Input(input.ct_twist_tip)

    # --------TYPE 1 Wingtip Fence-------------
    wtf_name = Input("Wingtip Fence")
    wtf_airfoil_up = Input(input.wtf_airfoil_up)
    wtf_airfoil_root = Input(input.wtf_airfoil_root)
    wtf_airfoil_down = Input(input.wtf_airfoil_down)
    wtf_chord_root_ratio = Input(input.wtf_chord_root_ratio)
    wtf_taper_ratio_up = Input(input.wtf_taper_ratio_up)
    wtf_taper_ratio_down = Input(input.wtf_taper_ratio_down)
    wtf_height_up_ratio = Input(input.wtf_height_up_ratio)
    wtf_height_down_ratio = Input(input.wtf_height_down_ratio)
    wtf_sweep_up = Input(input.wtf_sweep_up)
    wtf_sweep_down = Input(input.wtf_sweep_down)
    wtf_twist_up = Input(input.wtf_twist_up)
    wtf_twist_down = Input(input.wtf_twist_down)

    # --------TYPE 2 Raked Wingtip-------------
    rkt_name = Input("Raked Wingtip")
    rkt_airfoil_start = Input(input.rkt_airfoil_start)
    rkt_airfoil_tip = Input(input.rkt_airfoil_tip)
    rkt_chord_start = Input(input.rkt_chord_start)
    rkt_taper_ratio = Input(input.rkt_taper_ratio)
    rkt_span_ratio = Input(input.rkt_span_ratio)
    rkt_sweep_le = Input(input.rkt_sweep_le)

    # --------TYPE 3 Sharklet-------------------
    skt_airfoil_start = Input(input.skt_airfoil_start)
    skt_airfoil_mid = Input(input.skt_airfoil_mid)
    skt_airfoil_tip = Input(input.skt_airfoil_tip)

    skt_chord_mid = Input(input.skt_chord_mid)
    skt_K_lambda = Input(input.skt_K_lambda)
    skt_height_ratio = Input(input.skt_height_ratio)
    skt_KR = Input(input.skt_KR)
    skt_cant = Input(input.skt_cant)
    skt_sweep_le = Input(input.skt_sweep_le)
    skt_sweep_transition_te = Input(input.skt_sweep_transition_te)
    skt_twist = Input(input.skt_twist)
    skt_nu_blended_sections = Input(input.skt_nu_blended_sections)

    @Part
    def aircraft_frame(self):
        return Frame(pos=self.position)  # this helps visualizing the wing local reference frame

    @Part
    def fuselage(self):
        return Fuselage(pass_down="ln_d, lt_d",
                        color="Blue")

    @Part
    def htp_right_wing(self):
        return HorizontalTail(htp_root_airfoil=self.htp_root_airfoil,
                              htp_tip_airfoil=self.htp_tip_airfoil,
                              htp_area=self.htp_area,
                              htp_taper=self.htp_taper,
                              htp_dihedral=self.htp_dihedral,
                              wing_area=self.right_wing.wing_area_total,
                              starting_point_mac=self.right_wing.starting_point_mac,
                              wing_sweep_025c=self.right_wing.wing_sweep_025c,
                              MAC_chord_length=self.right_wing.MAC_chord_length,
                              position=self.position.translate('z', 0.3 * self.fuselage.cabin_d))

    @Part
    def htp_left_wing(self):
        return MirroredShape(shape_in=self.htp_right_wing.solid,
                             reference_point=self.htp_right_wing.position,
                             transparency=0.4,
                             vector1=self.htp_right_wing.position.Vz,
                             vector2=self.htp_right_wing.position.Vx)

    @Part
    def right_wing(self):
        return Wing(name=self.name,
                    TYPE_airfoil=self.TYPE_wing_airfoil,
                    airfoil_root=self.airfoil_root,
                    airfoil_kink=self.airfoil_kink,
                    airfoil_tip=self.airfoil_tip,
                    wing_span=self.wing_span,
                    M_cruise=self.M_cruise,
                    incidence=self.incidence,
                    twist=self.twist,
                    wing_c_root=self.wing_c_root,
                    wing_taper_ratio_inboard=self.wing_taper_ratio_inboard,
                    cabin_l=self.fuselage.cabin_l,
                    position=self.position.translate('x', 0.48 * self.fuselage.cabin_l,
                                                     '-z', 0.40 * self.fuselage.cabin_d))

    @Part(parse=False)
    def right_winglet(self):
        if self.TYPE_winglet == 0:
            return CantedWinglet(name="Canted Winglet",
                                 airfoil_root=self.ct_airfoil_root,
                                 airfoil_tip=self.ct_airfoil_tip,
                                 chord_wingtip=self.right_wing.chords[2],
                                 chord_root_ratio=self.ct_chord_root_ratio,
                                 taper_ratio=self.ct_taper_ratio,
                                 wing_span=self.right_wing.wing_span/2,
                                 height_ratio=self.ct_height_ratio,
                                 sweep=self.ct_sweep,
                                 cant=self.ct_cant,
                                 twist_tip=self.ct_twist_tip,
                                 position=self.right_wing.section_positions[2],
                                 avl_duplicate_pos=self.position,
                                 suppress=not self.winglet_ON)

        elif self.TYPE_winglet == 1:
            return WingtipFence(name="Wingtip Fence",
                                airfoil_up=self.wtf_airfoil_up,
                                airfoil_root=self.wtf_airfoil_root,
                                airfoil_down=self.wtf_airfoil_down,
                                chord_wingtip=self.right_wing.chords[2],
                                wing_span=self.right_wing.wing_span/2,
                                chord_root_ratio=self.wtf_chord_root_ratio,
                                taper_ratio_up=self.wtf_taper_ratio_up,
                                taper_ratio_down=self.wtf_taper_ratio_down,
                                height_up_ratio=self.wtf_height_up_ratio,
                                height_down_ratio=self.wtf_height_down_ratio,
                                sweep_up=self.wtf_sweep_up,
                                sweep_down=self.wtf_sweep_down,
                                twist_up=self.wtf_twist_up,
                                twist_down=self.wtf_twist_down,
                                position=rotate(translate(self.right_wing.section_positions[2],
                                                          'x', self.right_wing.chords[2] -
                                                          self.right_wing.chords[2] * self.wtf_chord_root_ratio),
                                                'x', np.deg2rad(-90)),
                                avl_duplicate_pos=self.position,
                                suppress=not self.winglet_ON)

        elif self.TYPE_winglet == 2:
            return RakedWingtip(name="Raked Wingtip",
                                airfoil_start=self.rkt_airfoil_start,
                                airfoil_tip=self.rkt_airfoil_tip,
                                chord_start=self.right_wing.chords[2],
                                taper_ratio=self.rkt_taper_ratio,
                                wing_span=self.right_wing.wing_span / 2,
                                span_ratio=self.rkt_span_ratio,
                                sweep_le=self.rkt_sweep_le,
                                position=self.right_wing.section_positions[2],
                                avl_duplicate_pos=self.position,
                                suppress=not self.winglet_ON)

        elif self.TYPE_winglet == 3:
            return Sharklet(name="Sharklet",
                            airfoil_start=self.skt_airfoil_start,
                            airfoil_mid=self.skt_airfoil_mid,
                            airfoil_tip=self.skt_airfoil_tip,
                            # chord start = wing.chord_tip
                            chord_start=self.right_wing.chords[2],
                            chord_mid=self.skt_chord_mid,
                            K_lambda=self.skt_K_lambda,
                            wing_semi_span=self.right_wing.wing_span / 2,
                            height_ratio=self.skt_height_ratio,
                            KR=self.skt_KR,
                            cant=self.skt_cant,
                            sweep_le=self.skt_sweep_le,
                            sweep_transition_te=self.skt_sweep_transition_te,
                            twist=self.skt_twist,
                            dihedral=self.right_wing.wing_dihedral,
                            nu_blended_sections=self.skt_nu_blended_sections,
                            position=rotate(self.right_wing.section_positions[2],
                                            'x', np.deg2rad(self.right_wing.wing_dihedral)),
                            avl_duplicate_pos=self.position,
                            suppress=not self.winglet_ON)

    @Part
    def left_wing(self):
        return MirroredShape(shape_in=self.right_wing.solid,
                             reference_point=self.right_wing.position,
                             transparency=0.4,
                             vector1=self.right_wing.position.Vz,
                             vector2=self.right_wing.position.Vx)

    @Part
    def left_winglet(self):
        return MirroredShape(shape_in=self.right_winglet.surface,
                             reference_point=self.right_wing.position.point,
                             # Two vectors to define the mirror plane
                             vector1=self.right_wing.position.Vz,
                             vector2=self.right_wing.position.Vx,
                             suppress=not self.winglet_ON,
                             mesh_deflection=0.0001)

    @Part
    def vtp_wing(self):
        return VerticalTail(vtp_root_airfoil=self.vtp_root_airfoil,
                            vtp_tip_airfoil=self.vtp_tip_airfoil,
                            vtp_aspect_ratio=self.vtp_aspect_ratio,
                            vtp_sweep=self.vtp_sweep,
                            vtp_area=self.vtp_area,
                            htp_area=self.htp_right_wing.htp_area,
                            lh=self.htp_right_wing.lh,
                            Vh=self.htp_right_wing.Vh,
                            MAC_chord_length=self.right_wing.MAC_chord_length,
                            starting_point_mac=self.right_wing.starting_point_mac,
                            cabin_d=self.fuselage.cabin_d,
                            wing_span=self.right_wing.wing_span,
                            position=rotate90(self.position.translate('z', (0.48 * self.fuselage.cabin_d)),
                                              'x'),
                            color="blue")

    @Attribute
    def avl_surfaces(self):  # this scans the product tree and collect all instances of the avl.Surface class
        return self.find_children(lambda o: isinstance(o, avl.Surface))

    @Part
    def avl_configuration(self):
        return avl.Configuration(name='A320',
                                 reference_area=self.right_wing.wing_area_total,
                                 reference_span=self.right_wing.wing_span,
                                 reference_chord=self.right_wing.MAC_chord_length,
                                 reference_point=self.position.point,
                                 surfaces=self.avl_surfaces,
                                 mach=self.M_cruise)

    @Part
    def step_writer_components(self):
        return STEPWriter(default_directory=DIR,
                          trees=[self.fuselage,
                                 self.right_wing,
                                 self.right_winglet,
                                 self.left_wing,
                                 self.left_winglet])

    @Part
    def avl_analysis(self):
        return Analysis(aircraft=[self.right_wing,
                                  self.right_winglet,
                                  self.left_wing,
                                  self.left_winglet],
                        altitude=9000,
                        TYPE_winglet=self.TYPE_winglet,
                        TYPE_wing_airfoil=self.TYPE_wing_airfoil,
                        configuration=self.avl_configuration,
                        case_settings=[('fixed_aoa', {'alpha': 3}),
                                       ('fixed_cl', {'alpha': avl.Parameter(name='alpha', value=0.5, setting='CL')})]
                        )

if __name__ == '__main__':
    from parapy.gui import display

    obj = Aircraft(label="Aircraft assembly")
    display(obj)


diaInicio = int(input().replace("Dia ", ""))
hi, mi, si = [int(x) for x in input().split(" : ")]
diaFim = int(input().replace("Dia ", ""))
hf, mf, sf = [int(x) for x in input().split(" : ")]

dias = diaFim - diaInicio
horas = hf - hi
minutos = mf - mi
segundos = sf - si

if segundos < 0:
  segundos = 60 + segundos
  minutos -= 1

if minutos < 0:
  minutos = 60 + minutos
  horas -= 1

if horas < 0:
  horas = 24 + horas
  dias -= 1

print(f"{dias} dia(s)")
print(f"{horas} hora(s)")
print(f"{minutos} minuto(s)")
print(f"{segundos} segundo(s)")


def cipher(text, shift, encrypt=True):
    """
    The Caesar cipher function is an encryption code where it is replaced by a
    letter from the alphabet after a fixed number of positions down the alphabet
    (A then B then C, etc.).

    The parameters are text, shift, and encrypt=True. The text would contain a word or
    phrase that are from the letters of the alphabet, shift would be a number, and
    encrypt=True ensures that this function would shift. If encrypt=False, it will go
    up the alphabet, meaning the opposite direction of encrypt=True.

    Encrypting:
    cipher('hello', 2, encrypt=True):
    jgnnq

    Decrypting:
    cipher('jgnnq', 2, encrypt=False):
    hello

    """
    alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    new_text = ''
    for c in text:
        index = alphabet.find(c)
        if index == -1:
            new_text += c
        else:
            new_index = index + shift if encrypt == True else index - shift
            new_index %= len(alphabet)
            new_text += alphabet[new_index:new_index+1]
    return new_text


from preprocessing.sms import SMSDataPreprocessingManager
from sklearn.metrics import confusion_matrix, classification_report, accuracy_score
from model.model import *
import argparse

if __name__ == "__main__":

    parser = argparse.ArgumentParser(description="set arguments. ")
    parser.add_argument("--data_path", default="./data/sample/spam.csv", type=str, help="Traing and Validation data")
    parser.add_argument("--model_path", default="./models/model/model.pkl", type=str, help="save model path")

    args = parser.parse_args()

    # 데이터 불러오기
    train_df = SMSDataPreprocessingManager.read_entire_data(path=args.data_path)

    # 데이터 preprocessing
    X_data_tfidf, X_train_tfidf, X_test_tfidf, y_train, y_test = SMSDataPreprocessingManager.data_preprocess(train_df)

    # training model
    lgbm_model = training_model(X_train_tfidf, X_test_tfidf, y_train, y_test)

    # save model
    save_model(lgbm_model, args.model_path)

    # evaluate model
    y_pred = evaluate_model(lgbm_model, X_test_tfidf)

    print(classification_report(y_test, y_pred, target_names=['ham', 'spam']))