import datetime
import pytest

@pytest.fixture
def basic_event():
    return {
        "id": "harrastushaku:13248",
        "location": {
            "@id": "https://api.hel.fi/linkedcourses/v1/place/tprek:8020/"
        },
        "keywords": [{
            "@id": "https://api.hel.fi/linkedcourses/v1/keyword/yso:p23125/"
        }],
        "super_event": None,
        "event_status": "EventRescheduled",
        "external_links": [],
        "offers": [],
        "data_source": "harrastushaku",
        "publisher": "ahjo:u48040030",
        "sub_events": [],
        "images": [{
            "id": 2531,
            "license": "cc_by",
            "created_time": "2020-06-10T11:15:57.772163Z",
            "last_modified_time": "2020-06-10T11:15:57.772182Z",
            "name": "",
            "url": "https://www.harrastushaku.fi/images/activityimages/6135_0232.JPG",
            "cropping": "",
            "photographer_name": None,
            "alt_text": None,
            "data_source": "harrastushaku",
            "publisher": "ahjo:u48040030",
            "@id": "https://api.hel.fi/linkedcourses/v1/image/2531/",
            "@context": "http://schema.org",
            "@type": "ImageObject"
        }],
        "videos": [],
        "in_language": [],
        "audience": [{
            "@id": "https://api.hel.fi/linkedcourses/v1/keyword/yso:p11617/"
        }, {
            "@id": "https://api.hel.fi/linkedcourses/v1/keyword/yso:p16485/"
        }],
        "created_time": "2020-06-12T06:15:44.181210Z",
        "last_modified_time": "2020-07-30T12:19:11.898081Z",
        "date_published": "2020-07-30T11:17:00Z",
        "start_time": "2020-08-22",
        "end_time": "2020-08-22",
        "custom_data": None,
        "audience_min_age": 12,
        "audience_max_age": 17,
        "super_event_type": None,
        "deleted": False,
        "replaced_by": None,
        "extension_course": {
            "enrolment_start_time": None,
            "enrolment_end_time": None,
            "maximum_attendee_capacity": 35,
            "minimum_attendee_capacity": None,
            "remaining_attendee_capacity": 1
        },
        "location_extra_info": None,
        "description": {
            "fi": "<p> <span style='background - color: initial;''>Työnjaossa pääset siivoamaan\
            karsinoita ja tekemään muita navettatöitä, hoitamaan ja puuhailemaan erilaisten eläinten\
            kanssa sekä ruokkimaan eläimiä. Voit esimerkiksi päästä taluttamaan lehmää, hypyttämään\
            vuohta agility radalla, harjaamaan kania tai jopa ratsastamaan. Työnjako alkaa klo 10.30\
            ja loppuu klo 15. Ota mukaan säänmukaiset ja navettaan sopivat vaatteet sekä kumisaappaat,\
            osa päivästä ollaan ulkona. Toimintapäiviin sisältyy yhteinen ruokatauko, jolloin syödään\
            omia eväitä. </span> </p>"
        },
        "provider_contact_info": None,
        "provider": None,
        "name": {
            "fi": "Lauantai työnjako 22.8."
        },
        "info_url": None,
        "short_description": None,
        "@id": "https://api.hel.fi/linkedcourses/v1/event/harrastushaku:13248/",
        "@context": "http://schema.org",
        "@type": "Event/LinkedEvent"
}

@pytest.fixture
def event_with_images_only(frozen_datetime):
    return {
        'images': [
            {
                '@context': 'http://schema.org',
                '@id': 'foo',
                '@type': 'ImageObject',
                'alt_text': None,
                'created_time': (frozen_datetime - datetime.timedelta(days=6 * 30)).isoformat() + 'Z',
                'cropping': '',
                'data_source': 'foo',
                'id': 1,
                'last_modified_time': (frozen_datetime - datetime.timedelta(days=30)).isoformat() + 'Z',
                'license': 'cc_by',
                'name': '',
                'photographer_name': None,
                'publisher': 'foo:u1',
                'url': 'https://doesnotexist.local/images/image001.jpg'
            }
        ],
    }

@pytest.fixture
def imported_hobby(hobby_with_events):
    hobby_with_events.data_source = 'linked_courses'
    hobby_with_events.origin_id = 'foo:1'
    hobby_with_events.save()
    event = hobby_with_events.events.all()[0]
    event.data_source = 'linked_courses'
    event.origin_id = 'foo:1'
    event.save()
    event = hobby_with_events.events.all()[1]
    event.data_source = 'linked_courses'
    event.origin_id = 'foo:2'
    event.save()
    return hobby_with_events

@pytest.fixture
def imported_hobby2(hobby_with_events2):
    hobby_with_events2.data_source = 'linked_courses'
    hobby_with_events2.origin_id = 'foo:2'
    hobby_with_events2.save()
    event = hobby_with_events2.events.all()[0]
    event.data_source = 'linked_courses'
    event.origin_id = 'foo:3'
    event.save()
    event = hobby_with_events2.events.all()[1]
    event.data_source = 'linked_courses'
    event.origin_id = 'foo:4'
    event.save()
    return hobby_with_events2


def mask(n):
    mask = 0
    i = 1
    while n//i:
        digit = n/i % 10
        mask |= 1 << int(digit)
        i *= 10
    return mask

# set = a , memo = arr, a = alist
def dp(a,arr,alist):
    if a == 0:
        arr[a] = 0
        return arr[a]
    if arr[a] != -1:
        return arr[a]
    maxi = 0
    for num in alist:
        bitmask = mask(num)
        if ((a | bitmask) == a):
            maxi = max(dp(a ^ mask(num), arr, alist) + num, maxi)
    arr[a] = maxi
    return arr[a]

if __name__ == '__main__':
    t = int(input())
    for _ in range(t):
        n = int(input())
        li = list(map(int,input().split()))
        left = 1 << 10
        memo = [None] * left
        maxsum = 0
        for i in range(left):
            memo[i] = -1
        for i in range(left):
            maxsum = max(maxsum, dp(i, memo, li))
        print('Maximum = ',maxsum)


# -*- coding: utf-8 -*-
# @Time    : 2017/7/12 下午2:23
# @Author  : play4fun
# @File    : 一个重要的事.py
# @Software: PyCharm

"""
一个重要的事.py:
当我们可以  参 数 -1 来 定 出图像的深度 数据类型 与原图像保持一致
但是我们在代 码中使用的却是 cv2.CV_64F。 是为什么呢 ？
想象一下一个从黑到白的边界的导数是整数，而一个从白到黑的边界点导数却是负数。
如果原图像的深度是 np.int8 时 所有的负值 会 截断变成 0
 换句话就是把边界丢失掉。
所以如果 两种边界你 想检测到
最好的的办法就是将输出的数据类型 设置的更高
  比如 cv2.CV_16S cv2.CV_64F 等。
  取绝对值然后再把它 回 到 cv2.CV_8U。
  下 的示例演示了输出图片的深度不同造成的不同效果。
"""

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('../data/box.jpg', 0)

# Output dtype = cv2.CV_8U
sobelx8u = cv2.Sobel(img, cv2.CV_8U, 1, 0, ksize=5)
# Output dtype = cv2.CV_64F. Then take its absolute and convert to cv2.CV_8U
sobelx64f = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=5)

abs_sobel64f = np.absolute(sobelx64f)
sobel_8u = np.uint8(abs_sobel64f)

plt.subplot(1, 3, 1), plt.imshow(img, cmap='gray')
plt.title('Original'), plt.xticks([]), plt.yticks([])
plt.subplot(1, 3, 2), plt.imshow(sobelx8u, cmap='gray')
plt.title('Sobel CV_8U'), plt.xticks([]), plt.yticks([])
plt.subplot(1, 3, 3), plt.imshow(sobel_8u, cmap='gray')
plt.title('Sobel abs(CV_64F)'), plt.xticks([]), plt.yticks([])

plt.show()

ch18-图像梯度/一个重要的事.py


import hashlib
import hmac
import httplib
import json
import logging
import socket

from neutron.plugins.vyatta import exceptions
from neutron.plugins.vyatta import vrouter_db_v2
from oslo.config import cfg

from novaclient.v1_1 import client

LOG = logging.getLogger(__name__)

class ApiProxyClient(object):
    """APIProxyClient class to construct REST API client requests."""
    def __init__(self, server):
        self.server = server
        self.port = cfg.CONF.VROUTER.api_port

    def rest_call(self, action, uri, data):
        headers = {}

        if (data is not None):
            headers['Content-type'] = 'application/json'
            headers['Accept'] = 'application/json'

        private_key = cfg.CONF.VROUTER.api_private_key
        public_key = cfg.CONF.VROUTER.api_public_key
        content = json.dumps(data)
        hmac_digest = hmac.new(private_key, content, hashlib.sha1).hexdigest()

        headers['PublicKey'] = public_key
        headers['Hash'] = hmac_digest

        conn = httplib.HTTPConnection(self.server, self.port)
        if conn is None:
            LOG.error('ProxyClient: Could not establish HTTP connection.')
            raise exceptions.VRouterConnectFailure(ip_address=self.server)

        try:
            if (data is None):
                conn.request(action, uri, headers=headers)
            else:
                conn.request(action, uri, content, headers)

            response = conn.getresponse()
            response_data = json.loads(response.read())
            if response.status != 201:
                action_name = {
                    'GET': 'get',
                    'POST': 'create',
                    'PUT': 'update',
                    'DELETE': 'delete',
                }.get(action, 'do something with')
                raise exceptions.VRouterOperationError(
                    ip_address=self.server, action=action_name,
                    code=response.status, message=response_data)

            return_value = (response.status, response_data)
        except (socket.timeout, socket.error, ValueError) as exc:
            LOG.error(_('ProxyClient: Exception occurred while reading '
                        'the response: %s') % exc)
            raise exceptions.VRouterConnectFailure(ip_address=self.server)
        finally:
            conn.close()

        return return_value

def create_nova_client(context, tenant=None):
    if tenant is None:
        tenant_id = context.project_id
    else:
        tenant_id = None
    return client.Client(
        cfg.CONF.VROUTER.tenant_admin_name,
        cfg.CONF.VROUTER.tenant_admin_password,
        tenant, cfg.CONF.VROUTER.keystone_url, service_type="compute",
        tenant_id=tenant_id)

def allocate_instance(context, router):
    nova_client = create_nova_client(context, cfg.CONF.VROUTER.tenant_name)
    instances = nova_client.servers.findall()
    for instance in instances:
        if vrouter_db_v2.is_allocated(context.session, instance.id):
            continue
        ifs = instance.interface_list()
        if len(ifs) != 1:
            continue
        ip_address = ifs[0].fixed_ips[0]['ip_address']
        return ip_address, instance.id
    return None, None

def initialize_router(context, address, router):
    vrouter_client = ApiProxyClient(address)
    data = {
        'router': {
            'name': router.get('name', 'vyatta-router'),
            'admin_state_up': router.get('admin_state_up', False),
        }
    }
    vrouter_client.rest_call('POST', '/v2.0', data)

def deinitialize_router(context, address):
    vrouter_client = ApiProxyClient(address)
    vrouter_client.rest_call('DELETE', '/v2.0/router', None)

def attach_interface(context, port_id, instance_id):
    nova_client = create_nova_client(context)
    server = nova_client.servers.get(instance_id)
    server.interface_attach(port_id, None, None)

def detach_interface(context, port_id, instance_id):
    nova_client = create_nova_client(context)
    server = nova_client.servers.get(instance_id)
    server.interface_detach(port_id)

def configure_interface(context, address, interface_infos):
    vrouter_client = ApiProxyClient(address)
    for interface_info in interface_infos:
        data = {'router': {'router_interface_info': interface_info}}
        vrouter_client.rest_call(
            'PUT', '/v2.0/router/add_router_interface', data)

def deconfigure_interface(context, address, interface_infos):
    vrouter_client = ApiProxyClient(address)
    for interface_info in interface_infos:
        data = {'router': {'router_interface_info': interface_info}}
        vrouter_client.rest_call(
            'PUT', '/v2.0/router/remove_router_interface', data)

def configure_gateway(context, address, interface_infos):
    if len(interface_infos) != 1:
        raise exceptions.InvalidNumberIPsOnPort()
    vrouter_client = ApiProxyClient(address)
    data = {'router': {'external_gateway_info': interface_infos[0]}}
    vrouter_client.rest_call('PUT', '/v2.0/router', data)

def clear_gateway(context, address, interface_infos):
    vrouter_client = ApiProxyClient(address)
    data = {'router': {'external_gateway_info': None}}
    vrouter_client.rest_call('PUT', '/v2.0/router', data)

def assign_floating_ip(context, address, fixed_ip, floating_ip):
    vrouter_client = ApiProxyClient(address)
    data = {'router': {'router_floating_ip_info': {
            'floating_ip_address': floating_ip,
            'fixed_ip_address': fixed_ip}}}
    vrouter_client.rest_call('PUT', '/v2.0/router/assign_floating_ip', data)

def unassign_floating_ip(context, address, fixed_ip, floating_ip):
    vrouter_client = ApiProxyClient(address)
    data = {'router': {'router_floating_ip_info': {
            'floating_ip_address': floating_ip,
            'fixed_ip_address': fixed_ip}}}
    vrouter_client.rest_call('PUT', '/v2.0/router/unassign_floating_ip', data)


from torch_geometric.data import HeteroData
from torch_geometric.loader import DataLoader, DataListLoader
import torch_geometric.transforms as T
from torch_geometric.nn import HGTConv, Linear

from torch.optim import Adam
from torch.nn import functional as F
from torch import nn

from sklearn.metrics import classification_report

import torch
import argparse
import numpy as np
from tqdm.auto import tqdm
import pandas as pd
import json
import pickle
import os

class CICdata():
    def __init__(self, path_data):
        f = open(path_data,'rb')
        self.df = pickle.load(f)
        self.conn_feat = ['Duration', 'Packets', 'Bytes', 'Proto_ICMP ', 'Proto_IGMP ','Proto_TCP  ', 'Proto_UDP  ','flag_A', 'flag_P', 'flag_R', 'flag_S','flag_F', 'Tos_0', 'Tos_16', 'Tos_32', 'Tos_192']
        self.label_cols_oh = ['attack_benign','attack_bruteForce', 'attack_dos', 'attack_pingScan', 'attack_portScan']

    def make_ip_map(self, data):
        unique_ip = np.unique(np.append(data['Src IP Addr'].to_numpy(),
                                        data['Dst IP Addr'].to_numpy()))
        return {ip:idx for idx, ip in enumerate(unique_ip)}

    def encode_ip(self, value):
        temp = [0]*10
        if value == '192.168.100.6': #internal web server
            temp[0] = 1.0
        elif value == '192.168.100.5': #internal file server
            temp[1] = 1.0
        elif value == '192.168.100.4': #internal mail server
            temp[2] = 1.0
        elif value == '192.168.100.3': #internal backup server
            temp[3] = 1.0
        elif value[:11] == '192.168.100': #server subnet
            temp[4] = 1.0
        elif value[:11] == '192.168.200': #management subnet
            temp[5] = 1.0
        elif value[:11] == '192.168.210': #office subnet
            temp[6] = 1.0
        elif value[:11] == '192.168.220': #developer subnet
            temp[7] = 1.0
        elif value[5:6]=='_': #public ip
            temp[8] = 1.0
        elif value in ['0.0.0.0', '255.255.255.255']: #local ip
            temp[9] = 1.0

        return temp

    def get_ip_feat(self, ip_map):
        ip_data = []
        for ip, idx in ip_map.items():
            ip_data.append(self.encode_ip(ip))

        return torch.tensor(ip_data).float()

    def make_edges(self, data, ip_map):
        src = []
        dst = []
        count = 0
        for _, row in data.iterrows():
            #source ip to connection
            src.append(ip_map[row['Src IP Addr']])
            dst.append(count)

            #destination ip to connection
            src.append(ip_map[row['Dst IP Addr']])
            dst.append(count)
            count +=1

        return torch.tensor([src, dst]), torch.tensor([dst, src])

    def get_info_conn(self, data, cols):
        return torch.tensor(data[cols].values)

    def process(self, n_rows=200):
        x_conn = self.get_info_conn(self.df, self.conn_feat)
        y = self.get_info_conn(self.df, self.label_cols_oh)
        data_list = []

        for i in tqdm(range(1, (len(self.df)//n_rows)+1), desc='processing'):
            start_idx = (i-1)*n_rows
            end_idx = i*n_rows
            sample = self.df[start_idx:end_idx]
            ip_map = self.make_ip_map(sample)
            ip_to_conn, conn_to_ip = self.make_edges(sample, ip_map)
            data = HeteroData()
            data['ip'].x = self.get_ip_feat(ip_map) #encode ip's from the map
            data['connection'].x = x_conn[start_idx:end_idx].float()
            data['connection'].y = y[start_idx:end_idx]
            data['ip','connection'].edge_index = ip_to_conn
            data['connection','ip'].edge_index = conn_to_ip
            data_list.append(data)

        return data_list

class HGT(torch.nn.Module):
    def __init__(self, data_graph, hidden_channels, out_channels, num_heads, num_layers):
        super().__init__()

        self.lin_dict = torch.nn.ModuleDict()
        for node_type in data_graph.node_types:
            self.lin_dict[node_type] = Linear(-1, hidden_channels)

        print(self.lin_dict)
        self.convs = torch.nn.ModuleList()
        for _ in range(num_layers):
            conv = HGTConv(hidden_channels, hidden_channels, data_graph.metadata(),
                           num_heads, group='sum')
            self.convs.append(conv)

        self.lin = Linear(hidden_channels, out_channels)

    def forward(self, x_dict, edge_index_dict):
        for node_type, x in x_dict.items():
            x_dict[node_type] = self.lin_dict[node_type](x).relu_()

        for conv in self.convs:
            x_dict = conv(x_dict, edge_index_dict)

        return self.lin(x_dict['connection'])

def main(args):
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    cic_data = CICdata(args.train_data)
    #cic_data.df = cic_data.df[:2000]
    print('processing training data...\n')
    data_train = cic_data.process(n_rows=args.connections_graph)
    #out channels = number of classes
    #hidden channels and num_layers determines complexity
    model = HGT(data_graph= data_train[0], hidden_channels=args.hidden_channels, out_channels=5,
            num_heads=args.num_heads, num_layers=args.hidden_layers)

    # Initialize lazy module, still on cpu
    with torch.no_grad():
        out = model(data_train[0].x_dict, data_train[0].edge_index_dict)

    #hard code batch size
    batch_size = 64
    optimizer = Adam(model.parameters())
    train_loader = DataLoader(data_train, batch_size=batch_size)

    model.to(device)
    model.train()
    for epoch in range(args.epochs):
        total_examples = total_loss = 0

        for batch in train_loader:
            optimizer.zero_grad()
            batch.to(device)
            out = model(batch.x_dict, batch.edge_index_dict)
            loss = F.cross_entropy(out, batch['connection'].y.float())
            loss.backward()
            optimizer.step()

            total_examples += batch_size
            total_loss += float(loss) * batch_size

        tqdm.write('EPOCH '+str(epoch)+' loss: '+ str(total_loss/total_examples))

    cic_val = CICdata(args.val_data)
    #cic_val.df = cic_val.df[:2000]
    print('\nprocessing validation data...\n')
    data_val = cic_val.process(n_rows=args.connections_graph)

    model.eval()
    count=0
    preds = []
    labels = []
    print('\npredicting on validation data...\n')
    for graph in tqdm(data_val, position=0, leave=True):
        graph.to(device)
        preds.append(model(graph.x_dict, graph.edge_index_dict).argmax(dim=1))
        labels.append(graph['connection'].y.argmax(dim=1))

    preds = torch.cat(preds)
    labels = torch.cat(labels)
    cr = classification_report(preds.cpu(), labels.cpu())
    print(cr)
    cr_df = pd.DataFrame(classification_report(preds.cpu(), labels.cpu(), output_dict=True)).transpose()

    os.makedirs(os.path.dirname(args.path_eval), exist_ok=True)
    with open(args.path_eval, 'w') as f:
        f.write('## Settings Training\n')
        f.write(json.dumps(vars(args)))
        f.write('\n## Evaluations results\n')
        f.write(cr_df.to_markdown())

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='train and evaluate Graph neural networks on network data')
    parser.add_argument('-td','--train-data', type=str, help='path of processed trainingsdata', default='data/train/week1_prep_train.pkl')
    parser.add_argument('-vd','--val-data', type=str, help='path of processed validation data', default='data/eval/week1_prep_val.pkl')
    parser.add_argument('-pe','--path-eval', type=str, help='path of evaluation results', default='runs/exp0.txt')

    parser.add_argument('-hc','--hidden-channels', type=int, help='number of hidden channels for algorithm', default=64)
    parser.add_argument('-hl','--hidden-layers', type=int, help='number of hidden layers for algorithm', default=2)
    parser.add_argument('-nh','--num-heads', type=int, help='number of heads for algorithm', default=4)
    parser.add_argument('-e','--epochs', type=int, help='number of epochs algorithm is trained', default=20)
    parser.add_argument('-cg','--connections-graph', type=int, help='number of network connections in a graph', default=200)

    arguments = parser.parse_args()
    main(arguments)


from queue import Queue
from collections import deque

class ACTrie:
    """Aho Corasick Trie"""

    def __init__(self):
        self.root = Node(output='')
        # self.q = Queue()
        self.q = deque()

    def _build(self, patterns):

        for w_i, word in enumerate(patterns):
            node = self.root
            for i, letter in enumerate(word, start=1):
                # output = (word, w_i) if i == len(word) else None
                output = word if i == len(word) else None
                node = node.append_letter(letter, output)

    def print(self, node):
        """"""
        print(node)
        for child in node.c.values():
            self.print(child)

    def _build_fails(self):
        """"""
        # root children to queue
        q = self.q
        for child in self.root.c.values():
            child.f = self.root
            # q.put(child)
            q.append(child)

        # while not q.empty():
        while len(q):
            # current = q.get()
            current = q.popleft()

            for letter, child in current.c.items():
                # q.put(child)
                q.append(child)

                # find a fail for child
                fail_node = current.f

                while True:
                    # fail_node has an appropriate letter
                    if letter in fail_node.c:
                        child.f = fail_node.c[letter]
                        child.o.extend(child.f.o)
                        break

                    # does not have letter
                    # if root
                    if fail_node.f is None:
                        child.f = fail_node
                        break
                    else:
                        # go to upper fail node
                        fail_node = fail_node.f

    def build(self, patterns):
        """"""
        self._build(patterns)
        self._build_fails()

    # fixme maybe as generator
    def find_matching(self, string):
        """"""
        # from collections import Counter
        # result = Counter()
        result = []
        current = self.root

        for letter in string:
            if letter in current.c:
                current = current.c[letter]
                result.extend(current.o)
                # result.update(current.o)

            # fixme here we need to check all fails up to root
            else:
                current = current.f
                while current is not None and letter not in current.c:
                    current = current.f
                # went up to root
                if current is None:
                    current = self.root
                    continue

                current = current.c[letter]
                result.extend(current.o)
                # result.update(current.o)

        return result
        # return set(result)
        # from collections import Counter
        # return Counter(result)

class Node:

    __slots__ = ('o', 'c', 'f')

    def __init__(self, output=None):

        self.o = []
        self.c = {}
        self.f = None

        if output:
            self.o.append(output)

    def __str__(self):
        return f'Node: ' \
               f'outputs: `{self.o}` ' \
               f'fail_node: {getattr(self.f, "letter", None)}'

    def append_letter(self, letter, output=None) -> 'Node':

        if letter in self.c:
            child = self.c[letter]
            if output:
                child.o.append(output)
        else:
            child = Node(output=output or None)
            self.c[letter] = child

        return child

if __name__ == '__main__':

    # words = ['asd', 'as', 'a', 'bdd']
    # words = ['c', 'cc', 'ccc', 'cccc']
    # words = []
    words = ['aab', 'aab']
    # words = ['c', 'dadac']
    # words = ['a', 'ab', 'bc', 'aab', 'aac', 'bd']

    trie = ACTrie()
    trie.build(patterns=words)
    trie.print(trie.root)

    # string = 'aaab'
    # string = 'abcabcabc'
    string = 'bcaab'

    matches = trie.find_matching(string)
    print(matches)


# Transitions class hold transitions
class transition:
    def __init__(self, start, end, regex):
        self.start = start
        self.end = end
        self.regex = regex

    # This function checks transition done or not.
    def isDone(self):
        if(len(self.regex) == 1):
            return True
        else:
            return False

    # Print transition prettier.
    def print_t(self):
        print (f'\tq{self.start} -> q{self.end} when {self.regex} comes.')

# NFA class
class formal_nfa:
    def __init__(self, regex):
        self.Q = 2
        self.transitions = []
        self.start = 0
        self.accept = [1]
        self.must_change_states = {}
        self.__find_transitions(0,1,regex)
        self.__deleteStartofStar()
        self.__delete_multiple()

    # Print NFA.
    def print_nfa(self):

        print("\n\n\nStates: ", end=" ")

        for i in range(self.Q):
            print(f'q{i}', end=" ")

        print("\nLanguage: All ASCII Chracters except \"+\", \"*\", \"(\", \")\"\n")

        print("Transitions: ")
        for a in self.transitions:
            a.print_t()

        print(f"\nStart state is q{self.start}")

        print(f"Accept state is q{self.accept[0]}\n\n")

    '''
    This function optimize changable states

    For Example:
        q2 must change to q1
        q1 must change to q3
        q4 must change to q5
        q6 must change to q1

    As you can see we must change "q1"s to "q3" on right side, because of row 2.

    __optimizeChangables function do this operation.
    '''

    def __delete_multiple(self):
        for i, t1 in enumerate(self.transitions):
            for t2 in self.transitions[i+1:]:
                if t1.start == t2.start and t1.end == t2.end and t1.regex == t2.regex:
                    t2.print_t()
                    self.transitions.remove(t2)

    def __optimizeChangables(self):
        # Find key by given value.
        def getKey(val):
            for key, value in self.must_change_states.items():
                 if val == value:
                     return key

        somethingChanged = True

        while(somethingChanged): # We must check all situations.

            somethingChanged = False

            for value in self.must_change_states.values():
                for key in self.must_change_states.keys():
                    if value == key:
                        tempValue = self.must_change_states.get(key)
                        tempKey = getKey(value)
                        self.must_change_states[tempKey] = tempValue
                        somethingChanged = True

    # This Function delete unnecessary states. (For better understanding check out Readme)
    def __deleteStartofStar(self):
        self.__optimizeChangables()

        for key, value in self.must_change_states.items():
            if key == self.start:
                self.start = value
            if key == self.accept[0]:
                self.accept[0] = value
            for t in self.transitions:
                if t.end == key:
                    t.end = value
                if t.start == key:
                    t.start = value

        self.__cleanStates()

    # This function takes n as input and decrease 1 states which greater than n
    # For example:
    # before  -  0 1 2 3 4 5 6
    #       minus_1_all_states_after(3)
    # after   -  0 1 2 3 4 5

    def __minus_1_all_states_after(self, n):
        for t in self.transitions:
            if t.start > n:
                t.start = t.start - 1
            if t.end > n:
                t.end = t.end - 1

        for key, value in self.must_change_states.items():
            if key > n:
                key = key - 1
            if value > n:
                value = value - 1

        if self.start > n:
            self.start = self.start - 1
        if self.accept[0] > n:
            self.accept[0] = self.accept[0] - 1

    def __cleanStates(self):
        self.Q = self.Q - len(self.must_change_states)

        for key in self.must_change_states:
            self.__minus_1_all_states_after(key)

    # This function check regex if there is "Union" operation it returns false else return true
    # and this meaning we can parse other operations.

    def __IsThereAnyUnion(self, regex):
        p = 0

        for element in regex:
            if(element == "("):
                p = p + 1
            elif(element == ")"):
                p = p - 1

            if (p == 0 and (element == "|")):
                return False

        return True

    # This function find "(" in regex if position of ")" is given.
    def __findBracketsStartPoint(self, regex, bracket):
        regex = regex[0:bracket]
        p = -1

        for i, element in enumerate(reversed(regex)):
            if(element == "("):
                p = p + 1
            elif(element == ")"):
                p = p - 1

            if (p == 0):
                return len(regex) - i

        return -1

    # This is recursive function which find next transition.

    def __find_transitions(self, start, end, regex):

        t = transition(start, end, regex)

        # Checking transition. If True we our t to add transitions
        if(t.isDone()):
            self.transitions.append(t)
        else:
            p = 0

            stack = []

            if(t.regex[0] == "(" and t.regex[-1] == ")"):
                for i, c in enumerate(t.regex):
                    if(c == "("):
                        stack.append(i)
                    elif(c == ")"):
                        if(i == len(t.regex)-1 and stack[-1] == 0):
                            t.regex = t.regex[1:-1]
                            break
                        stack.pop()
                    else:
                        continue

            for i, element in enumerate(t.regex):

                if(element == "("):
                    p = p + 1
                elif(element == ")"):
                    p = p - 1

                if(element == "|" and p == 0):
                    self.__find_transitions(t.start, t.end, t.regex[0:i])
                    self.__find_transitions(t.start, t.end, t.regex[i+1:])
                    break

                elif(i < len(regex) - 1 and self.__IsThereAnyUnion(t.regex)  and p == 0):
                    if(t.regex[i+1] not in ["|", "*"]):
                        b = self.Q
                        self.Q = self.Q + 1
                        self.__find_transitions(t.start, b , t.regex[0:i+1])
                        self.__find_transitions(b , t.end, t.regex[i+1:])

                        break

                elif(element == "*" and self.__IsThereAnyUnion(t.regex) and p == 0):

                    point = i

                    if(t.regex[i-1] == ")"):
                        point = self.__findBracketsStartPoint(t.regex, i-1)

                    if (t.start != t.end):
                        self.must_change_states[t.start] = t.end
                    self.__find_transitions(t.end, t.end, t.regex[point - 1: i])

                    if i != len(t.regex) - 1:
                        self.__find_transitions(t.start, t.end, t.regex[0:point-1] + t.regex[i+1:])

                    break


# origin : https://www.youtube.com/watch?v=mQGwjrStQgg

import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()

x_train = [1,2,3]
y_train = [1,2,3]

W = tf.Variable(tf.random_normal(shape=[1]), dtype=tf.float32)
b = tf.Variable(tf.random_normal(shape=[1]), dtype=tf.float32)

hypothesis = x_train * W + b
cost = tf.reduce_mean(tf.square(hypothesis - y_train))
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1)
train = optimizer.minimize(cost)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for step in range(100):
        sess.run(train)
        print(step, sess.run(cost), sess.run(W), sess.run(b))


""" Extract event structures from files ans answers for posing new questions """

import os
import sys

if os.name == 'nt':
    root_path = "/".join(os.path.realpath(__file__).split("\\")[:-2])
else:
    root_path = "/".join(os.path.realpath(__file__).split("/")[:-2])
if root_path not in sys.path:
    sys.path.append(root_path)

import logging
from datastructures.datatypes import EVENT_TAGS

logger = logging.getLogger(__name__)

def buildTriggerToEventIDIndex(trigger_dict, event_dict):
    """ Build dict from trigger name to Event ID from datstructures.datatypes.Event class """
    index = {}
    for event_id, event in event_dict.items():
        trigger_name = trigger_dict[event.arguments[event.name]].name.lower()
        if trigger_name not in index:
            index[trigger_name] = set()
        index[trigger_name].add(event.id)
    return index

def buildLabelToEventIDIndex(trigger_dict, event_dict):
    """ Build dict from trigger name to Event ID from datstructures.datatypes.Event class """
    index = {}
    for event_id, event in event_dict.items():
        trigger_label = trigger_dict[event.arguments[event.name]].class_label
        if trigger_label not in index:
            index[trigger_label] = set()
        index[trigger_label].add(event.id)
    return index

def buildEventToEventAsThemeIndex(event_dict):
    """ Build dict from Event to Event as theme argument from datstructures.datatypes.Event class """
    index = {}
    for event_id, event in event_dict.items():
        for argument, id in event.arguments.items():
            argument_name = argument
            while argument_name.endswith(tuple(["+", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"])):
                argument_name = argument_name[:-1]
            if argument_name == "Theme" and id.startswith("E"):
                if id not in index:
                    index[id] = set()
                index[id].add(event.id)
    return index

def extractProteinThemeOfEventPairs(proteins, event_triggers, events, predict=False):
    """ Extract Protein = themeOf => Event Trigger Relations,
    Ignoring equivalences for now!
    Parameters
    ----------
    proteins : dict
        dict of Protein objects
    event_triggers : dict
        dict of EventTrigger objects
    events : dict
        dict of Event objects
    predict : bool
        True if events are unknown and should be predicted. False otherwise

    Returns
    -------
    list
        List of tuples (question, subject, answers), where subject is [protein_name]
        and answers is [(event_label, EventTrigger] )
    int
        Number of answer entities
    """

    protein_trigger_pairs = {}
    number_new_answers = 0
    # Add all protein as questions, even those with no answers
    for id, protein in proteins.items():
        protein_trigger_pairs[protein.name] = ["Theme", protein.name, {}]  # "Theme" argument also denotes the "Participant" Argument for Pathway Events
    if predict is False:
        for event in events.values():
            for argument, id in event.arguments.items():
                if (argument.startswith("Theme") or argument.startswith("Participant")) and not id.startswith("E"):
                    event_trigger = event_triggers[event.arguments[event.name]]
                    protein = proteins[event.arguments[argument]].name
                    protein_trigger_pairs[protein][2][event_trigger.start_index] = (event_trigger.class_label, event_trigger)
                    number_new_answers += 1
    # tuples[0] protein_name, tuples[1] EventTrigger list
    protein_trigger_pairs = [("What are events of " + tuples[1] + "?", [tuples[1], tuples[0]],
                             [tuples[2][key] for key in sorted(tuples[2].keys())])
                             for tuples in protein_trigger_pairs.values()]
    return protein_trigger_pairs, number_new_answers

def extractEvents(proteins, triggers, events, prior_events, trigger_to_event_id_index, label_to_event_id_index, event_theme_to_event_index,
                  recursion_depth, question_type, predict=False):
    """ Extract events, Use class_label as priors instead of the triggers. For questions not including the trigger evidence
    Parameters
    ----------
    proteins : dict
        dict of Protein objects
    triggers : dict
        dict of EventTrigger objects
    events : dict
        dict of Event objects
    prior_events : list
        Previously found theme event pairs, however pubmed_id is already specified here
        [ {pubmed_id : [([subjects], [(label, label, start_index_word, end_index_word, star_index_token, end_index_token)])]} ]
    trigger_to_event_id_index : dict
        Label trigger name (lower) to Event ID dict
    label_to_event_id_index : dict
        Label trigger name (lower) to Event ID dict
    event_theme_to_event_index : dict
        Mapping of event ID which is theme to another event ID
    recursion_depth: int
        Number of recursion steps beginning from 0
    question_type : int
        0, if trigger question. 1, if event argument question
    predict : bool
        True if events are unknown and should be predicted. False otherwise

    Returns
    -------
    list
        List of tuples (question, subject, answers), where subject is [event_name, event_label, theme_protein]
        and answers is [(regulation_event_type, EventTrigger), ...]
    int
        Number of answer entities
    """

    entities = {**proteins, **triggers}
    event_arguments = {}  # Ask a question for each event tuple found in a previous step
    number_new_answers = 0

    trigger_id_to_event_id_index = {}
    for event_id, event in events.items():
        trigger_id = triggers[event.arguments[event.name]].id
        if trigger_id not in trigger_id_to_event_id_index:
            trigger_id_to_event_id_index[trigger_id] = set()
        trigger_id_to_event_id_index[trigger_id].add(event.id)

    for subject, answers in prior_events:
        if recursion_depth == 7:
            logger.info(subject)
            logger.info(answers)
        for evidence, label, _, _, _, _ in answers:
            list_of_prior_entities = []
            if label in EVENT_TAGS:
                list_of_prior_entities = [evidence, label] + list(subject)
            elif label not in EVENT_TAGS:
                # assert(len(list_of_prior_entities) >= 3) Assertion is only valid during training, during evaluation many things can happen
                list_of_prior_entities = list(subject[0:2]) + [evidence, label] + list(subject[2:])
            # Assertion when only triggers and starting_protein prevalent in the prior_event tuple
            # TODO: Change this when including event arguments into the prior_event_tuple
            assert(len(list_of_prior_entities) % 2 == 0)

            dict_key = label + "_" + label + "_" + "_".join(subject)
            current_event_ids = set()  # set of (current_event_id, root_event_id)
            matching_event_ids = set()  # set of root_event_ids
            matching = not predict  # True if predict is False. Otherwise do not try to match prior events and find subsequent answers to create training data.
            list_number = 0
            # logger.info(label)
            # logger.info(evidence)
            # logger.info(list_of_prior_entities)
            while list_number < len(list_of_prior_entities) and matching is True:
                # logger.info(list_number)
                new_event_ids = set()  # list of (new_event_id, root_event_id)
                entity = list_of_prior_entities[list_number]

                # Attention! Words are cased in the dicts but not in the prior_event tuples
                # Check if current event matches an event from the prior_event_dict
                if (list_number % 2 == 0) and (list_number == len(list_of_prior_entities) - 2):
                    matching = False
                    # Final protein theme
                    for event_ids in current_event_ids:
                        current_event_id = event_ids[0]
                        for current_argument_key, current_argument_value in events[current_event_id].arguments.items():
                            if current_argument_key.startswith(tuple(["Theme", "Participant"])) and current_argument_value.startswith("T"):
                                if entities[current_argument_value].name == entity:
                                    matching = True
                                    matching_event_ids.add(event_ids[1])
                elif list_number == 0:
                    # logger.info(entities)
                    # logger.info(events)
                    # logger.info(prior_events)
                    # logger.info(label_to_event_id_index)
                    # logger.info(entity)
                    # logger.info(list_of_prior_entities)
                    # Start of prior event, that is always an event trigger
                    matching = False
                    if entity in trigger_to_event_id_index:  # Sanity check due to edge cases like syntax errors as "ubiquitinationof" existing as triggers
                        new_event_ids = set([(event_id, event_id) for event_id in trigger_to_event_id_index[entity]])
                        if len(new_event_ids) != 0:
                            matching = True
                    elif entity in label_to_event_id_index:
                        new_event_ids = set([(event_id, event_id) for event_id in label_to_event_id_index[entity]])
                        if len(new_event_ids) != 0:
                            matching = True
                    current_event_ids = new_event_ids
                elif (list_number % 2 == 0) and (list_number < len(list_of_prior_entities) - 2):
                    matching = False
                    # Event trigger or event argument (both simple and nested possible)
                    for event_ids in current_event_ids:
                        current_event_id = event_ids[0]
                        for current_argument_key, current_argument_value in events[current_event_id].arguments.items():
                            # TODO Check correct handling of binding events and other stuff
                            argument_name = current_argument_key
                            while argument_name.endswith(tuple(["+", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"])):
                                argument_name = argument_name[:-1]
                            if argument_name == events[current_event_id].name:
                                continue
                            elif argument_name == list_of_prior_entities[list_number + 1]:
                                # Events with multiple themes, e.g., Bindings
                                if current_argument_value.startswith("T") and entities[current_argument_value].class_label in EVENT_TAGS \
                                        and entities[current_argument_value].class_label == entity:
                                    # New Event Label Argument
                                    matching = True
                                    new_event_ids.add(event_ids)
                                elif current_argument_value.startswith("T") and entities[current_argument_value].name == entity:
                                    # New Protein Argument
                                    matching = True
                                    new_event_ids.add(event_ids)
                                elif current_argument_value.startswith("E"):
                                    trigger_label = triggers[events[current_argument_value].arguments[events[current_argument_value].name]].class_label
                                    if trigger_label == entity:
                                        matching = True
                                        new_event_ids.add(event_ids)
                            elif current_argument_value.startswith("E"):  # nested event with another event as theme
                                trigger = triggers[events[current_argument_value].arguments[events[current_argument_value].name]]
                                if entity in [trigger.name, trigger.class_label] and trigger.class_label == list_of_prior_entities[list_number + 1]:
                                    new_event_ids.update(set([(new_event_id, event_ids[1]) for new_event_id in trigger_id_to_event_id_index[trigger.id]]))
                                    if len(new_event_ids) != 0:
                                        matching = True
                    if recursion_depth == 7:
                        logger.info(current_event_ids)
                        logger.info(list_number)
                    current_event_ids = new_event_ids

                list_number += 1

            if dict_key not in event_arguments:
                if label in EVENT_TAGS:
                    event_arguments[dict_key] = [label] + list_of_prior_entities[1:] + [{}]
                else:
                    event_arguments[dict_key] = list_of_prior_entities + [{}]
            # logger.info("Matching")
            # logger.info(matching)
            if matching:
                if recursion_depth == 7:
                    logger.info(subject)
                    logger.info(str(evidence) + " " + str(label))
                    logger.info(matching_event_ids)
                for matching_event_id in matching_event_ids:
                    if question_type == 0:
                        if matching_event_id in event_theme_to_event_index:
                            # if recursion_depth == 4:
                            #     logger.info(list_of_prior_entities)
                            #     logger.info(matching_event_id)
                            #     logger.info(event_theme_to_event_index[matching_event_id])
                            #     exit()
                            for id in event_theme_to_event_index[matching_event_id]:
                                nested_event = triggers[events[id].arguments[events[id].name]]
                                event_arguments[dict_key][-1][nested_event.start_index] = (nested_event.class_label, nested_event)
                                number_new_answers += 1
                    elif question_type == 1:
                        matching_event = events[matching_event_id]
                        for argument, id in matching_event.arguments.items():
                            # TODO Check correct handling of binding events and other stuff
                            argument_name = argument
                            while argument_name.endswith(tuple(["+", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"])):
                                argument_name = argument_name[:-1]

                            # Handle multiple binding/pathway arguments
                            if matching_event.name in ["Binding", "Pathway"] and argument_name in ["Theme", "Participant"]:
                                assert(id.startswith("T"))
                                # Last argument of list_of_prior_entities is Theme or Participant
                                if list_of_prior_entities[-2] != entities[id].name:  # further Theme or Participant
                                    assert(id.startswith("T"))
                                    protein_or_trigger_argument = entities[id]
                                    event_arguments[dict_key][-1][protein_or_trigger_argument.start_index] =\
                                        (argument_name, protein_or_trigger_argument)
                                    number_new_answers += 1

                            # Handle site arguments in bindings (only GENIA). Check that Theme Suffix and Site Suffix have the same number.
                            elif matching_event.name == "Binding" and argument_name == "Site":
                                theme_entity = list_of_prior_entities[-2]
                                site_belonging_to_current_theme = False
                                for theme_argument, theme_id in matching_event.arguments.items():
                                    theme_argument_name = theme_argument
                                    argument_name_temp = argument
                                    if theme_argument.startswith("Theme") and entities[theme_id].name == theme_entity:
                                        while True:
                                            if theme_argument_name[-1].isdigit() and argument_name_temp[-1].isdigit():
                                                if theme_argument_name[-1] == argument_name_temp[-1]:
                                                    theme_argument_name = theme_argument_name[:-1]
                                                    argument_name_temp = argument_name_temp[:-1]
                                                else:
                                                    break
                                            elif (not theme_argument_name[-1].isdigit()) and (not argument_name_temp[-1].isdigit()):
                                                site_belonging_to_current_theme = True
                                                break
                                            else:
                                                break
                                if site_belonging_to_current_theme is True:
                                    protein_or_trigger_argument = entities[id]
                                    event_arguments[dict_key][-1][protein_or_trigger_argument.start_index] =\
                                        (argument_name, protein_or_trigger_argument)
                                    number_new_answers += 1

                            # Default case
                            elif argument_name not in ["Theme", "Participant", matching_event.name]:
                                protein_or_trigger_argument = None
                                if id.startswith("T"):
                                    protein_or_trigger_argument = entities[matching_event.arguments[argument]]
                                else:  # id.startswith("E")
                                    temp_event_id = events[matching_event.arguments[argument]].id
                                    protein_or_trigger_argument =\
                                        triggers[events[temp_event_id].arguments[events[temp_event_id].name]]
                                event_arguments[dict_key][-1][protein_or_trigger_argument.start_index] =\
                                    (argument_name, protein_or_trigger_argument)
                                number_new_answers += 1
                # logger.info(event_arguments[dict_key])

    if recursion_depth == 7:
        logger.info(event_arguments)
        # exit()
    question_and_answers = []
    for tuples in event_arguments.values():
        question_type_string = "events" if question_type == 0 else "arguments"
        question = "What are " + question_type_string + " "
        for i, question_entity in enumerate(tuples[:-1]):
            # TODO: Revise questions when excluding triggers from the question
            assert(len(tuples[:-1]) % 2 == 0)
            if i == len(tuples[:-1]) - 2:
                question = question + "of " + question_entity + "?"
            elif i % 2 == 0:
                if tuples[:-1][i + 1] in EVENT_TAGS:
                    question = question + "of the " + question_entity + " "
                else:
                    question = question + "with the " + tuples[:-1][i + 1] + " " + question_entity + " "
        question_and_answers.append([question, tuples[:-1], [tuples[-1][key] for key in sorted(tuples[-1].keys())]])

    # logger.info(event_arguments.items())
    # logger.info(question_and_answers)
    # exit()

    return question_and_answers, number_new_answers


def contracting(l):

  result = True
  for i in range(len(l)-1):
    if i == 0:
      diff = abs(l[i] - l[i+1])
    else:
      adjDiff = abs(l[i] - l[i+1])
      if adjDiff >= diff:
        result = False
        break

  return(result)

def counthv(l):

  (hc,vc) = (0,0)
  for i in range(1,len(l)-1):
    if (l[i] > l[i-1]) and (l[i] > l[i+1]):
      hc += 1
    elif (l[i] < l[i-1]) and (l[i] < l[i+1]):
      vc +=1

  return([hc,vc])

def leftrotate(m):

  n = len(m)
  rotatedMatrix = []
  for i in range(n):
    tempList = []
    for j in range(n):
      tempList.append(m[j][n-(i+1)])
    rotatedMatrix.append(tempList)

  return(rotatedMatrix)


from folium import Map
from geo import Geopoint

lat = float("32.98220")
long = float("-96.53060")

antipode_lat = lat.__mul__(int("-1"))

antipode_long = long.__add__(float("180"))

if long.__lt__(float("0")):
    antipode_long = long.__add__(float("180"))
elif long.__eq__(float("0")):
    antipode_long = float("180")
else:
    antipode_long = long.__sub__(float("180"))

print(antipode_lat, antipode_long)

location = list((antipode_lat, antipode_long))

# mymap = Map(location)
# mymap.save(str("antipode_nathy.html"))

g = Geopoint(2, 4)

print(g.closest_parallel())


__version__ = "0.1.0"

import platform

import httpx
from fastapi import FastAPI
from fastapi.responses import PlainTextResponse

app = FastAPI()

@app.get("/rate/{base}")
async def get_rate(base: str, target: str):
    return {
        "source": base.upper(),
        "target": target.upper(),
        "rate": 0.752492,
        "node": platform.node(),
    }

@app.get("/discover")
async def discover():
    resp = httpx.get("http://quotes.service.consul/hostname")
    other_node = resp.text
    return {"node": platform.node(), "other_node": other_node}

@app.get("/hostname", response_class=PlainTextResponse)
async def hostname():
    return platform.node()

@app.get("/health")
async def health():
    return {"status": "ok"}


from magicCards import magicCard
from pygame import display
from Decks import *
import pygame

from Cards import Card

class Player:
    def __init__(self, name, deck, image, x, y):
        self.name = name
        self.health = 30
        self.mana = 0
        self.turn_mana = 0
        self.max_mana = 10
        self.hand = []
        self.field = []
        self.deck = deck
        self.cemetery = []
        self.image = pygame.image.load(image)
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y

    def take_damage(self, card):
        self.health -= card.attack

    def pickUp(self, screen, image, rectt, player2, background):

        self.hand.append(self.deck[0])
        del self.deck[0]
        self.display_init(screen, image, rectt, player2, background)

    def turn_message(self):
        print("C'est à votre tour, ", self.name,
              " ! Il vous reste ", self.health, " PV")

    def initiate_mana(self, screen, image, rectt, player2, background):
        if self.turn_mana < self.max_mana:
            self.turn_mana += 1
        self.mana = self.turn_mana
        self.display_init(screen, image, rectt, player2, background)

    def wake_cards(self):
        for element in self.field:
            element.use = 1

    def phase_invoke_cards(self, screen, background, image, rectt, player2):
        arret = 0
        on = 0
        i = 0

        print(
            "Voici les serviteurs présents dans votre main. Montant de mana : ", self.mana)
        while arret != 1:

            for e in pygame.event.get():
                if e.type == pygame.MOUSEBUTTONDOWN:
                    mx, my = pygame.mouse.get_pos()
                    print("Coordone X" + str(mx))
                    print("Coordone y" + str(my))
                    self.display_init(
                        screen, image, rectt, player2, background)
                    test = 0

                    for element in self.hand:
                        test += 1
                        if(mx+50 > element.rect.x > mx-50) and (my+50 > element.rect.y > my-50):

                            print("-(", i, ")", end=' ')
                            element.print_card()
                            card = element
                            print("test : " + str(test))

                            if on == 0:

                                print("tessssst" + str(test))
                                rect = pygame.Surface((175, 235))
                                rect.set_alpha(60)
                                rect.fill((255, 255, 255))
                                screen.blit(
                                    rect, (element.rect.x, element.rect.y))

                                on = 1

                                pygame.display.flip()

                            elif(mx+50 > element.rect.x > mx-50) and (my+50 > element.rect.y > my-50):

                                screen.blit(
                                    rect, (element.rect.x, element.rect.y))
                                pygame.display.flip()

                    if (my > 245 and my < 700 and on == 1)   :

                        print("name , cost : " +str(card.name) , str(card.cost))

                        on = 0
                        if self.mana >= card.cost:

                            if("magicCard" == type(card).__name__):

                                on =0
                                if(card.dmg_add ==0):
                                    print("Attack")

                                    for element in player2.field:
                                        if(mx+100 > element.rect.x > mx-100) and (my+100 > element.rect.y > my-100):
                                            if on == 0:

                                                card.magic_attempt(player2,element)
                                                self.mana -= card.cost
                                                del self.hand[test-2]
                                            if(mx+100 > player2.rect.x > mx-100) and (my+100 > player2.rect.y > my-100) and on == 0 and card.dmg_add == 0:
                                                card.magic_attempt(player2,player2)
                                                del self.hand[test-2]

                                        else:
                                            print("Selectionner un footballer")
                                    self.display_init(
                                        screen, image, rectt, player2, background)

                                else:
                                    for element in self.field:
                                        if(mx+100 > element.rect.x > mx-100) and (my+100 > element.rect.y > my-100):
                                            if on == 0:
                                                card.magic_attempt(player2,element)
                                                self.mana -= card.cost

                                                del self.hand[test-1]
                                            if(mx+100 > self.rect.x > mx-100) and (my+100 > self.rect.y > my-100) and on == 0 and self.dmg_add == 0:
                                                card.magic_attempt(player2,player2)
                                                del self.hand[test-1]

                                        else:
                                            print("Selectionner un footballer")

                                    self.display_init(
                                        screen, image, rectt, player2, background)

                            else:
                                self.mana -= card.cost
                                self.field.append(card)
                                print("Vous avez posé ", card.name)

                                print(str(test))
                                del self.hand[test-1]
                                test = 0

                                pygame.display.flip()
                                self.display_init(
                                    screen, image, rectt, player2, background)
                        else:
                            print("Pas assez de mana ")

                    if(1550 > mx > 1350):
                        if(550 > my > 450):
                            arret = 1
                            break

    def phase_attack(self, screen, image, rectt, player2, background):
        print("Phase d'attaque !")
        on = 0
        arret = 0
        while arret != 1:
            for e in pygame.event.get():
                if e.type == pygame.MOUSEBUTTONDOWN:
                    mx, my = pygame.mouse.get_pos()
                    print("Coordone X" + str(mx))
                    print("Coordone Y" + str(my))

                    for element in self.field:
                        if(mx+100 > element.rect.x > mx-100) and (my+100 > element.rect.y > my-100):

                            rect = pygame.Surface(
                                (175, 235))
                            rect.set_alpha(60)
                            rect.fill((255, 255, 255))
                            element.print_card()

                            screen.blit(
                                rect, (element.rect.x, element.rect.y))
                            on = 1
                            cardA = element
                            pygame.display.flip()

                    if(1550 > mx > 1350):
                        if(550 > my > 450):
                            arret = 1
                            break

                    for element in player2.field:
                        if(mx+100 > element.rect.x > mx-100) and (my+100 > element.rect.y > my-100):
                            if on == 1:
                                if cardA.use == 1:
                                    cardA.fight_attempt(player2, element)

                                    print(str(cardA.health))
                                    print(str(element.health))

                                    self.display_init(
                                        screen, image, rectt, player2, background)

                                else:
                                    print("Le footballeur est sur le banc")

                            else:
                                print("Selectionner un footballer avant")
                        else:
                            print("Le footballeur est sur le banc")

                    if(mx+50 > player2.rect.x > mx-50) and (my+50 > player2.rect.y > my-50):

                        if cardA.use == 1:
                            player2.health -= cardA.attack
                            cardA.use = 0
                            self.display_init(
                                screen, image, rectt, player2, background)

                            '''self.clean_after()'''

                        else:
                            print("Votre joueur est sur le Banc ")

    def clean_after(self):
        print("Morts ", self.name, " : ")
        for element in self.field:
            if element.health == 0:
                print("-", element.name)
        i = 0
        while i < len(self.field):
            if self.deck[i].health == 0:
                self.cemetery.append(self.deck[i])
                del self.deck[i]
                while self.deck[i].health == 0:
                    self.cemetery.append(self.deck[i])
                    del self.deck[i]
            i += 1

    def display_init(self, screen, image, rectt, player2, background):

        screen.blit(background, (0, 0))
        screen.blit(image, rectt)

        screen.blit(player2.image, player2.rect)

        police = pygame.font.SysFont("monospace", 17)

        image_health = police.render(
            str(self.health) + " / 30", 1, (255, 255, 255))

        image_health2 = police.render(
            str(player2.health) + " / 30", 1, (255, 255, 255))

        image_mana = police.render(
            str(self.mana) + " / 10", 1, (255, 255, 255))
        image_mana2 = police.render(
            str(player2.mana) + " / 10", 1, (255, 255, 255))
        if(self.name == "Cowboy Mbappé"):
            screen.blit(image_mana, (1185, 980))
            screen.blit(image_mana2, (1145, 62))
        else:
            screen.blit(image_mana2, (1185, 980))
            screen.blit(image_mana, (1145, 62))

        screen.blit(image_health, (self.rect.x, self.rect.y))

        screen.blit(image_health2, (player2.rect.x, player2.rect.y))

        if(self.name == "Cowboy Mbappé"):
            for i in range(len(self.field)):
                if self.field[i].health <= 0:
                    del self.field[i]
                else:
                    self.field[i].image = pygame.transform.scale(
                        self.field[i].image, (160, 220))
                    self.field[i].rect.x = 600 + (i * 175)
                    self.field[i].rect.y = 525

                    screen.blit(
                        self.field[i].image, (self.field[i].rect.x, 525))

            for i in range(len(player2.field)):
                if player2.field[i].health <= 0:
                    del player2.field[i]
                else:
                    player2.field[i].image = pygame.transform.scale(
                        player2.field[i].image, (160, 220))
                    player2.field[i].rect.x = 600 + (i * 175)
                    player2.field[i].rect.y = 250

                    screen.blit(
                        player2.field[i].image, (player2.field[i].rect.x, player2.field[i].rect.y))

            for i in range(len(self.hand)):

                self.hand[i].image = pygame.transform.scale(
                    self.hand[i].image, (175, 235))
                self.hand[i].rect.x = (i * 175)
                screen.blit(
                    self.hand[i].image, self.hand[i].rect)
            for i in range(len(player2.hand)):

                player2.hand[i].image = pygame.transform.scale(
                    player2.hand[i].image, (175, 235))
                player2.hand[i].rect.x = (i * 175)
                player2.hand[i].rect.y = 50

                screen.blit(
                    player2.hand[i].image, player2.hand[i].rect)
        else:

            for i in range(len(player2.field)):
                if player2.field[i].health <= 0:
                    del player2.field[i]
                else:
                    player2.field[i].image = pygame.transform.scale(
                        player2.field[i].image, (160, 220))
                    player2.field[i].rect.x = 600 + (i * 175)
                    player2.field[i].rect.y = 525

                    screen.blit(
                        player2.field[i].image, (player2.field[i].rect.x, 525))

            for i in range(len(self.field)):
                if self.field[i].health <= 0:
                    del self.field[i]
                else:
                    self.field[i].image = pygame.transform.scale(
                        self.field[i].image, (160, 220))
                    self.field[i].rect.x = 600 + (i * 175)
                    self.field[i].rect.y = 250
                    screen.blit(
                        self.field[i].image, (self.field[i].rect.x, 250))

            for i in range(len(player2.hand)):

                player2.hand[i].image = pygame.transform.scale(
                    player2.hand[i].image, (175, 235))
                player2.hand[i].rect.x = (i * 175)
                screen.blit(
                    player2.hand[i].image, player2.hand[i].rect)
            for i in range(len(self.hand)):

                self.hand[i].image = pygame.transform.scale(
                    self.hand[i].image, (175, 235))
                self.hand[i].rect.x = (i * 175)
                self.hand[i].rect.y = 50

                screen.blit(
                    self.hand[i].image, self.hand[i].rect)

        pygame.display.flip()

    def player_turn(self, player2, screen, background):

        self.turn_message()
        print("Terrain adverse : ")
        for element in player2.field:
            element.print_card(False)
        print("------------------------------------------------")
        print("Votre terrain")
        for element in self.field:
            element.print_card(False)
        print("------------------------------------------------")
        self.wake_cards()
        self.pickUp(screen, self.image, self.rect, player2, background)
        self.initiate_mana(screen, self.image, self.rect, player2, background)
        self.phase_invoke_cards(
            screen, background, self.image, self.rect, player2)
        self.phase_attack(screen, self.image, self.rect, player2, background)


from collections import deque

# 입력받기
N, M, K, X = map(int, input().split(' '))

road = [[] for _ in range(N+1)]

for i in range(M):
    n, m = map(int, input().split(' '))
    road[n].append(m)

# BFS 메서드 정의
def bfs(road, start, visited):
    # 큐(Queue) 구현을 위해 deque 라이브러리 사용
    queue = deque([start])
    # 현재 노드를 방문 처리
    visited[start] = 0
    while queue:
        # 큐에서 하나의 원소를 뽑아 출력
        now_node = queue.popleft()
        # 해당 원소와 연결된, 아직 방문하지 않은 원소들을 큐에 삽입
        for next_node in road[now_node]:
            if visited[next_node] == -1:
                queue.append(next_node)
                visited[next_node] = visited[now_node] + 1

# 각 노드가 방문된 정보를 리스트 자료형으로 표현(1차원 리스트)
visited = [-1] * (N + 1)

# 정의된 BFS 함수 호출
bfs(road, X, visited)

# 최단 거리가 정확히 K인 모든 도시들의 번호를 출력
if K not in visited : print(-1)
else :
    number = 0
    for v in visited :
        if v == K :
            print(number)
        number += 1


import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, LabelEncoder

def load_data(file_path):
    """
    Load the dataset from a CSV file.

    Args:
        file_path (str): Path to the CSV file.

    Returns:
        pandas.DataFrame: Loaded dataset.
    """
    data = pd.read_csv(file_path)
    return data

def preprocess_data(data):
    """
    Perform preprocessing on the dataset.

    Args:
        data (pandas.DataFrame): Input dataset.

    Returns:
        tuple: Tuple containing preprocessed features and target variables.
    """
    # convert `Neighborhood` into numeric
    le = LabelEncoder()
    data["Neighborhood"] = le.fit_transform(data["Neighborhood"])

    # Split features and target variable
    X = data.drop('Price', axis=1)
    y = data['Price']

    # Perform train-test split
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

    # Standardize features using StandardScaler
    scaler = StandardScaler()
    X_train_scaled = scaler.fit_transform(X_train)
    X_test_scaled = scaler.transform(X_test)

    return X_train_scaled, X_test_scaled, y_train, y_test


import sys
sys.stdin=open("input.txt", "rt")

n1=int(input())
num1=list(map(int,input().split()))
n2=int(input())
num2=list(map(int,input().split()))

ans=[]
a=0
b=0

for _ in range(n1+n2):
    if num1[a]<num2[b]:
        ans.append(num1[a])
        a+=1
    else:
        ans.append(num2[b])
        b+=1
    if a==n1 or b==n2:
        break

if a==n1:
    ans=ans+num2[b:n2]
else:
    ans=ans+num1[a:n1]

for i in ans:
    print(i,end=' ')

python algorithm 문제풀이/sec 3/4. 두 리스트 합치기.py

4. 두 리스트 합치기.py


class UndergroundSystem:

    def __init__(self):
        self.complete = {}
        self.chkin = {}

    def checkIn(self, id: int, stationName: str, t: int) -> None:
        self.chkin[id] = (stationName, t)

    def checkOut(self, id: int, stationName: str, t: int) -> None:
        if id in self.chkin:
            inat = self.chkin[id]
            complete_key = (inat[0],stationName)
            if complete_key in self.complete:
                cur_val = self.complete[complete_key]
                new_val = (cur_val[0]+t-inat[1], cur_val[1]+1)
            else:
                new_val = (t-inat[1],1)
            self.complete[complete_key] = new_val

    def getAverageTime(self, startStation: str, endStation: str) -> float:
        key = (startStation, endStation)
        cur_val = self.complete[key]
        return cur_val[0]/cur_val[1]

# Your UndergroundSystem object will be instantiated and called as such:
# obj = UndergroundSystem()
# obj.checkIn(id,stationName,t)
# obj.checkOut(id,stationName,t)
# param_3 = obj.getAverageTime(startStation,endStation)


#!/usr/bin/env python3
"""
    Recurrent Neural Networks
"""
import numpy as np

def deep_rnn(rnn_cells, X, h_0):
    """ performs forward propagation for a deep RNN
        rnn_cells is a list of instances of length l for forward propagation
        X is the data to be used, ndarray (t, m, i)
            t is the maximum number of time steps
            m is the batch size
            i is the dimensionality of the data
        h_0 is the initial hidden state, ndarray (l, m, h)
            h is the dimensionality of the hidden state
        Returns: H, Y
            H ndarray containing all of the hidden states
            Y ndarray containing all of the outputs
    """
    # print("xxxx", X.shape)
    t, m, i = X.shape
    l, m, h = h_0.shape
    H = np.zeros((t + 1, l, m, h))
    # H[-1] = np.zeros(h)
    Y = np.zeros((t, i))
    Y = []
    h_next = h_0
    for ti in range(t):
        # print('ti', ti)
        for l in range(len(rnn_cells)):
            # print('l', l)
            x = X[ti] if not l else H[ti + 1, l - 1]
            H[ti + 1, l], y = rnn_cells[l].forward(h_next[l], x)
            # print(H[ti + 1])
            # print('yyy', y.shape)
        Y.append(y)
        h_next = H[ti + 1]
    # print(Y)
    # print('yshape', np.array(Y).shape)
    # print('hshape', H.shape)
    return H, np.array(Y)


import os
import numpy as np
import raisimpy as raisim
import time

raisim.World.set_license_file(os.path.dirname(os.path.abspath(__file__)) + "/../../rsc/activation.raisim")
quadcopter_urdf_file = os.path.dirname(os.path.abspath(__file__)) + "/../../rsc/ITM-quadcopter/urdf/ITM-quadcopter.urdf"

world = raisim.World()
world.set_time_step(0.001)
server = raisim.RaisimServer(world)
ground = world.add_ground()

quadcopter = world.add_articulated_system(quadcopter_urdf_file)
quadcopter.set_name("ITM-quadcopter")
quadcopter_nominal_joint_config = np.array([0, 0, 0.1433, 1.0, 0.0, 0.0, 0.0, 0, 0, 0, 0])
quadcopter.set_generalized_coordinates(quadcopter_nominal_joint_config)

server.launch_server(8080)

time.sleep(2)
world.integrate1()

print(quadcopter.get_mass_matrix())

for i in range(5000000):
    world.integrate()

server.kill_server()


class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

class LinkedList:
    def __init__(self, value):
        self.head = Node(value)

    def append(self, value):
        cur = self.head
        while cur.next is not None:
            cur = cur.next
        cur.next = Node(value)

#링크드리스트 -> 끝을 알 수 없음
#1방법-전체의 길이를 알아낸 다음에 알아낸 길이 만큼만 -k만큼 하면 뒤에서k만큼 이동가능
    #->1.linkedlist길이 전부 알아내기 O(N) 2.그 길이에서 k만큼 뺀 길이 만큼 이동 O(N-K)

#2방법
    #1.노드를 두개 잡는다
    #2.한 노드를 다른 노드보다 k만큼 떨어지게 한다.
    #3.그리고 계속 한 칸씩 같이 이동한다.
    #4.만약 더 빠른 노드가 끝에 도달했다면
    #느린 노드는 끝에서 k만큼 떨어진 노드가 되므로 바로 반환하자 O(N)빠른노드 O(N-k)느린노드

    #->시간복잡도의 연산량이 같음
    def get_kth_node_from_last(self, k):
        slow = self.head
        fast = self.head

        for i in range(k):
            fast = fast.next #k만큼 앞으로 가도록 한다.

        while fast is not None: #끝까지 이동
            fast = fast.next
            slow = slow.next

        return slow

    # def get_kth_node_from_last(self, k):
    #     length = 1  # 시작 노드의 길이를 세기 위해 1부터 시작합니다
    #     cur = self.head
    #
    #     while cur.next is not None:  # cur을 끝까지 이동시킴
    #         cur = cur.next
    #         length += 1
    #     end_length = length - k  # 끝까지 이동시킨 후 k만큼 떨어진 곳
    #     cur = self.head
    #     for i in range(end_length):
    #         cur = cur.next
    #     return cur

linked_list = LinkedList(6)
linked_list.append(7)
linked_list.append(8)

print(linked_list.get_kth_node_from_last(2).data)  # 7이 나와야 합니다!


from flask import Response, abort
from flask_restful import Resource, request
from flasgger import swag_from
from flask_jwt_extended import jwt_required, get_jwt_identity

import json

from app.models.account import AccountModel
from app.models.boast import BoastModel
from app.docs.boast import *

class Boast(Resource):
    @swag_from(BOAST_GET)
    @jwt_required
    def get(self):
        """
        자랑 글 리스트 불러오기
        """
        boasts = BoastModel.objects()

        if not boasts.first():
            return Response('', 204)

        response = [{
            'id': str(boast.id),
            'date': str(boast.date)[:10],
            'title': boast.title,
            'author_id': boast.author.id,
            'author_nickname': boast.author.nickname,
            'content': boast.content
        } for boast in boasts]

        return Response(json.dumps(response, ensure_ascii=False), 200, content_type='application/json; charset=utf8')

    @swag_from(BOAST_POST)
    @jwt_required
    def post(self):
        """
        자랑 글 작성
        """
        user = AccountModel.objects(id=get_jwt_identity()).first()
        if not user:
            abort(403)

        rq = request.form
        if len(rq['title']) < 5:
            return Response('', 205)

        boast = BoastModel(
            title=rq['title'],
            author=user,
            content=rq['content'],
        ).save()

        return Response(str(boast.id), 201)

    @swag_from(BOAST_DELETE)
    @jwt_required
    def delete(self):
        """
        자랑 글 삭제
        """
        user = AccountModel.objects(id=get_jwt_identity()).first()
        if not user:
            abort(403)
        id = request.form['id']

        boast = BoastModel.objects(id=id).first()
        if boast.author.id != user.id:
            abort(403)

        boast.delete()

        return Response('', 201)


from enum import Enum

from qtpynodeeditor import FlowScene, PortType

from qtpy.QtCore import QPointF

from ies import MixMethod, LightDirection

from nodes import (PointlightNode,
                   SpotlightNode,
                   NoiseNode,
                   MixNode,
                   DisplayNode)

class Preset(Enum):
    EMPTY = "Empty"
    SPOTLIGHT = "Spotlight"
    LAMPSHADE = "Lamp Shade"
    # FLASHLIGHT = "Flash Light"

def loadPreset(scene: FlowScene, preset: Preset = Preset.EMPTY):
    scene.clear_scene()

    if preset is Preset.EMPTY:
        displayNode = scene.create_node(DisplayNode)
        displayNode.position += QPointF(2000, 500)

    elif preset is Preset.SPOTLIGHT:
        spotlight = scene.create_node(SpotlightNode)
        spotlight.position += QPointF(500, 100)

        noise = scene.create_node(NoiseNode)
        noise.position += QPointF(500, 700)

        mix = scene.create_node(MixNode)
        mix.position += QPointF(1000, 300)
        mix.model.setMixMethod(MixMethod.MULTIPLY)

        display = scene.create_node(DisplayNode)
        display.position += QPointF(1500, 100)

        scene.create_connection(spotlight[PortType.output][0],
                                mix[PortType.input][0])
        scene.create_connection(noise[PortType.output][0],
                                mix[PortType.input][1])
        scene.create_connection(mix[PortType.output][0],
                                display[PortType.input][0])

    elif preset is Preset.LAMPSHADE:
        spotlightUp = scene.create_node(SpotlightNode)
        spotlightUp.position += QPointF(500, 100)
        spotlightUp.model.setLightDiretion(LightDirection.UP)
        spotlightUp.model.setAngle(60)

        spotlightDown = scene.create_node(SpotlightNode)
        spotlightDown.position += QPointF(500, 700)
        spotlightDown.model.setLightDiretion(LightDirection.DOWN)
        spotlightDown.model.setAngle(60)

        spotMix = scene.create_node(MixNode)
        spotMix.position += QPointF(1000, 300)
        spotMix.model.setMixMethod(MixMethod.MAX)

        pointlight = scene.create_node(PointlightNode)
        pointlight.position += QPointF(1000, 800)
        pointlight.model.setIntensity(20)

        pointMix = scene.create_node(MixNode)
        pointMix.position += QPointF(1500, 300)
        pointMix.model.setMixMethod(MixMethod.MAX)

        display = scene.create_node(DisplayNode)
        display.position += QPointF(2000, 319)
        display.model.setLightPositionZ(0)

        scene.create_connection(spotlightDown[PortType.output][0],
                                spotMix[PortType.input][1])
        scene.create_connection(spotlightUp[PortType.output][0],
                                spotMix[PortType.input][0])
        scene.create_connection(spotMix[PortType.output][0],
                                pointMix[PortType.input][0])
        scene.create_connection(pointlight[PortType.output][0],
                                pointMix[PortType.input][1])
        scene.create_connection(pointMix[PortType.output][0],
                                display[PortType.input][0])

    # elif preset is Preset.FLASHLIGHT:
    #     spotlight = scene.create_node(SpotlightNode)
    #     spotlight.position += QPointF(500, 100)
    #     spotlight.model.setLightDiretion(LightDirection.UP)
    #     spotlight.model.setAngle(30)
    #
    #     noise = scene.create_node(NoiseNode)
    #     noise.position += QPointF(500, 700)
    #
    #     mix = scene.create_node(MixNode)
    #     mix.position += QPointF(1000, 300)
    #     mix.model.setMixMethod(MixMethod.MULTIPLY)
    #
    #     display = scene.create_node(DisplayNode)
    #     display.position += QPointF(1500, 100)
    #     display.model.setLightPositionZ(0)
    #     display.model.setLightPositionY(60)
    #     display.model.setLightRotationX(-90)
    #
    #     scene.create_connection(spotlight[PortType.output][0],
    #                             mix[PortType.input][0])
    #     scene.create_connection(noise[PortType.output][0],
    #                             mix[PortType.input][1])
    #     scene.create_connection(mix[PortType.output][0],
    #                             display[PortType.input][0])


import json
import time
import traceback
from collections import namedtuple
from io import BytesIO

import discord
import timeago as timesince

def get(file):
    try:
        with open(file, encoding="utf8") as data:
            return json.load(
                data, object_hook=lambda d: namedtuple("X", d.keys())(*d.values())
            )
    except AttributeError:
        raise AttributeError("Unknown argument")
    except FileNotFoundError:
        raise FileNotFoundError("JSON file wasn't found")

def traceback_maker(err, advance: bool = True):
    _traceback = "".join(traceback.format_tb(err.__traceback__))
    error = ("```py\n{1}{0}: {2}\n```").format(type(err).__name__, _traceback, err)
    return error if advance else f"{type(err).__name__}: {err}"

def timetext(name):
    return f"{name}_{int(time.time())}.txt"

def timeago(target):
    return timesince.format(target)

def date(target, clock=True):
    if clock is False:
        return target.strftime("%d %B %Y")
    return target.strftime("%d %B %Y, %H:%M")

def responsible(target, reason):
    responsible = f"[ {target} ]"
    if reason is None:
        return f"{responsible} no reason given..."
    return f"{responsible} {reason}"

def actionmessage(case, mass=False):
    output = f"**{case}** the user"

    if mass is True:
        output = f"**{case}** the IDs/Users"

    return f"✅ Successfully {output}"

async def prettyResults(
    ctx, filename: str = "Results", resultmsg: str = "Here's the results:", loop=None
):
    if not loop:
        return await ctx.send("The result was empty...")

    pretty = "\r\n".join(
        [f"[{str(num).zfill(2)}] {data}" for num, data in enumerate(loop, start=1)]
    )

    if len(loop) < 15:
        return await ctx.send(f"{resultmsg}```ini\n{pretty}```")

    data = BytesIO(pretty.encode("utf-8"))
    await ctx.send(
        content=resultmsg, file=discord.File(data, filename=timetext(filename.title()))
    )


#! /usr/bin/env python3
from .sub_singleton import SubjuGatorMission

SIDE_LENGTH = 1  # meters
SPEED_LIMIT = 0.2  # m/s

class Square(SubjuGatorMission):
    async def run(self, args):
        center = self.move().forward(0).zero_roll_and_pitch()
        for i in range(4):
            forward = self.move().forward(SIDE_LENGTH).zero_roll_and_pitch()
            right = forward.right(SIDE_LENGTH).zero_roll_and_pitch()

            await self.go(forward, speed=SPEED_LIMIT)
            await self.go(right, speed=SPEED_LIMIT)
            await self.go(forward, speed=SPEED_LIMIT)
            await self.go(center, speed=SPEED_LIMIT)
            center = center.yaw_right_deg(90)
            await self.go(center, speed=SPEED_LIMIT)

        print("Done!")


import os

from prefect.deployments import Deployment
from prefect.filesystems import GitHub
from prefect.infrastructure.docker import DockerContainer
from prefect.orion.schemas.schedules import CronSchedule

github_block = GitHub.load("pwc-github-storage-block")
docker_container_block = DockerContainer.load("pwc-datalake-infra-block")

deployment = Deployment(
    name="pwc-to-gcs-deployment",
    flow_name="pwc-upload-to-gcs-flow",
    parameters={
        "base_url": "https://production-media.paperswithcode.com/about/",
        "files": ["papers-with-abstracts", "links-between-papers-and-code", "datasets"],
        "gcs_block_name": "pwc-gcs-block",
        "ignore_download_if_exists": False,
        "output_dir": "./data",
    },
    schedule=(CronSchedule(cron="0 0 * * mon", timezone=os.getenv("timezone"))),
    storage=github_block,
    path="datalake/",
    entrypoint="datalake/etl_web_to_gcs.py:main_flow",
    infrastructure=docker_container_block,
)

if __name__ == "__main__":
    deployment.apply()


import functools
import string

f = open("puzzle_input.txt", "r")
puzzle_input = f.read().split("\n")

priority_sum = 0
team_size = 3
values_dict = { item:value for value,item in enumerate(string.ascii_letters, 1) }

for idx in range(0, len(puzzle_input), team_size):

    elf_team = [puzzle_input[idx+i] for i in range(team_size)]
    team_badge = functools.reduce(lambda x,y: set(x) & set(y), elf_team).pop()
    priority_sum += values_dict[team_badge]

print(priority_sum) # 2488


import inspect

from django.core.management import BaseCommand

from corehq.extensions import extension_manager

class Command(BaseCommand):
    help = "List all defined extension points."

    def handle(self, *args, **options):
        title = "CommCare Extension Points\n"
        print("\n" + title + "=" * len(title) + "\n")
        for name, point in extension_manager.registry.items():
            func = point.definition_function
            header = f"{func.__module__}.{func.__name__}\n"
            print(header + "-" * len(header) + "\n")
            print(inspect.getdoc(point.definition_function))
            print("\nImplementations:\n")
            for extension in point.extensions:
                callable = extension.callable
                print(f"    * {callable.__module__}.{callable.__name__}")
            print("\n")


# Dynamic Programming 2
# Pass

"""
두 번째 DP 풀이 시도.

첫 번쨰 DP에서 중복 체크를 할 때 시간 초과가 나는 것을 보고 이것을 어떻게 처리할 지 고민했습니다.
그리고 생각 끝에 처음부터 중복을 없애주는 방법을 생각해냈습니다.

배점에서 최댓값이 되는 점수는 모든 배점을 합한 값입니다.
따라서 산출 가능한 점수의 범위는 "0 ~ 모든 배점의 합"이 됩니다.

그렇다면
1. "모든 배점의 합" 만큼의 크기를 가진 리스트를 만든 뒤
2. 연산 도출 여부를 모두 False로 초기화하고
3. 연산을 통해 도출될 때마다 True로 처리하면 되지 않을까?
라는 생각이 들었습니다. 그리고 이렇게 했더니 드디어 Pass를 받았습니다.

연산 과정은 첫 번째 DP와 거의 비슷합니다만, 이번에는 합산을 Memoization 리스트의 끝에서부터 해야 합니다.
그렇게 하지 않으면 "같은 연산 단계에서 True로 표시한 수"도 연산에 포함시켜서 제대로 된 답이 나오지 않기 때문입니다.

"""

import sys
sys.stdin = open('sample_input.txt')

T = int(input())

for tc in range(1, T+1):
    # 문제의 갯수와 배점 입력 받기
    N = int(input())
    scores = list(map(int, input().split()))

    # Dynamic Programming 수행 리스트 생성
    # 크기는 배점의 합. 원소는 모두 False로 초기화
    dp = [False for _ in range(sum(scores)+1)]
    # Base Case가 되는 0은 True로 변경
    dp[0] = True

    # 연산 수행
    # 배점에서 점수를 하나씩 꺼낸다
    for score in scores:
        # dp 리스트의 끝에서부터 연산 수행
        # 끝에서부터 수행하는 이유는 잘못된 연산 누적을 피하기 위함이다!
        for i in range(len(dp)-1, -1, -1):
            # 숫자의 dp 값이 True일 경우 (= 과거에 연산을 실행했을 경우)
            if dp[i]:
                # 그 숫자에 배점을 더한 합산 결과의 dp 값을 True로 변경해준다.
                dp[i + score] = True

    # dp 리스트에 존재하는 True의 갯수를 출력
    print('#{} {}'.format(tc, dp.count(True)))


from easyAI import TwoPlayerGame, SSS, Negamax, DUAL, solve_with_depth_first_search, TranspositionTable
from easyAI.Player import Human_Player, AI_Player

class TicTacToe(TwoPlayerGame):
    """The board positions are numbered as follows:
    1 2 3
    4 5 6
    7 8 9
    """

    def __init__(self, players=None):
        self.players = players
        self.board = [0 for i in range(9)]
        self.current_player = 1  # player 1 starts.

    def possible_moves(self):
        return [i + 1 for i, e in enumerate(self.board) if e == 0]

    def make_move(self, move):
        self.board[int(move) - 1] = self.current_player

    def unmake_move(self, move):  # optional method (speeds up the AI)
        self.board[int(move) - 1] = 0

    def lose(self):
        """ Has the opponent "three in line ?" """
        return any(
            [
                all([(self.board[c - 1] == self.opponent_index) for c in line])
                for line in [
                    [1, 2, 3],
                    [4, 5, 6],
                    [7, 8, 9],  # horiz.
                    [1, 4, 7],
                    [2, 5, 8],
                    [3, 6, 9],  # vertical
                    [1, 5, 9],
                    [3, 5, 7],
                ]
            ]
        )  # diagonal

    def is_over(self):
        return (self.possible_moves() == []) or self.lose()

    def show(self):
        print(
            "\n"
            + "\n".join(
                [
                    " ".join([[".", "O", "X"][self.board[3 * j + i]]
                             for i in range(3)])
                    for j in range(3)
                ]
            )
        )

    def scoring(self):
        return -100 if self.lose() else 0

    def ttentry(self):
        return "".join([str(i) for i in self.board])

CONSOLE_WIDTH = 50

def get_padded_string(s):
    one_sided_padding = (CONSOLE_WIDTH - 2 - len(s))//2
    return '*' + ' ' * one_sided_padding + msg + ' ' * one_sided_padding + '*'

if __name__ == "__main__":

    from easyAI import AI_Player, Negamax

    ai_algo = Negamax(6)

    # game = TicTacToe([Human_Player(), AI_Player(ai_algo)])
    # scoring = 100
    # game.play()

    # 2. Dodatni scoring sprawia, że algorytm nie chce wygrać (wybiera ruchy jak najlepsze dla gracza a nie dla siebie)
    # Skala scoringu nie ma tutaj znaczenia.

    # 3.

    did_anybody_win = {
        3: [],
        6: [],
        9: [],
    }

    for ai_foresight in [3, 6, 9]:
        print('-'*CONSOLE_WIDTH)
        msg = f'For depth {ai_foresight}'

        print(get_padded_string(msg))

        print('-'*CONSOLE_WIDTH)
        for ai_approach in [Negamax(ai_foresight), SSS(ai_foresight), DUAL(ai_foresight)]:
            print('\n\n')
            print('-'*CONSOLE_WIDTH)
            print(f'For :{ai_approach.__class__.__name__} ai:')

            player = AI_Player(ai_approach)
            game = TicTacToe([player, player])
            history = game.play()

            print(len(history))
            did_anybody_win[ai_foresight].append(
                len(history) != 9 + 1)  # 9 moves of both players + ending state

    print(f"Did anybody win for each depth: {did_anybody_win}")
    # Argumenty do konstruktora obiektów reprezentujących AI wyglądają następująco
    # depth: ile ruchów na planszy sprawdzić do przodu? dla parametru 9 ai zna całe drzewo stanów dla kółka i krzyżyk
    # depth 3 jest za mały żeby ai grało dobrze, 6 i 9 jest ok
    # scoring: ile punktow sie zdobywa za przegrana/wygrana - "motywator" dla algorytmu, można nie ustawiać, nieustawiony scoring jest pobierany z samej gry
    # win_score: próg ponad którym ai uznaje grę za wygraną, detal implementacyjny, można nie ustawiać
    # tt: tablica transpozycji, jak poniżej
    # przeszukanie wyczerpujące wszystkie stany
    perfect_game_state_indicator = solve_with_depth_first_search(
        game=TicTacToe(),
        win_score=100
    )

    # print(f'Can always win? {r}')
    # print(f'At what depth? {d}')
    # print(f'First move: {m}')
    print(perfect_game_state_indicator) # 0 oznacza że można wymusić remis, nie można wygrać jeżeli ruchy obu graczy są optymalne
    assert perfect_game_state_indicator == 0 # zawsze bedzie true

    # https://zulko.github.io/easyAI/ai_descriptions.html

    # 4. Tablica transpozycji
    # Cachuje wszystkie ruchy ktore zostaly juz raz rozstrzygniete przez AI, zmniejsza naklad obliczeniowy
    # (dla danego stanu liczymy nastepne ruchy tylko raz)
    ttable = TranspositionTable()
    # do tego trzeba zaimplementować dla gry metode .ttentry(), która zwraca klucz do hashowania
    # tak się tego używa
    ai = Negamax(9, tt=ttable)
    player = AI_Player(ai)
    game = TicTacToe(players=[player, player])
    game.play()

    ttable.to_json_file('transposition_table.json')
    # zapistanie do pliku (mozna pozniej zaimportować i wznowić grę)