import cv2 as cv2
import matplotlib.pyplot as plt
import numpy as np
import json
import cv2
import sys

def readlandmarks(path) :
    with open(path, 'r') as f:
        points = json.load(f)
    return points

# Face 1
image_1 = cv2.imread('./images/Im387.png')
img1 = np.copy(image_1)
landmarks_1 = readlandmarks('./landmarks/Im387.json')

for p in landmarks_1:
        cv2.circle(img1, (p[0], p[1]), 4, (0, 255, 0), -1)
cv2.imshow("img1_landmarks", img1)

# Face 2
image_2 = cv2.imread('./images/Im386.png')
img2 = np.copy(image_2)
img2_gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
landmarks_2 = readlandmarks('./landmarks/Im386.json')
img2_new_face = np.zeros_like(image_2, np.uint8)

for p in landmarks_2:
        cv2.circle(img2, (p[0], p[1]), 4, (0, 255, 0), -1)
cv2.imshow("img2_landmarks", img2)

# Delaunay triangulation
points = np.array(landmarks_1, np.int32)
convexhull = cv2.convexHull(np.array(points, np.int32))
rect = cv2.boundingRect(convexhull)
subdiv = cv2.Subdiv2D(rect)
for p in landmarks_1:
        subdiv.insert(p)
triangles = subdiv.getTriangleList()
triangles = np.array(triangles, dtype=np.int32)

# find indexes of triangles
def extract_index_nparray(nparray):
    index = None
    for num in nparray[0]:
        index = num
        break
    return index

indexes_triangles = []
for t in triangles:
    pt1 = (t[0], t[1])
    pt2 = (t[2], t[3])
    pt3 = (t[4], t[5])

    index_pt1 = np.where((points == pt1).all(axis=1))
    index_pt1 = extract_index_nparray(index_pt1)

    index_pt2 = np.where((points == pt2).all(axis=1))
    index_pt2 = extract_index_nparray(index_pt2)

    index_pt3 = np.where((points == pt3).all(axis=1))
    index_pt3 = extract_index_nparray(index_pt3)

    if index_pt1 is not None and index_pt2 is not None and index_pt3 is not None:
        triangle = [index_pt1, index_pt2, index_pt3]
        indexes_triangles.append(triangle)

# Triangulation of both faces
for triangle_index in indexes_triangles:
    # Triangulation of the first face
    tr1_pt1 = landmarks_1[triangle_index[0]]
    tr1_pt2 = landmarks_1[triangle_index[1]]
    tr1_pt3 = landmarks_1[triangle_index[2]]
    triangle1 = np.array([tr1_pt1, tr1_pt2, tr1_pt3], np.int32)

    rect1 = cv2.boundingRect(triangle1)
    (x, y, w, h) = rect1
    cropped_triangle = image_1[y: y + h, x: x + w]
    cropped_tr1_mask = np.zeros((h, w), np.uint8)

    points = np.array([[tr1_pt1[0] - x, tr1_pt1[1] - y],
                      [tr1_pt2[0] - x, tr1_pt2[1] - y],
                      [tr1_pt3[0] - x, tr1_pt3[1] - y]], np.int32)

    cv2.fillConvexPoly(cropped_tr1_mask, points, 255)
    cropped_triangle = cv2.bitwise_and(cropped_triangle, cropped_triangle,
                                       mask=cropped_tr1_mask)

    cv2.line(img1, tr1_pt1, tr1_pt2, (0, 0, 255), 2)
    cv2.line(img1, tr1_pt3, tr1_pt2, (0, 0, 255), 2)
    cv2.line(img1, tr1_pt1, tr1_pt3, (0, 0, 255), 2)

    # Triangulation of second face
    tr2_pt1 = landmarks_2[triangle_index[0]]
    tr2_pt2 = landmarks_2[triangle_index[1]]
    tr2_pt3 = landmarks_2[triangle_index[2]]
    triangle2 = np.array([tr2_pt1, tr2_pt2, tr2_pt3], np.int32)

    rect2 = cv2.boundingRect(triangle2)
    (x, y, w, h) = rect2
    cropped_triangle2 = image_2[y: y + h, x: x + w]
    cropped_tr2_mask = np.zeros((h, w), np.uint8)

    points2 = np.array([[tr2_pt1[0] - x, tr2_pt1[1] - y],
                       [tr2_pt2[0] - x, tr2_pt2[1] - y],
                       [tr2_pt3[0] - x, tr2_pt3[1] - y]], np.int32)

    cv2.fillConvexPoly(cropped_tr2_mask, points2, 255)
    cropped_triangle2 = cv2.bitwise_and(cropped_triangle2, cropped_triangle2,
                                       mask=cropped_tr2_mask)

    cv2.line(img2, tr2_pt1, tr2_pt2, (0, 0, 255), 2)
    cv2.line(img2, tr2_pt3, tr2_pt2, (0, 0, 255), 2)
    cv2.line(img2, tr2_pt1, tr2_pt3, (0, 0, 255), 2)

    # Warp triangles
    points = np.float32(points)
    points2 = np.float32(points2)
    M = cv2.getAffineTransform(points, points2)
    warped_triangle = cv2.warpAffine(cropped_triangle, M, (w, h))
    warped_triangle = cv2.bitwise_and(warped_triangle, warped_triangle,
                                      mask=cropped_tr2_mask)

    # Reconstructing destination face
    img2_new_face_rect_area = img2_new_face[y: y + h, x: x + w]
    img2_new_face_rect_area_gray = cv2.cvtColor(img2_new_face_rect_area, cv2.COLOR_BGR2GRAY)

    # create a mask to remove the lines between the triangles
    _, mask_triangles_designed = cv2.threshold(img2_new_face_rect_area_gray, 1, 255, cv2.THRESH_BINARY_INV)
    warped_triangle = cv2.bitwise_and(warped_triangle, warped_triangle, mask=mask_triangles_designed)
    img2_new_face_rect_area = cv2.add(img2_new_face_rect_area, warped_triangle)
    img2_new_face[y: y + h, x: x + w] = img2_new_face_rect_area

cv2.imshow("img1_triangles", img1)
cv2.imshow("img2_triangles", img2)

# Face swapped (putting 1st face into 2nd face)
img2_face_mask = np.zeros_like(img2_gray)
convexhull2 = cv2.convexHull(np.array(landmarks_2, np.int32))
img2_head_mask = cv2.fillConvexPoly(img2_face_mask, convexhull2, 255)
img2_face_mask = cv2.bitwise_not(img2_head_mask)
img2_head_noface = cv2.bitwise_and(image_2, image_2, mask=img2_face_mask)

result = cv2.add(img2_head_noface, img2_new_face)
cv2.imshow("result_without_line", result)

# seamlessclone
(x, y, w, h) = cv2.boundingRect(convexhull2)
center_face2 = (int((x + x + w) / 2), int((y + y + h) / 2))
seamlessclone = cv2.seamlessClone(result, image_2, img2_head_mask, center_face2, cv2.MIXED_CLONE)
cv2.imshow("seamlessclone_without_line", seamlessclone)


from tiase.fimport import fimport,synthetic,visu

###
### AS A SCRIPT
### python -m import.py
###

_usage_str = """
Options:
    [ --cac40, --nasdaq100]
"""

def _usage():
    print(_usage_str)

def _test1():
    df = fimport.get_dataframe_from_yahoo('AI.PA')
    print(df)
    print()

def _test2():
    hist = fimport.get_dataframe_from_csv('./tiase/data/CAC40/AI.PA.csv')
    visu.display_from_dataframe(hist, "Close", "AI.PA.close.png")

def _test3():
    y = synthetic.get_sinusoid(length=100, amplitude=1, frequency=.1, phi=0, height = 0)
    df = synthetic.create_dataframe(y, .1)
    visu.display_from_dataframe(df,"Close", "close.png")

def _download(values):
    if values == "cac40":
        fimport.download_from_yahoo(fimport.cac40.keys())
    elif values == "nasdaq100":
        fimport.download_from_yahoo(fimport.nasdaq100.keys())

if __name__ == '__main__':
    import sys
    if len(sys.argv) > 1:
        if sys.argv[1] == "--test1" or sys.argv[1] == "-t1": _test1()
        elif sys.argv[1] == "--test2" or sys.argv[1] == "-t2": _test2()
        elif sys.argv[1] == "--test3" or sys.argv[1] == "-t3": _test3()
        elif sys.argv[1] == "--cac40" : _download('cac40')
        elif sys.argv[1] == "--nasdaq100" : _download('nasdaq100')
        else: _usage()
    else: _usage()


import copy
import math
import random
import re
from queue import Queue, PriorityQueue

from utils.read_file import read_file
from utils.ui import *
import time

def octile_distance(source, target):
    dx = abs(source[0] - target[0])
    dy = abs(source[1] - target[1])
    return dx + dy + (math.sqrt(2) - 2) * min(dx, dy)

def chebyshev_distance(source, target):
    return max(abs(source[0] - target[0]), abs(source[1] - target[1]), abs(source[2] - target[2]))

class Boundary:
    N = None
    M = None
    F = None

# Visual grid
class Visualizer:
    visual_map = None
    visual_grid = None
    grid_start_x = None
    grid_start_y = None
    visited_score = 0
    agent_visual = {}
    agent_total = 0

class Dnode:
    goal = None
    vgoal = None
    map_data = None

    def __init__(self, name: str, value: (int, int, int), parent=None, g=0):
        self.parent = parent
        self.name = name
        self.keys = parent.keys.copy() if parent is not None else set()
        self.value = value
        self.g = g
        if self.name.startswith("K") and self.name[1:] not in self.keys:
            self.keys.add(self.name[1:])

    def __lt__(self, other):
        return self.cost() < other.cost()

    def __str__(self):
        return self.name

    def cost(self):
        return self.g

    @staticmethod
    def is_reachable(cell):
        return cell != "-1"

    def children(self):
        queue = Queue()
        children = []
        visited = set()
        if re.search(r'^D(\d+)$', self.name) is not None and self.name[1:] not in self.keys:
            return []
        if self.name.startswith("UP"):
            z = self.value[2] + 1
        elif self.name.startswith("DO"):
            z = self.value[2] - 1
        else:
            z = self.value[2]
        grid = Dnode.map_data[f"floor{z}"]["floor_data"]
        queue.put((self.value[0], self.value[1], 0))
        while not queue.empty():
            x, y, c = queue.get()
            if (x, y) not in visited:
                visited.add((x, y))
                if (x, y, z) == Dnode.vgoal:
                    children.append(Dnode(grid[x][y], (x, y, z), self, self.g + c))
                    continue
                if (x, y) != (self.value[0], self.value[1]):
                    if grid[x][y] == "DO" or grid[x][y] == "UP":
                        children.append(Dnode(grid[x][y] + str(z), (x, y, z), self, self.g + c))
                    elif grid[x][y].startswith("K"):
                        children.append(Dnode(grid[x][y], (x, y, z), self, self.g + c))
                    elif re.search(r'^D(\d+)$', grid[x][y]) is not None:
                        children.append(Dnode(grid[x][y], (x, y, z), self, self.g + c))
                        continue
                if x > 0 and Dnode.is_reachable(grid[x - 1][y]):
                    queue.put((x - 1, y, c + 1))
                if x < Boundary.N - 1 and Dnode.is_reachable(grid[x + 1][y]):
                    queue.put((x + 1, y, c + 1))
                if y > 0 and Dnode.is_reachable(grid[x][y - 1]):
                    queue.put((x, y - 1, c + 1))
                if y < Boundary.M - 1 and Dnode.is_reachable(grid[x][y + 1]):
                    queue.put((x, y + 1, c + 1))
                if (x, y + 1) in visited and (x + 1, y) in visited and Dnode.is_reachable(grid[x + 1][y + 1]):
                    queue.put((x + 1, y + 1, c + 1))
                if (x + 1, y) in visited and (x, y - 1) in visited and Dnode.is_reachable(grid[x + 1][y - 1]):
                    queue.put((x + 1, y - 1, c + 1))
                if (x, y - 1) in visited and (x - 1, y) in visited and Dnode.is_reachable(grid[x - 1][y - 1]):
                    queue.put((x - 1, y - 1, c + 1))
                if (x - 1, y) in visited and (x, y + 1) in visited and Dnode.is_reachable(grid[x - 1][y + 1]):
                    queue.put((x - 1, y + 1, c + 1))
        return children

    def reconstruct_path(self):
        path = []
        node = self
        while node:
            path.append(node)
            node = node.parent
        return path[::-1]

class Pnode:
    map_data = None
    goal = None
    vgoal = None
    grid = None
    level = None
    valid = set()

    def __init__(self, value, parent=None, g=0):
        self.parent = parent
        self.value = value
        self.g = g

    def __lt__(self, other):
        return self.cost() < other.cost()

    def h(self):
        return octile_distance(self.value, Pnode.vgoal)

    def cost(self):
        return self.h() + self.g

    @staticmethod
    def preprocessing_goal(goal):
        if goal.startswith("DO") or goal.startswith("UP"):
            return goal[:2]
        else:
            return goal

    def children(self):
        children = []
        x = self.value[0]
        y = self.value[1]
        hv = [False, False, False, False]  # up, right, down, left
        if x > 0 and Pnode.grid[x - 1][y] in Pnode.valid:
            children.append(Pnode((x - 1, y), self, self.g + 1))
            hv[3] = True
        if x < Boundary.N - 1 and Pnode.grid[x + 1][y] in Pnode.valid:
            children.append(Pnode((x + 1, y), self, self.g + 1))
            hv[1] = True
        if y > 0 and Pnode.grid[x][y - 1] in Pnode.valid:
            children.append(Pnode((x, y - 1), self, self.g + 1))
            hv[2] = True
        if y < Boundary.M - 1 and Pnode.grid[x][y + 1] in Pnode.valid:
            children.append(Pnode((x, y + 1), self, self.g + 1))
            hv[0] = True
        if hv[0] and hv[1] and Pnode.grid[x + 1][y + 1] in Pnode.valid:
            children.append(Pnode((x + 1, y + 1), self, self.g + 1))
        if hv[1] and hv[2] and Pnode.grid[x + 1][y - 1] in Pnode.valid:
            children.append(Pnode((x + 1, y - 1), self, self.g + 1))
        if hv[2] and hv[3] and Pnode.grid[x - 1][y - 1] in Pnode.valid:
            children.append(Pnode((x - 1, y - 1), self, self.g + 1))
        if hv[3] and hv[0] and Pnode.grid[x - 1][y + 1] in Pnode.valid:
            children.append(Pnode((x - 1, y + 1), self, self.g + 1))
        return children

    def reconstruct_path(self, start: str, goal: str):
        path = []
        node = self
        while node:
            path.append((None, node.value[0], node.value[1], Pnode.level))
            node = node.parent
        path.reverse()
        path[0] = (start, path[0][1], path[0][2], path[0][3])
        path[len(path) - 1] = (goal, path[len(path) - 1][1], path[len(path) - 1][2], path[len(path) - 1][3])
        return path

    @staticmethod
    def a_star(map_data, start: Dnode, goal: Dnode):
        Pnode.goal = Pnode.preprocessing_goal(goal.name)
        Pnode.level = start.value[2] if start.value[2] == goal.value[2] else goal.value[2]
        Pnode.grid = map_data[f"floor{Pnode.level}"]["floor_data"]
        Pnode.vgoal = (goal.value[0], goal.value[1])
        Pnode.valid.add(Pnode.goal)
        frontier = PriorityQueue()
        frontier.put(Pnode((start.value[0], start.value[1])))
        visited = set()
        while not frontier.empty():
            current_node = frontier.get()
            if current_node.value not in visited:
                if current_node.value == Pnode.vgoal:
                    x = current_node.reconstruct_path(start.name, goal.name)
                    return x
                visited.add(current_node.value)
                for child in current_node.children():
                    index = next((i for i, e in enumerate(frontier.queue) if e.value == child.value), -1)
                    if child.value not in visited and index == -1:
                        frontier.put(child)
                    elif index != -1 and frontier.queue[index].cost() > child.cost():
                        frontier.queue.pop(index)
                        frontier.put(child)
        return None

def find_dtree(map_data, start: str, goal: str, keys=None):
    Dnode.map_data = map_data
    Dnode.goal = goal
    Dnode.vgoal = map_data['atkds'][Dnode.goal]
    start = Dnode(start, map_data['atkds'][start])
    if keys is not None:
        start.keys = keys
    frontier = PriorityQueue()
    frontier.put(start)
    visited = set()
    while not frontier.empty():
        current_node = frontier.get_nowait()
        if (current_node.value, tuple(current_node.keys)) not in visited:
            if current_node.name == Dnode.goal:
                # Visualizer.visual_grid[current_node.value[2] - 1][current_node.value[0]][current_node.value[1]].make_end()
                return current_node.reconstruct_path()
            visited.add((current_node.value, tuple(current_node.keys)))
            for child in current_node.children():
                index = next(
                    (i for i, e in enumerate(frontier.queue) if e.value == child.value and e.keys == child.keys),
                    -1)
                if (child.value, tuple(child.keys)) not in visited and index == -1:
                    frontier.put(child)
                    # Visualizer.visual_grid[child.value[2] - 1][child.value[0]][child.value[1]].make_start()
                elif index != -1 and frontier.queue[index].cost() > child.cost():
                    frontier.queue.pop(index)
                    frontier.put(child)
    return None

def find_path(map_data, dtree):
    Pnode.valid.clear()
    Pnode.valid.add("0")
    for key in map_data['atkds'].keys():
        if key.startswith("A") or key.startswith("T"):
            Pnode.valid.add(key)
    path = Pnode.a_star(map_data, dtree[0], dtree[1])
    for i in range(1, len(dtree) - 1):
        path.extend(Pnode.a_star(map_data, dtree[i], dtree[i + 1])[1:])
    return path

class Agent:
    map_data = None

    def __init__(self, start, goal, path=None, current=0, keys=None):
        self.start = start
        self.goal = goal
        self.path = path
        self.keys = keys
        self.__current = current
        if self.path is None:
            dtree = find_dtree(Agent.map_data, self.start, self.goal)
            if dtree is None:
                self.keys = None
                self.path = [(start, Agent.map_data['atkds'][start][0], Agent.map_data['atkds'][start][1], Agent.map_data['atkds'][start][2])]
            else:
                self.keys = dtree[-1].keys
                self.path = find_path(Agent.map_data, dtree)

    def cell(self):
        return self.path[self.__current][1], self.path[self.__current][2], self.path[self.__current][3]

    def makecopy(self):
        return Agent(self.start, self.goal, self.path.copy(), self.__current, self.keys.copy())

    def move(self, agents):
        if self.path is None:
            return 0
        if self.__current < len(self.path) - 1:
            self.__current += 1
            for agent in agents:
                if self.start != agent.start:
                    if self.cell() == agent.cell():
                        self.__current -= 1
                        return 0
            if self.start != 'A1' and self.__current == len(self.path) - 1:
                Agent.map_data['atkds'][self.start] = self.path[self.__current][1:]
                Agent.map_data[f'floor{self.path[self.__current][3]}']['floor_data'][self.path[self.__current][1]][
                    self.path[self.__current][2]] = self.start
                Agent.map_data[f'floor{self.path[0][3]}']['floor_data'][self.path[0][1]][self.path[0][2]] = '0'
                while True:
                    x = random.randint(0, Boundary.N - 1)
                    y = random.randint(0, Boundary.M - 1)
                    z = random.randint(1, Boundary.F)
                    if Agent.map_data[f'floor{z}']['floor_data'][x][y] == '0':
                        Agent.map_data['atkds'].update({self.goal: (x, y, z)})
                        Agent.map_data[f'floor{z}']['floor_data'][x][y] = self.goal
                        self.__current = 0
                        dtree = find_dtree(Agent.map_data, self.start, self.goal, self.keys)
                        self.path = None if dtree is None else find_path(Agent.map_data, dtree)
                        break
                return 1
        return 2

    def get_out_of_the_way(self, position, cell):
        self.path.insert(position + 1, (None, cell[0], cell[1], cell[2]))
        self.path.insert(position + 2, self.path[position])

    def __str__(self):
        return self.start + " " + str(self.cell())

class Anode:
    n = None
    combinations = None

    def __init__(self, agents, parent=None, t=0, combination=None, status=None):
        self.parent = parent
        self.agents = agents
        self.t = t
        self.combination = '0' * Anode.n if combination is None else combination
        self.status = '0' * Anode.n if status is None else status

    def __lt__(self, other):
        return self.t + self.h() < other.t + other.h()

    def h(self):
        dec = int(self.combination, 2)
        # return dec flipped
        return dec ^ (2 ** (len(self.combination) + 1) - 1)

    def __str__(self):
        agents = [str(agent) for agent in self.agents]
        return " ".join(agents) + " " + f"status: {self.status}" + " " + f"t: {self.t}"

    def __copy_agents(self):
        agents = []
        for agent in self.agents:
            agents.append(agent.makecopy())
        return agents

    def children(self):
        children = []
        for combination in Anode.combinations:
            move = 0
            agents = self.__copy_agents()
            status = ''
            for agent in agents:
                if combination[move] == '1':
                    signal = agent.move(agents)
                    if signal > 0:
                        status += '1'
                    else:
                        status += '0'
                else:
                    status += '0'
                move += 1
            children.append(Anode(agents, self, self.t + 1, combination, status))
        return children

    def reconstruct_path(self):
        path = []
        node = self
        Visualizer.agent_visual[0] = Visualizer.visual_grid
        for agent in node.agents:
            Visualizer.agent_visual[int(agent.start[1:])] = copy.deepcopy(Visualizer.visual_grid)
        while node is not None:
            path.append(node)
            node = node.parent
        return path[::-1]

def visual_path(path):
    if len(path) == 1:
        Visualizer.visited_score = None
        return
    for node in path:
        for i in range(Anode.n):
            for agent in node.agents:
                Visualizer.agent_visual[int(agent.start[1:])][agent.cell()[2] - 1][agent.cell()[0]][
                    agent.cell()[1]].make_visited()
            Visualizer.visual_grid[node.agents[i].cell()[2] - 1][node.agents[i].cell()[0]][
                node.agents[i].cell()[1]].make_agent(node.agents[i].start)
            draw(WIN, Visualizer.visual_grid[node.agents[i].cell()[2] - 1], Boundary.N, Boundary.M, WIDTH,
                 Visualizer.grid_start_x,
                 Visualizer.grid_start_y)
            pygame.time.delay(100)
            pygame.display.update()
        for i in range(Anode.n):
            if node != path[-1]:
                Visualizer.visual_grid[node.agents[i].cell()[2] - 1][node.agents[i].cell()[0]][
                    node.agents[i].cell()[1]].make_path()
                Visualizer.visual_grid[node.agents[i].cell()[2] - 1][node.agents[i].cell()[0]][
                    node.agents[i].cell()[1]].name = ''
        pygame.time.wait(100)
    num_agent = len(path[0].agents)
    len_path = len(path)
    Visualizer.visited_score = num_agent * len_path

def prevent_deadlock(agents):
    a1_path = set([cell[1:] for cell in agents[0].path])
    for i in range(1, len(agents)):
        if agents[i].path is None:
            continue
        ai_path = set([cell[1:] for cell in agents[i].path])
        intersection = a1_path.intersection(ai_path)
        union = a1_path.union(ai_path)
        if agents[0].path[0][1:] in intersection and agents[i].path[0][1:] in intersection:
            intersection.remove(agents[0].path[0][1:])
            for j, cell in enumerate(agents[i].path):
                if cell[1:] in intersection:
                    x = cell[1]
                    y = cell[2]
                    z = cell[3]
                    grid = Agent.map_data[f'floor{z}']['floor_data']
                    if x > 0 and grid[x - 1][y] == "0" and (x - 1, y, z) not in union:
                        agents[i].get_out_of_the_way(j, (x - 1, y, z))
                        break
                    if x < Boundary.N - 1 and grid[x + 1][y] == "0" and (x + 1, y, z) not in union:
                        agents[i].get_out_of_the_way(j, (x + 1, y, z))
                        break
                    if y > 0 and grid[x][y - 1] == "0" and (x, y - 1, z) not in union:
                        agents[i].get_out_of_the_way(j, (x, y - 1, z))
                        break
                    if y < Boundary.M - 1 and grid[x][y + 1] == "0" and (x, y + 1, z) not in union:
                        agents[i].get_out_of_the_way(j, (x, y + 1, z))
                        break
                    if x > 0 and y > 0 and grid[x - 1][y] == "0" and grid[x][y - 1] and grid[x - 1][y - 1] == "0" and (
                            x - 1, y - 1, z) not in union:
                        agents[i].get_out_of_the_way(j, (x - 1, y - 1, z))
                        break
                    if x < Boundary.N - 1 and y > 0 and grid[x + 1][y] == "0" and grid[x][y - 1] == "0" and grid[x + 1][
                        y - 1] == "0" and (x + 1, y - 1, z) not in union:
                        agents[i].get_out_of_the_way(j, (x + 1, y - 1, z))
                        break
                    if x < Boundary.N - 1 and y < Boundary.M - 1 and grid[x + 1][y] == "0" and grid[x][y + 1] == "0" and \
                            grid[x + 1][y + 1] == "0" and (x + 1, y + 1, z) not in union:
                        agents[i].get_out_of_the_way(j, (x + 1, y + 1, z))
                        break
                    if x > 0 and y < Boundary.M - 1 and grid[x - 1][y] == "0" and grid[x][y + 1] == "0" and grid[x - 1][
                        y + 1] == "0" and (x - 1, y + 1, z) not in union:
                        agents[i].get_out_of_the_way(j, (x - 1, y + 1, z))
                        break

def mapf(map_data):
    Boundary.N = map_data['floor1']['height']
    Boundary.M = map_data['floor1']['width']
    Boundary.F = map_data['floor_count']
    Agent.map_data = copy.deepcopy(map_data)
    count = 0
    agents = []
    for agent in map_data['atkds'].keys():
        if agent.startswith('A'):
            agents.append(Agent(agent, 'T' + agent[1:]))
            count += 1
    agents.sort(key=lambda x: x.start)
    prevent_deadlock(agents)
    Anode.n = count
    Anode.combinations = sorted([bin(i)[2:].zfill(count) for i in range(2 ** count)][1:])
    start = Anode(agents)
    frontier = PriorityQueue()
    frontier.put(start)
    visited = set()
    while not frontier.empty():
        current_node = frontier.get_nowait()
        if tuple([agent.cell() for agent in current_node.agents]) not in visited:
            if current_node.agents[0].cell() == current_node.agents[0].path[-1][1:]:
                return current_node.reconstruct_path()
            visited.add(tuple([agent.cell() for agent in current_node.agents]))
            for child in current_node.children():
                index = next((i for i, e in enumerate(frontier.queue) if
                              tuple([agent.cell() for agent in e.agents]) == tuple(
                                  [agent.cell() for agent in child.agents])), -1)
                if tuple([agent.cell() for agent in child.agents]) not in visited and index == -1:
                    frontier.put(child)
                elif index != -1 and frontier.queue[index].t > child.t:
                    frontier.queue.pop(index)
                    frontier.put(child)
    return None

def print_visual_grid(map_data):
    visual_map = []
    for floor, floor_data in map_data.items():
        # Check if the data is a floor
        if re.search(r'^floor\d+$', floor) is not None:
            visual_map.append(make_grid(Boundary.N, Boundary.M, WIDTH))
            for i in range(Boundary.N):
                for j in range(Boundary.M):
                    if floor_data['floor_data'][i][j] == "-1":
                        visual_map[-1][i][j].make_barrier()
                    elif floor_data['floor_data'][i][j].startswith("T"):
                        visual_map[-1][i][j].make_closed_agent(floor_data['floor_data'][i][j])
                    elif floor_data['floor_data'][i][j].startswith("A"):
                        visual_map[-1][i][j].make_agent(floor_data['floor_data'][i][j])
                    elif floor_data['floor_data'][i][j].startswith("K"):
                        visual_map[-1][i][j].make_key(floor_data['floor_data'][i][j])
                    elif re.search(r'^D(\d+)$', floor_data['floor_data'][i][j]) is not None:
                        visual_map[-1][i][j].make_door(floor_data['floor_data'][i][j])
                    elif floor_data['floor_data'][i][j] == "DO":
                        visual_map[-1][i][j].make_door("DO")
                    elif floor_data['floor_data'][i][j] == "UP":
                        visual_map[-1][i][j].make_door("UP")

    return visual_map

def save_image_level4( floor_index, agent_index, grid_start_x, grid_start_y):
    change_agent_and_redraw(Visualizer.agent_visual[agent_index][floor_index], grid_start_x, grid_start_y)
    pygame.display.update()
    if agent_index == 0:
        agent_index = '_print_path'
    is_folder_exists('src/images/level4')
    pygame.image.save(WIN, f'src/images/level4/floor{floor_index}_agent{agent_index}.jpg')

def level4(url):
    map_data = read_file(url)
    Boundary.N = map_data[f'floor{1}']['height']  # Row
    Boundary.M = map_data[f'floor{1}']['width']  # Column

    # Calculate the total grid size
    total_grid_width = Boundary.M * (WIDTH // Boundary.M)
    total_grid_height = Boundary.N * (WIDTH // Boundary.N)

    # Calculate the starting position to center the grid
    grid_start_x = (WIDTH - total_grid_width) // 2
    grid_start_y = (WIDTH - total_grid_height) // 2

    Visualizer.grid_start_x = grid_start_x
    Visualizer.grid_start_y = grid_start_y

    # Create the visualizer
    visual_map = print_visual_grid(map_data)
    Visualizer.visual_grid = visual_map
    run = True
    playagain = False

    floor_index = 0
    total_floor = len(visual_map)
    Visualizer.visual_grid = visual_map
    agent_index = 0
    Visualizer.agent_visual[agent_index] = Visualizer.visual_grid

    while run:
        # Draw the visualizer
        command = draw_menu_level4(Visualizer.agent_total, agent_index, floor_index)
        if playagain:
            playagain = False
            Visualizer.visual_grid = print_visual_grid(map_data)

        print_score(Visualizer.visited_score)

        # change_agent_and_redraw(Visualizer.agent_visual[agent_index], grid_start_x, grid_start_y)

        change_agent_and_redraw(Visualizer.agent_visual[agent_index][floor_index], grid_start_x, grid_start_y)
        # draw(WIN, visual_map[floor_index], Boundary.N, Boundary.M, WIDTH, grid_start_x, grid_start_y)
        pygame.display.update()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
                playagain = False
                pygame.quit()
            if pygame.MOUSEBUTTONDOWN:
                if command == 1:
                    start = time.process_time()
                    Visualizer.agent_visual[agent_index] = Visualizer.visual_grid
                    # agent_index = 0
                    playagain = True
                    Visualizer.visited_score = 0
                    map_data = read_file(url)
                    visual_map = print_visual_grid(map_data)
                    Visualizer.visual_grid = visual_map
                    solution = mapf(map_data)
                    print('Time: ', 1000.0*( time.process_time() - start))

                    Visualizer.agent_total = len(solution[0].agents)
                    visual_path(solution)
                    save_image_level4( floor_index, agent_index, grid_start_x, grid_start_y)

                # Go up floor
                if command == 2:
                    playagain = False
                    if floor_index < total_floor - 1:
                        floor_index += 1
                    else:
                        floor_index = 0
                    command = -1
                    save_image_level4( floor_index, agent_index, grid_start_x, grid_start_y)

                # Go down floor
                if command == 3:
                    playagain = False
                    if floor_index > 0:
                        floor_index -= 1
                    else:
                        floor_index = total_floor - 1
                    save_image_level4( floor_index, agent_index, grid_start_x, grid_start_y)

                if command == 4:
                    playagain = False
                    if agent_index < len(Visualizer.agent_visual) - 1:
                        agent_index += 1
                    else:
                        agent_index = 0
                    save_image_level4( floor_index, agent_index, grid_start_x, grid_start_y)
                #  Exit menu
                if command == 0:
                    playagain = False
                    run = False

            pygame.time.wait(100)
            pygame.display.flip()

def test():
    map_data = read_file('test.txt')
    solution = mapf(map_data)

    for e in solution:
        print(e)

# test()


class Solution:
    # @param A : integer
    # @return an integer
    def reverse(self, A):
        B = list(str(A))
        B = B[::-1]
        if(A<0):
            x = B.pop()
            B.insert(0,'-')
        B = ''.join
        B = int(B)
        if (len(bin(B)) -2)>32:
            return 0
        return B


import torch
import torch.nn.functional as f
import torch.utils.data as data
import constant
import torchvision
import subprocess
import pandas as pd
import random
from test_bond_analysis import new_create_bond_matrix
from test_bond_analysis import new_process_bond_list
from test_bond_analysis import read_neighbor_list
from test_bond_analysis import new_create_force_matrix
from test_bond_analysis import new_create_formal_force_matrix

from left_test_bond_analysis import new_create_bond_matrix as left_new_create_bond_matrix
from left_test_bond_analysis import new_process_bond_list as left_new_process_bond_list
from left_test_bond_analysis import read_bond_list as left_read_bond_list

from right_test_bond_analysis import new_create_bond_matrix as right_new_create_bond_matrix
from right_test_bond_analysis import new_process_bond_list as right_new_process_bond_list
from right_test_bond_analysis import read_bond_list as right_read_bond_list
#from test_bond_analysis import new_create_force_matrix
#from test_bond_analysis import new_create_formal_force_matrix

# preprocessing
torch.manual_seed(2293)
torch.set_default_dtype(torch.float64)

bond_list = read_neighbor_list("data_input/bond_5_3only_74_458_2432.csv", 74)
bond_list = new_process_bond_list(bond_list)

random.seed(32768)

class Net(torch.nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.input = torch.nn.Linear(539, 1024)
        self.hidden_1 = torch.nn.Linear(1024, 512)
        self.hidden_2 = torch.nn.Linear(512, 256)
        self.hidden_3 = torch.nn.Linear(256, 128)
        self.hidden_4 = torch.nn.Linear(128, 64)
        self.output = torch.nn.Linear(64, 2)

    def forward(self, x):
        x = f.relu(self.input(x))
        x = f.relu(self.hidden_1(x))
        x = f.relu(self.hidden_2(x))
        x = f.relu(self.hidden_3(x))
        x = f.relu(self.hidden_4(x))
        x = self.output(x)
        return x

class BoundNet(torch.nn.Module):
    def __init__(self, input_size_list):
        super(BoundNet, self).__init__()
        self.input = torch.nn.ModuleList([torch.nn.Linear(input_size_list[i], 1024) for i in range(5)])
        self.hidden_1 = torch.nn.Linear(1024, 512)
        self.hidden_2 = torch.nn.Linear(512, 256)
        self.hidden_3 = torch.nn.Linear(256, 128)
        self.hidden_4 = torch.nn.Linear(128, 64)
        self.output = torch.nn.Linear(64, 2)

    def forward(self, x):
        x = [f.relu(self.input[i](x[i])) for i in range(5)]
        x = torch.cat(x)
        x = f.relu(self.hidden_1(x))
        x = f.relu(self.hidden_2(x))
        x = f.relu(self.hidden_3(x))
        x = f.relu(self.hidden_4(x))
        x = self.output(x)
        return x

left_bond_list = []
left_bond_count = []
left_chirality_count = []
left_bond_c = []
left_chirality_c = []
left_feature_count = []

right_bond_list = []
right_bond_count = []
right_chirality_count = []
right_bond_c = []
right_chirality_c = []
right_feature_count = []

for i in range(5):
    left_bond_list_t, left_bond_count_t, left_chirality_count_t, left_bond_c_t, left_chirality_c_t = left_read_bond_list("data_input/bond" + str(i) + ".csv")
    left_bond_list.append(left_bond_list_t)
    left_bond_count.append(left_bond_count_t)
    left_chirality_count.append(left_chirality_count_t)
    left_bond_c.append(left_bond_c_t)
    left_chirality_c.append(left_chirality_c_t)
    left_feature_count.append(left_bond_c_t + left_chirality_c_t + 1)

for i in range(5):
    right_bond_list_t, right_bond_count_t, right_chirality_count_t, right_bond_c_t, right_chirality_c_t = right_read_bond_list("data_input/bond" + str(i + 27) + ".csv")
    right_bond_list.append(right_bond_list_t)
    right_bond_count.append(right_bond_count_t)
    right_chirality_count.append(right_chirality_count_t)
    right_bond_c.append(right_bond_c_t)
    right_chirality_c.append(right_chirality_c_t)
    right_feature_count.append(right_bond_c_t + right_chirality_c_t + 1)

print("**************************************")
print("Left Parameters: ")
print("Bond layer count: ", left_bond_count)
print("Chirality layer count", left_chirality_count)
print("Bond feature: ", left_bond_c)
print("Chirality feature: ", left_chirality_c)
print("Total feature count: ", left_feature_count)
left_bond_list = [left_new_process_bond_list(left_bond_list[i]) for i in range(5)]
print("**************************************")

print("**************************************")
print("Right Parameters: ")
print("Bond layer count: ", right_bond_count)
print("Chirality layer count", right_chirality_count)
print("Bond feature: ", right_bond_c)
print("Chirality feature: ", right_chirality_c)
print("Total feature count: ", right_feature_count)
right_bond_list = [right_new_process_bond_list(right_bond_list[i]) for i in range(5)]
print("**************************************")

def generate_force():
    data = pd.read_csv("share_file.csv", header=None, delimiter=",")

    spin_tensor = torch.tensor(data.iloc[:, 3:6].values, device=constant.device).requires_grad_(True)
    left_spin_tensor = torch.tensor(data.iloc[:, 3:6].values, device=constant.device).requires_grad_(True)
    right_spin_tensor = torch.tensor(data.iloc[:, 3:6].values, device=constant.device).requires_grad_(True)

    x_temp = new_create_bond_matrix(spin_tensor, bond_list)

    energy_prediction_temp = net(x_temp)

    energy_prediction = torch.sum(energy_prediction_temp, 0)
    energy_A = energy_prediction[0]
    energy_B = energy_prediction[1]

    force_prediction_A = -torch.autograd.grad(energy_A, spin_tensor, create_graph=True)[0]
    force_prediction_B = -torch.autograd.grad(energy_B, spin_tensor, create_graph=True)[0]

    force_prediction_temp = force_prediction_A + torch.cross(spin_tensor, force_prediction_B)
    force_prediction = torch.cross(spin_tensor, force_prediction_temp)

    left_x_temp = [left_new_create_bond_matrix(left_spin_tensor, left_bond_list[i], left_bond_count[i], left_chirality_count[i]) for i in range(5)]

    left_energy_prediction_temp = left_net(left_x_temp)
    left_energy_prediction = torch.sum(left_energy_prediction_temp, 0)
    left_energy_A = left_energy_prediction[0]
    left_energy_B = left_energy_prediction[1]
    print(left_energy_prediction, left_energy_A, left_energy_B)

    left_force_prediction_A = -torch.autograd.grad(left_energy_A, left_spin_tensor, create_graph=True)[0]
    left_force_prediction_B = -torch.autograd.grad(left_energy_B, left_spin_tensor, create_graph=True)[0]
    left_force_prediction_temp = left_force_prediction_A + torch.cross(left_spin_tensor, left_force_prediction_B)
    left_force_prediction = torch.cross(left_spin_tensor, left_force_prediction_temp)

    right_x_temp = [right_new_create_bond_matrix(right_spin_tensor, right_bond_list[i], right_bond_count[i], right_chirality_count[i]) for i in range(5)]

    right_energy_prediction_temp = right_net(right_x_temp)
    right_energy_prediction = torch.sum(right_energy_prediction_temp, 0)
    right_energy_A = right_energy_prediction[0]
    right_energy_B = right_energy_prediction[1]
    print(right_energy_prediction, right_energy_A, right_energy_B)

    right_force_prediction_A = -torch.autograd.grad(right_energy_A, right_spin_tensor, create_graph=True)[0]
    right_force_prediction_B = -torch.autograd.grad(right_energy_B, right_spin_tensor, create_graph=True)[0]
    right_force_prediction_temp = right_force_prediction_A + torch.cross(right_spin_tensor, right_force_prediction_B)
    right_force_prediction = torch.cross(right_spin_tensor, right_force_prediction_temp)

    force_prediction = new_create_formal_force_matrix(force_prediction, left_force_prediction, right_force_prediction)

    data.iloc[:, 9:12] = force_prediction.detach().numpy()
    data.to_csv("share_file.csv", header=False, index=False)
    return energy_prediction.detach().numpy()

print("Initializing net.")
net = Net()
net.load_state_dict(torch.load("data_input/pp_change_final_model_save_at_1_task_1.pt", map_location=lambda storage, loc: storage))
print(net)
net.to(constant.device)
print("Middle net loaded")

left_net = BoundNet(left_feature_count)
left_net.load_state_dict(torch.load("data_input/left_final_model_save_at_1_task_1.pt", map_location=lambda storage, loc: storage))

#print(net)
print("Left net parameters: \n")
print(left_net)
left_net.to(constant.device)
print("Left net loaded")
print("***********************")

right_net = BoundNet(right_feature_count)
right_net.load_state_dict(torch.load("data_input/right_final_model_save_at_1_task_1.pt", map_location=lambda storage, loc: storage))

#print(net)
print("Right net parameters: \n")
print(right_net)
right_net.to(constant.device)
print("Right net loaded")
print("***********************")

print("Initialized!")

# Initialize the first round
print("Generate first set up")
args = "./de_c_pure initialize".split()
args.append(str(constant.lattice_n))
args.append(str(constant.lattice_w))
args.append(str(constant.kT))
args.append(str(constant.dmp))
args.append(str(constant.dt))
args.append(str(0))
args.append(constant.init)
print(args)
popen_status = subprocess.Popen(args)
exit_code = popen_status.wait()
print("exit_status: " + str(exit_code))
print("First set up done!")

# simulation
print("Simulation start")

for round_n in range(constant.total_round):
    energy = generate_force()
    with open("energy.csv", "a") as energy_file:
        energy_file.write(str(round_n) + "," + str(energy) + "\n")
    args = "./de_c_pure calculate".split()
    args.append(str(constant.lattice_n))
    args.append(str(constant.lattice_w))
    args.append(str(constant.kT))
    args.append(str(constant.dmp))
    args.append(str(constant.dt))
    args.append(str(round_n))
    args.append(constant.init)
    args.append(str(random.randint(0, 1000000)))
    print(args)
    popen_status = subprocess.Popen(args)
    exit_code = popen_status.wait()
    print("exit_status: " + str(exit_code))
    if exit_code != 2:
        ValueError("force prediction collapsed.")
    print("round " + str(round_n) + " $$$$$$$$$$$$$$$$$$$$$$$")

print("Simulation done!")


# Loop para cada arquivo de teste
while True:
    try:
        nomes = []

        # Lê os 10 nomes
        for _ in range(10):
            nome = input()
            nomes.append(nome)

        # Imprime o terceiro, sétimo e nono nomes
        print(nomes[2])
        print(nomes[6])
        print(nomes[8])

    except EOFError:
        break


# -*- coding: utf-8 -*-
"""
@author: Meina Zhang
"""

from __future__ import print_function
import matplotlib.pyplot as plt
import argparse
import os
import numpy as np
from networks.multi_net import multi_attention
import cv2
import torch
import torch.optim
from torch.autograd import Variable
import glob
import torch.nn as nn
from PIL import Image
import warnings
from tqdm import tqdm
from torch.optim.lr_scheduler import MultiStepLR
from utils.common_utils import *
from SSIM import SSIM
from skimage.transform import pyramid_gaussian
import math

parser = argparse.ArgumentParser()
parser.add_argument('--num_iter', type=int, default=1500, help='number of epochs of training')
parser.add_argument('--kernel_size', type=int, default=[79, 79], help='size of blur kernel [height, width]')
parser.add_argument('--img_size', type=int, default=[256, 256], help='size of each image dimension')
parser.add_argument('--img_size1', type=int, default=[630, 518], help='size of each image dimension')
parser.add_argument('--img_size2',  type=int, default=[630, 518], help='size of each image dimension')
parser.add_argument('--data_path', type=str, default="datasets/", help='path to blurry image')
parser.add_argument('--save_path', type=str, default="results/", help='path to save results')
parser.add_argument('--save_frequency', type=int, default=10, help='frequency to save results')
opt = parser.parse_args()
# print(opt)

torch.backends.cudnn.enabled = True
torch.backends.cudnn.benchmark = True
dtype = torch.cuda.FloatTensor

warnings.filterwarnings("ignore")

files_source = glob.glob(os.path.join(opt.data_path, 'wall.jpg'))

files_source.sort()
save_path = opt.save_path
os.makedirs(save_path, exist_ok=True)

# start #image
for f in files_source:
    INPUT = 'noise'
    pad = 'reflection'
    LR = 0.01
    num_iter = opt.num_iter
    reg_noise_std = 0.001
    p0 = 0.1
    delta_t = 0.1
    path_to_image = f
    imgname = os.path.basename(f)
    imgname = os.path.splitext(imgname)[0]

    _, imgs = get_image(path_to_image, -1) # load image and convert to np.
    y_color = np_to_torch(imgs).type(dtype)

    img_gray = readimg_gray(path_to_image)

    img_gray = np.float32(img_gray / 255.0)
    y = np.expand_dims(img_gray, 0)

    img_size = y.shape
    n_scales = 3
    imgs_trans = imgs.transpose(1,2,0)
    pyramid = list(pyramid_gaussian(imgs_trans, n_scales-1, multichannel=True))
    for l in range(len(pyramid)):
        pyramid[l] = pyramid[l].transpose(2,0,1)

    pyramid_size0 = pyramid[0].shape
    pyramid_size1 = pyramid[1].shape
    pyramid_size2 = pyramid[2].shape
    pyramid0 = np_to_torch(pyramid[0]).type(dtype)
    pyramid1 = np_to_torch(pyramid[1]).type(dtype)
    pyramid2 = np_to_torch(pyramid[2]).type(dtype)

    ker_size1 = math.ceil(opt.kernel_size[0]/2)
    ker_size2 = math.ceil(ker_size1/2)

    padh1, padw1 = ker_size1-1, ker_size1-1
    padh2, padw2 = ker_size2-1, ker_size2-1

    opt.img_size1[0], opt.img_size1[1] = pyramid_size1[1]+padh1, pyramid_size1[2]+padw1
    opt.img_size2[0], opt.img_size2[1] = pyramid_size2[1]+padh2, pyramid_size2[2]+padw2

    padh, padw = opt.kernel_size[0]-1, opt.kernel_size[1]-1
    opt.img_size[0], opt.img_size[1] = img_size[1]+padh, img_size[2]+padw

    img_size = imgs.shape

    print(imgname)
    # ######################################################################

    padw, padh = opt.kernel_size[0]-1, opt.kernel_size[1]-1
    opt.img_size[0], opt.img_size[1] = img_size[1]+padw, img_size[2]+padh
    input_depth = 8
    net_input = get_noise(input_depth, INPUT, (opt.img_size2[0], opt.img_size2[1])).type(dtype)

    n_k = 200
    net_input_kernel = get_noise(ker_size2*ker_size2, INPUT, (1, 1)).type(dtype)
    net_input_kernel.squeeze_()

    net = multi_attention(ker_size2,ker_size1,opt.kernel_size[0],channel=3).type(dtype)
    lossL1 = nn.L1Loss().type(dtype)
    lossL2 = nn.MSELoss().type(dtype)

    mse = torch.nn.MSELoss().type(dtype)
    ssim = SSIM().type(dtype)

    params_dict = [{'params': net.skip2.parameters(), 'lr': LR},
                   {'params': net.skip1.parameters(), 'lr': LR},
                   {'params': net.FEblock.parameters(), 'lr': 1e-2},
                    {'params': net.fcn2.parameters(), 'lr': 1e-4},
                    {'params': net.fcn1.parameters(), 'lr': 1e-4},
                    {'params': net.fcn0.parameters(), 'lr': 1e-4}]

    optimizer = torch.optim.Adam(params_dict)
    scheduler = MultiStepLR(optimizer, milestones=[2000, 3000, 4000], gamma=0.5)  # learning rates

    # initilization inputs
    net_input_saved = net_input.detach().clone()
    net_input_kernel_saved = net_input_kernel.detach().clone()

    for step in tqdm(range(num_iter)):

        scheduler.step(step)
        optimizer.zero_grad()

        skip_out2,kernel2,skip_out1,kernel1,skip_out0,kernel0 = net(net_input,net_input_kernel,\
                                                                    (pyramid_size1[1], pyramid_size1[2]), \
                                                                        (pyramid_size0[1], pyramid_size0[2]),\
                                                                            ker_size1,opt.kernel_size[0])

        out_k_m2 = kernel2.view(-1,1,ker_size2,ker_size2)
        out_k_m2 = out_k_m2.repeat(3,1,1,1)

        out_k_m1 = kernel1.view(-1,1,ker_size1,ker_size1)
        out_k_m1 = out_k_m1.repeat(3,1,1,1)

        out_k_m0 = kernel0.view(-1,1,opt.kernel_size[0],opt.kernel_size[1])
        out_k_m0 = out_k_m0.repeat(3,1,1,1)

        out_y2 = nn.functional.conv2d(skip_out2, out_k_m2, padding=0, groups =3,bias=None)
        out_y1 = nn.functional.conv2d(skip_out1, out_k_m1, padding=0, groups =3,bias=None)
        out_y0 = nn.functional.conv2d(skip_out0, out_k_m0, padding=0, groups =3,bias=None)

        if step < 300:

            total_loss = mse(out_y2, pyramid2) +mse(out_y1, pyramid1) + 2*mse(out_y0, pyramid0)

        else:
            total_loss =  1-ssim(pyramid2,out_y2)+ 1-ssim(pyramid1,out_y1) + 2*(1-ssim(pyramid0,out_y0))

        total_loss.backward()
        optimizer.step()

        if (step + 1) % opt.save_frequency == 0:
            save_path = os.path.join(opt.save_path, '%s_x.png'%imgname)
            out_x_np = torch_to_np(skip_out0)

            out_x_np = out_x_np[:,padh//2:padh//2+img_size[1], padw//2:padw//2+img_size[2]]

            channel_out = out_x_np.transpose(1,2,0)
            channel_out = (channel_out*255).astype(np.uint8)
            channel_out = Image.fromarray(channel_out).convert('RGB')
            channel_out.save(save_path)

            save_path = os.path.join(opt.save_path, '%s_k.png'%imgname)
            out_k_np = out_k_m0.permute(1,0,2,3)
            out_k_np = torch_to_np(out_k_np)
            out_k_np /= np.max(out_k_np)

            channel_out = out_k_np.transpose(1,2,0)
            channel_out = (channel_out*255).astype(np.uint8)
            channel_out = Image.fromarray(channel_out).convert('RGB')
            channel_out.save(save_path)

        torch.save(net, os.path.join(opt.save_path, "%s_net.pth" % imgname))


""" The function get_parameter() is supposed to return parameters saved
in a csv file /settings/settings_file.csv within this package

"""
import pandas as pd
import pkg_resources

def get_parameter(parameter):
    """ Read settings csv file in /settings/settings_file.csv in this package

    Parameters
    ----------
    parameter : str
        parameter to read

    Returns
    -------
    float
        value of the parameter
    str
        comment for the parameter
    """

    # get module name
    resource_package = __name__

    print(resource_package)

    # path to file within package
    resource_path = 'settings/settings_file.csv'

    csv_file = pkg_resources.resource_stream(resource_package, resource_path)

    df = pd.read_csv(csv_file, sep=',', index_col=[0])

    value = df.loc[parameter,'value']
    comment = df.loc[parameter,'comment']

    return value, comment


import itertools
import random
import time
from typing import Optional, Tuple, List, Set

from mappi.models import MappiFunction, Result, Context

def test_func(
    context: Context,
    func: MappiFunction,
) -> Optional[Result]:
    values = {name: context.generate_value() for name in func.variables}
    if context.no_modulo:
        compute = lambda x: func.func(x, **values)
    else:
        compute = lambda x: func.func(x, **values) % context.output_range
    try:
        vals = {x: compute(x) for x in context.input_values}
    except ZeroDivisionError:
        return None
    if len(set(vals.values())) == context.output_range:
        substituted_expression = f"({func.substitute(values)})"
        if not context.no_modulo:
            substituted_expression = (
                f"{substituted_expression} % {context.output_range}"
            )
        verify_func = eval(f"lambda x: {substituted_expression}")
        is_ordered = all(
            verify_func(iv) == i for (i, iv) in enumerate(context.input_values)
        )
        if context.strict_order and not is_ordered:
            return None
        assert len(set(verify_func(iv) for iv in context.input_values)) == len(
            context.input_values
        )
        return Result(
            score=len(substituted_expression),
            func=func,
            substituted_expression=substituted_expression,
            mapping=vals.copy(),
            is_ordered=is_ordered,
        )
    return None

def find_results(context: Context) -> Tuple[List[Result], bool]:
    results: List[Result] = []
    seen_exprs: Set[str] = set()
    last_print_time = init_time = time.time()
    for attempt in itertools.count():
        try:
            if attempt % 100 == 0:
                now = time.time()
                if now - init_time > context.time_limit:
                    print("Time limit reached.")
                    break
                if now - last_print_time > 1:
                    last_print_time = now
                    print(
                        f"{attempt} attempts, {len(results)} candidates found in {now - init_time:.2f}s ..."
                    )

            result = test_func(
                context,
                random.choice(context.functions),
            )
            if result:
                if (
                    not results
                    or result.score < results[-1].score
                    and result.substituted_expression not in seen_exprs
                ):
                    print("FOUND:", result.format())
                    results.append(result)
                    seen_exprs.add(result.substituted_expression)
                elif context.print_all:
                    print(".....", result.format())
        except KeyboardInterrupt:
            print()
            return (results, True)
    return (results, False)


import os

CURRENT_DIR = os.path.dirname(__file__)
LOGS_DIR = CURRENT_DIR + r"\logs"
LOGGER_SERVER_PATH = LOGS_DIR + r"\server.log"
ERROR_LOGGER_SERVER_PATH = LOGS_DIR + r"\server_error.log"
LOGGER_CLIENT_PATH = LOGS_DIR + r"\client.log"
ERROR_LOGGER_CLIENT_PATH = LOGS_DIR + r"\client_error.log"

HEADER_LENGTH = 1024
SERVER_PORT = 80
#SERVER_PORT = 5056
HOST_SERVER = "127.0.0.1"
#HOST_SERVER = "192.168.1.37"
#PUBLIC_IP = ""
PUBLIC_IP = ""


import pandas as pd
from neo4j import GraphDatabase
import re

def read_graph_data(file_name: str) -> pd.DataFrame:
    df = pd.read_excel(file_name)
    df.drop_duplicates(keep='first', inplace=True)
    graph_data = df[['Идентификатор операции', 'ADCM_шифрГЭСН', 'Последователи']]
    graph_data['Идентификатор операции'] = graph_data['Идентификатор операции'].apply(str.strip)
    graph_data = graph_data[graph_data['Идентификатор операции'].str.startswith('A')]
    graph_data.set_index('Идентификатор операции', inplace=True)  # Update indeces
    return graph_data

def m():
    df_init = pd.read_excel("2022-02-07 МОЭК_ЕКС график по смете.xlsx")
    df_init["is_duplicate"] = df_init.duplicated()
    df = read_graph_data("2022-02-07 МОЭК_ЕКС график по смете.xlsx")
    df["is_duplicate"] = df.duplicated()
    with pd.ExcelWriter('duplicated.xlsx', mode='w') as excel_output1:
        df_init.to_excel(excel_output1, sheet_name='before')
        df.to_excel(excel_output1, sheet_name='after')

def main():
    s = '(Learn Python) (not C++)'
    result = re.findall('\(.*?\)', s)
    print(result)

    s = 'Learn Python (not C++)'
    s = 'dffvdd'
    result = s[s.find('(') + 1:s.find(')')]
    print(s.find('('))

if __name__ == '__main__':
    main()


gallons = float(input('Enter the number of gallons used: '))
miles = float(input("Miles driven: "))

mileage = 0.0
count = 0
while gallons != -1:
    count += 1
    mileage += (miles / gallons)
    semi_total = miles / gallons
    grand_total = mileage / count
    gallons = float(input("Enter the gallons used: "))
    miles = float(input('Miles driven:'))
    print("The miles/gallon for this tank was ", semi_total)
    if gallons == -1:
        print("The overall average miles/gallon was ", grand_total)


from crispy_forms.bootstrap import InlineRadios
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Div, Field, Submit
from django import forms

from orders.models import Order

class OrderForm(forms.ModelForm):
    class Meta:
        model = Order
        fields = (
            'postcard',
            'postcard_text',
            'delivery_type',
            'delivery_date',
            'recipient',
            'recipient_name',
            'recipient_phone',
            'recipient_call',
            'recipient_address',
            'delivery_time',
            'comment',
        )
        widgets = {
            'postcard': forms.RadioSelect(),
            'postcard_text': forms.Textarea(attrs={'rows': 5}),
            'delivery_type': forms.RadioSelect(),
            'delivery_date': forms.TextInput(attrs={'type': 'date'}),
            'delivery_time': forms.TextInput(attrs={'type': 'time'}),
            'recipient': forms.RadioSelect(),
            'recipient_call': forms.RadioSelect(),
            'comment': forms.Textarea(attrs={'rows': 5, 'cols': 50}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.layout = Layout(
            Div(InlineRadios('postcard'), css_class='row my-2'),
            Div(Field('postcard_text'), hidden='true', css_class='row my-2 postcard_text'),
            Div(InlineRadios('delivery_type'), css_class='row my-2'),
            Div('delivery_date', css_class='row my-2'),
            Div(InlineRadios('recipient'), css_class='row my-2'),
            Div(
                Div('recipient_name', css_class='mr-3 recipient_info', hidden='true'),
                Div('recipient_phone', css_class='recipient_info', hidden='true'),
                css_class='row my-2'
            ),
            Div(InlineRadios('recipient_call'), css_class='row my-2 recipient_call', hidden='true'),
            Div(
                Div('recipient_address', css_class='mr-3 delivery_info', hidden='true'),
                Div('delivery_time', css_class='delivery_info', hidden='true'),
                css_class='row my-2'
            ),
            Div('comment', css_class='row my-2'),
            Div(Submit('submit', 'Заказать', css_class='btn orange-btn'), css_class='row my-2')
        )
        self.helper.form_method = 'post'
        self.helper.form_action = 'order-create'
        self.helper.form_class = 'order-form'
        self.helper.label_class = 'label'

class OrderCheckStatusForm(forms.Form):
    pk = forms.IntegerField(min_value=1)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_show_labels = False
        self.helper.form_method = 'post'
        self.helper.form_action = 'order-check-status'
        self.helper.layout = Layout(
            'pk',
            Submit('submit', 'Проверить', css_class='btn orange-btn')
        )

    def clean_pk(self):
        pk = self.cleaned_data.get('pk')
        order = Order.objects.filter(pk=pk).first()
        if not order:
            self.add_error('pk', 'Заказ с данным номером не найден')
        return pk


#!/usr/bin/env python3
#%%
# concat results from HOG+SVM
import json
import datetime

# ssiv bahia results filepath
SSIV_BAHIA_FILEPATH = "assets/results/hog_svm_ssiv_bahia_20181211T2249.json"

# jequitaia results filepath
JEQUITAIA_FILEPATH = "assets/results/hog_svm_jequitaia_20181211T2150.json"

# balsa results filepath
BALSA_FILEPATH = "assets/results/hog_svm_balsa_20181211T2234.json"

with open(SSIV_BAHIA_FILEPATH) as jsonfile:
  ssiv_bahia_results = json.load(jsonfile)

with open(JEQUITAIA_FILEPATH) as jsonfile:
  jequitaia_results = json.load(jsonfile)

with open(BALSA_FILEPATH) as jsonfile:
  balsa_results = json.load(jsonfile)

#%%
# concat results
all_results = ssiv_bahia_results + jequitaia_results + balsa_results

result_filepath = "hog_svm_all_{:%Y%m%dT%H%M}.json".format(datetime.datetime.now())
json.dump(all_results, open(result_filepath, 'w'))


from typing import Optional, Tuple

from . import config
from .lock import Lock

bot = config.get_slackbot()

def user_message(lock: Lock, **message_data) -> bool:
    res_json = bot.api_call("im.open", user=lock.user_id)

    if not res_json["ok"]:
        return False

    channel = res_json["channel"]["id"]

    res = bot.api_call("chat.postMessage", channel=channel, **message_data)
    return res["ok"]

def react_message(lock: Lock, message_id: str, reaction: str) -> bool:
    try:
        res = bot.api_call(
            "reactions.add",
            channel=lock.channel_id,
            name=reaction,
            timestamp=message_id,
        )
    except Exception:
        return False

    return res["ok"]

def channel_message(
    channel_id: str, message: str, init_lock: bool = False, user: Optional[str] = None
) -> Tuple[bool, str]:

    if init_lock:
        attachments: Optional[list] = [
            {
                "fallback": "buttons for /rlock /runlock actions",
                "callback_id": "lock_expiry",
                "actions": [
                    {
                        "name": "lock",
                        "text": "+20",
                        "type": "button",
                        "value": "lock_20",
                    },
                    {
                        "name": "lock",
                        "text": "+40",
                        "type": "button",
                        "value": "lock_40",
                    },
                    {
                        "name": "unlock",
                        "text": "Unlock",
                        "type": "button",
                        "value": "unlock",
                        "style": "primary",
                    },
                ],
            }
        ]
    else:
        attachments = None

    if user:
        res = bot.api_call(
            "chat.postEphemeral",
            channel=channel_id,
            text=message,
            attachments=attachments,
            user=user,
        )
    else:
        res = bot.api_call(
            "chat.postMessage",
            channel=channel_id,
            text=message,
            attachments=attachments,
        )

    return res["ok"], res.get("ts", "")

def update_channel_message(
    lock: Lock, message: str, unlock: bool = False
) -> Tuple[bool, Optional[str]]:
    if unlock:
        res = bot.api_call(
            "chat.update",
            channel=lock.channel_id,
            text=message,
            ts=lock.message_id,
            attachments=[],
        )
    else:
        res = bot.api_call(
            "chat.update", channel=lock.channel_id, text=message, ts=lock.message_id
        )

    return res["ok"], lock.message_id


print("Welcome to dice duels")
from random import randrange
ctr=0
player1=str(raw_input("player 1 enter name-\n"))
player2=str(raw_input("player 2 enter name-\n"))

player1w =0
player2w =0
while(ctr!=10):
	while(player1w!=3 and player2w!=3):
		raw_input("press enter to roll dice-\n")
		roll1= randrange(1,11)
		print(player1 + " rolled a " + str(roll1))
		print("")
		roll2= randrange(1,11)
		print(player2 + " rolled a " + str(roll2))
		print("")
		if (roll1<roll2):
			player1w +=1
			print(player1 + " wins the round!\n")
		elif(roll1>roll2):
			player2w +=1
			print(player2 + " wins the round!\n")
	if player1w ==3:
		print(player1 + " wins the game!\n")
		playagain=raw_input("If you want to play again type yes, if not type no.\n")
		if(playagain=="yes"):
			ctr=1
			player1w=0
			player2w=0
		if(playagain=="no"):
			ctr=10
	if player2w ==3:
		print(player2 + " wins the game!\n")
		playagain=raw_input("If you want to play again type yes, if not type no.\n")
		if(playagain=="yes"):
			ctr=1
			player1w=0
			player2w=0
		if(playagain=="no"):
			ctr=10


# Day 17 - Create Own Custom Classes
    # A class is just an blueprint for an object to be used later on.

class User:
    def __init__(self, user_id, username):
        self.id = user_id
        self.username = username
        self.followers = 0
        self.following = 0

    def follow(self, user):
        user.followers += 1
        self.following += 1

user_1 = User("001", "Daniel")
user_2 = User("002", "Faith")

user_1.follow(user_2)

print(user_1.followers)
print(user_1.following)
print(user_2.followers)
print(user_2.following)

100 Day Python Bootcamp - Intermediate/Day_17 - Quiz Project/custom_classes.py


import responses

from co2_tracker_utils.cloud_logging import (
    CLOUD_METADATA_MAPPING,
    get_env_cloud_details,
)

def setup_cloud_details_responses(tested_provider, provider_metadata):
    for provider, params in CLOUD_METADATA_MAPPING.items():
        if provider == tested_provider:
            responses.add(
                responses.GET, params["url"], json=provider_metadata, status=200
            )
        else:
            responses.add(responses.GET, params["url"], status=404)

@responses.activate
def test_get_env_cloud_details_mapping_aws():
    metadata = {"architecture": "x86_64", "availabilityZone": "us-east-1a"}
    setup_cloud_details_responses("AWS", metadata)

    assert get_env_cloud_details() == {"provider": "AWS", "metadata": metadata}

@responses.activate
def test_get_env_cloud_details_mapping_azure():
    metadata = {"compute": {"azEnvironment": "AzurePublicCloud"}}
    setup_cloud_details_responses("Azure", metadata)

    assert get_env_cloud_details() == {"provider": "Azure", "metadata": metadata}

@responses.activate
def test_get_env_cloud_details_mapping_google():
    metadata = {
        "attributes": {},
        "cpuPlatform": "Intel Haswell",
        "zone": "projects/253764845563/zones/us-central1-a",
    }
    setup_cloud_details_responses("GCP", metadata)

    expected_metadata = metadata
    del expected_metadata["attributes"]

    assert get_env_cloud_details() == {"provider": "GCP", "metadata": metadata}

@responses.activate
def test_get_env_cloud_details_mapping_nothing():
    metadata = {"instance": {"attributes": {"cluster-location": "us-east1-c"}}}
    setup_cloud_details_responses("localhost", metadata)

    assert get_env_cloud_details() is None


import matplotlib
matplotlib.use('tkagg')
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

from cBioF import preprocess_dataset as RDIM
from cBioF.metalearn_extension import Metafeatures
from cBioF.robustness_methods import robustness_methods

basic_mf = ['NumberOfCategoricalFeatures', 'NumberOfNumericFeatures', 'Dimensionality', 'NumberOfMissingValues',
            'RatioOfFeaturesWithMissingValues', 'RatioOfInstancesWithMissingValues',
            'MinCardinalityOfCategoricalFeatures', 'MinCardinalityOfNumericFeatures',
            'MinimumCardinalityFeaturesCount', 'MinimumCardinalityFeatures', 'MeanMeansOfNumericFeatures',
            'StdevMeansOfNumericFeatures', 'MeanStdDevOfNumericFeatures', 'StdevStdDevOfNumericFeatures',
            'MeanSkewnessOfNumericFeatures', 'MeanKurtosisOfNumericFeatures', 'NumberOfFeatures',
            'MeanCorrelation', 'MaxCorrelation', 'MinCorrelation', 'MinCategoricalMutualInformation',
              'MinNumericMutualInformation']

classif_mf = ['MinClassProbability', 'NumberOfClasses', 'MaxClassProbability', 'PredPCA1', 'PredPCA2', 'PredPCA3']

focus_mf = ['CategoricalMutualInformationOutlierFeatures', 'NumericMutualInformationOutlierFeatures',
            'FeaturesWithMostMissingValues', 'RatioOfFeaturesWithMostMissingValues', 'OutlierClassProbabilities',
            'OutlierClasses', 'CorrelationOutlierFeatures', 'CorrelationOutliers']

plot_mf = ["ClassHistogram", "DistributionBoxplots", "CategoricalCardinalityOutlierHistograms",
           "NumericCardinalityOutlierBoxplots", "CategoricalMutualInformationOutlierHistograms",
           "NumericMutualInformationOutlierHistograms"]

def explore_dataset(X, y, features, missing_values='Unknown', preprocessing=False, classification=True,
                        focus=False, plots=False):
    """ First prepare the data for data exploration. Then find issues in the dataset. These issues are based on:
     - feature types,
     - feature dimensionality,
     - missing values,
     - output imbalance,
     - irrelevant features,
     - normalisation,
     - multicollinearity

     The exploration can include a more thorough focus on outliers. Also several plots can be shown to give more insight
     in the dataset.
     If desired the output can also be preprocessed and returned immediately, with and without feature selection.

    :param X: A numpy matrix of the data. First axis corresponding to instances, second axis corresponding to samples
    :param y: A numpy array of the output. The length of the array should correspond to the size of the first
    axis of X
    :param features: A numpy array of the feature names. The length of the array should correspond to the size of the
    second axis of X
    :param missing_values: The way missing values are added to the data. Can be a list if missing values are portrayed
    in multiple ways. Default: 'Unknown' (several well-known ways of portraying missing values are checked)
    :param preprocessing: Whether preprocessing should be done after exploration
    :param classification: If the output is categorical. Default: True
    :param focus: Whether focus is desired on outliers to get a better insight in the data. Default: False
    :param plots: Whether plots should be shown to get a better insight in the data. Default: False
    :return: if: preprocessing = True: preprocessed X, y and features
    """

    # Test the input to be according to the standards
    robustness_methods.check_input_arrays(X, y, features)

    dfX, dfy = _create_pandas_dataframe_dataset(X, y, features, classification=classification)

    dfX, dfy, exploration_results = pandas_explore_dataset(dfX, dfy, missing_values=missing_values,
                                                               preprocessing=preprocessing, focus=focus,
                                                               plots=plots, classification=classification)
    X_new = dfX.values
    y_new = dfy.values
    f_new = np.array(list(dfX))

    return X_new, y_new, f_new, exploration_results

def pandas_explore_dataset(dfX, dfy, missing_values='Unknown', preprocessing=False, focus=False, plots=False, classification=True):
    """ First prepare the data for data exploration. Then find issues in the dataset. These issues are based on:
     - feature types,
     - feature dimensionality,
     - missing values,
     - output imbalance,
     - irrelevant features,
     - normalisation,
     - multicollinearity

     The exploration can include a more thorough focus on outliers. Also several plots can be shown to give more insight
     in the dataset.
     If desired the output can also be preprocessed and returned immediately, with and without feature selection.

    :param dfX: A pandas dataframe of the data. Every column corresponds to a feature, rows correspond to instances.
    :param dfy: A pandas series of the output. The length of the array should correspond to the size of the first
    axis of X
    :param missing_values: The way missing values are added to the data. Can be a list if missing values are portrayed
    in multiple ways. Default: 'Unknown' (several well-known ways of portraying missing values are checked)
    :param preprocessing: Whether preprocessing should be done after exploration
    :param focus: Whether focus is desired on outliers to get a better insight in the data. Default: False
    :param plots: Whether plots should be shown to get a better insight in the data. Default: False
    :param classification: If the output is categorical. Default: True
    :return: if: preprocessing = True: preprocessed dfX and dfy
    """

    # Test the input to be according to the standards
    robustness_methods.check_pandas_input(dfX, dfy)

    dfX = _prepare_dataset(dfX, missing_values=missing_values)

    exploration_results = _pandas_metalearn_explore_dataset(dfX, dfy, plots=plots, focus=focus, classification=classification)

    # If preprocessing is needed
    if preprocessing:
        print("\n  Preprocessing")
        dfX_new, dfy_new = RDIM.pandas_preprocess_dataset(dfX, dfy, exploration_results, fs_example=True, classification=classification)

        return dfX_new, dfy_new, exploration_results

def _pandas_metalearn_explore_dataset(dfX, dfy, focus=False, plots=False, classification=True):
    """ TFind issues in the dataset. These issues are based on:
     - feature types,
     - feature dimensionality,
     - missing values,
     - output imbalance,
     - irrelevant features,
     - normalisation,
     - multicollinearity

     The exploration can include a more thorough focus on outliers. Also several plots can be shown to give more insight
     in the dataset.

    :param dfX: A pandas dataframe of the data. Every column corresponds to a feature, rows correspond to instances.
    :param dfy: A pandas series of the output. The length of the array should correspond to the size of the first
    axis of X
    :param focus: Whether focus is desired on outliers to get a better insight in the data. Default: False
    :param plots: Whether plots should be shown to get a better insight in the data. Default: False
    :param classification: If the output is categorical. Default: True
    :return: if: preprocessing = True: preprocessed dfX and dfy
    """

    # Test the input to be according to the standards
    robustness_methods.check_pandas_input(dfX, dfy)

    mf = Metafeatures()

    list_mfs = basic_mf

    if classification:
        list_mfs.extend(classif_mf)

    if focus:
        list_mfs.extend(focus_mf)

    if plots:
        list_mfs.extend(plot_mf)

    metafeatures = mf.compute(dfX, dfy, metafeature_ids=list_mfs)

    exploration_results = {}
    exploration_results['cat'] = False
    exploration_results['num'] = False

    # Feature types
    if metafeatures['NumberOfCategoricalFeatures']['value'] > 0:
        print("\n Feature Types")
        exploration_results['cat'] = True
        print("%i categorical features are present, hot encoding is recommended for machine learning analysis"
              % metafeatures['NumberOfCategoricalFeatures']['value'])
        if metafeatures['NumberOfNumericFeatures']['value'] > 0:
            exploration_results['num'] = True
            print("Also %i numerical features are present. Either hot encoding or binning must occur for "
                  "further analysis" % metafeatures['NumberOfNumericFeatures']['value'])
    elif metafeatures['NumberOfNumericFeatures']['value'] > 0:
        exploration_results['num'] = True

    # Feature dimensionality
    exploration_results['fs'] = False

    if metafeatures['Dimensionality']['value'] > 1:
        print("\n Feature Dimensionality")
        exploration_results['fs'] = True
        print("Dimensionality is higher than 1: %.2f, feature selection is recommended"
              % metafeatures['Dimensionality']['value'])

    min_mi = min(metafeatures['MinCategoricalMutualInformation']['value'],
                 metafeatures['MinNumericMutualInformation']['value'])

    if classification and min_mi < 0.01:
        exploration_results['fs'] = True
        print("The mutual information of at least one feature is lower than 0.05: %.2f. "
              "Feature selection is recommended" % min_mi)

    exploration_results['mv'] = False
    exploration_results['cca'] = True
    exploration_results['aca'] = True

    if focus and exploration_results['cat']:
        feat = metafeatures['CategoricalMutualInformationOutlierFeatures']['value']
        out = [round(elem, 2) for elem in metafeatures['CategoricalMutualInformationOutliers']['value']]
        print("The categorical features %s have the lowest mutual information respectively %s" %
              (feat[0:3], out[0:3]))
        print("The categorical features %s have the highest mutual information respectively %s" %
              (feat[3:6], out[3:6]))
        feat = metafeatures['NumericMutualInformationOutlierFeatures']['value']
        out = [round(elem, 2) for elem in metafeatures['NumericMutualInformationOutliers']['value']]
        print("The numeric features %s have the lowest mutual information respectively %s" %
              (feat[0:3], out[0:3]))
        print("The numeric features %s have the highest mutual information respectively %s" %
              (feat[3:6], out[3:6]))

    # Missing values
    if metafeatures['NumberOfMissingValues']['value'] > 0:
        print("\n Missing Values")
        exploration_results['mv'] = True
        print("%i missing values are present, missing value handling should occur"
              % metafeatures['NumberOfMissingValues']['value'])
        if metafeatures['RatioOfInstancesWithMissingValues']['value'] > 0.10:
            print("The ratio of samples with missing values is not small %.2f, "
                  "only complete case analysis is not advised"
                  % metafeatures['RatioOfInstancesWithMissingValues']['value'])
            exploration_results['cca'] = False
        if metafeatures['RatioOfFeaturesWithMissingValues']['value'] > 0.10:
            print("The ratio of features with missing values is not small %.2f, "
                  "only available case analysis is not advised"
                  % metafeatures['RatioOfFeaturesWithMissingValues']['value'])
            exploration_results['aca'] = False

        if focus:
            feat = metafeatures['FeaturesWithMostMissingValues']['value']
            ratios = [round(elem, 2) for elem in metafeatures['RatioOfFeaturesWithMostMissingValues']['value']]
            print("The features %s have the most i values, with ratios of respectively %s" % (feat, ratios))

    exploration_results['imbalance'] = False

    # Output imbalance
    if classification and metafeatures['MinClassProbability']['value'] + 0.10 / metafeatures['NumberOfClasses']['value'] \
            < metafeatures['MaxClassProbability']['value']:
        print("\n Output imbalance")
        exploration_results['imbalance'] = True
        print(
            "Minority class probability is %.2f smaller than the majority class probability. Imbalance seems present,"
            " and should be taken into account" %
            (metafeatures['MaxClassProbability']['value'] - metafeatures['MinClassProbability']['value']))

        if focus:
            num_class = min(3, int(metafeatures['NumberOfClasses']['value'] / 2))
            out = [round(elem, 2) for elem in metafeatures['OutlierClassProbabilities']['value']]
            print("The minority classes %s have a probability of %s" %
                  (metafeatures['OutlierClasses']['value'][0: num_class], out[0: num_class]))
            print("The majority classes %s have a probability of %s" %
                  (metafeatures['OutlierClasses']['value'][-num_class:], out[-num_class:]))

    exploration_results['irrelevance'] = 0

    # Irrelevant features
    if metafeatures['MinCardinalityOfCategoricalFeatures']['value'] == 1 or \
                    metafeatures['MinCardinalityOfNumericFeatures']['value'] == 1:
        print("\n Irrelevant Features")
        exploration_results['irrelevance'] = metafeatures['MinimumCardinalityFeaturesCount']['value']
        print("%i features without any information are present" % metafeatures['MinimumCardinalityFeaturesCount'][
            'value'])
        exploration_results['irrelevant_features'] = metafeatures['MinimumCardinalityFeatures']['value']

        if focus:
            print('The features without any information present are %s' %
                  list(dfX)[metafeatures['MinimumCardinalityFeatures']['value']].tolist())

    # Normalisation
    print("\n Normalisation")

    exploration_results['norm_means'] = False
    exploration_results['norm_stdev'] = False
    exploration_results['stand'] = False

    mean_means = metafeatures['MeanMeansOfNumericFeatures']['value']
    stdev_means = metafeatures['StdevMeansOfNumericFeatures']['value']
    mean_stdevs = metafeatures['MeanStdDevOfNumericFeatures']['value']
    stdev_stdevs = metafeatures['StdevStdDevOfNumericFeatures']['value']
    if mean_means != 0 and stdev_means / mean_means > 0.01:
        print("There is a high variance in the means of the features. Normalisation or standardisation of the "
              "mean is recommended.")
        exploration_results['norm_means'] = True

    if mean_stdevs != 0 and stdev_stdevs / mean_stdevs > 0.01:
        print("There is a high variance in the standard deviation in the features. Normalisation or standardisation "
              "of the standard deviation is recommended")
        exploration_results['norm_stdev'] = True

    if abs(metafeatures['MeanSkewnessOfNumericFeatures']['value']) > 1:
        print("The average skewness of the numeric features is highly different from the normal distribution. "
              "Keep in mind a significant number of the features is not normally distributed")
        exploration_results['stand'] = True

    if abs(metafeatures['MeanKurtosisOfNumericFeatures']['value'] - 3) > 1:
        print("The average kurtosis of the numeric features is highly different from the normal distribution. "
              "Keep in mind a significant number of the features is not normally distributed")
        exploration_results['stand'] = True

    # Multicollinearity
    print("\n Multicollinearity")
    mc_threshold = 1 / ((metafeatures['NumberOfFeatures']['value']) ** (1 / 2))

    exploration_results['mc'] = False

    if classification and metafeatures['PredPCA1']['value'] > mc_threshold:
        print('The first principal component already explains %.2f variance in the dataset, showing a high amount of '
              'multicollinearity being present' % metafeatures['PredPCA1']['value'])
        exploration_results['mc'] = True
    elif classification and metafeatures['PredPCA1']['value'] + metafeatures['PredPCA2']['value'] > mc_threshold:
        print(
            'The first two principal component already explain %.2f variance in the dataset, showing a high amount of '
            'multicollinearity being present' %
            metafeatures['PredPCA1']['value'] + metafeatures['PredPCA2']['value'])
        exploration_results['mc'] = True
    elif classification and metafeatures['PredPCA1']['value'] + metafeatures['PredPCA2']['value'] + metafeatures['PredPCA3'][
        'value'] > mc_threshold:
        print(
            'The first three principal component already contain %.2f variance in the dataset, showing a high amount of '
            'multicollinearity being present' %
            metafeatures['PredPCA1']['value'] + metafeatures['PredPCA2']['value'] + metafeatures['PredPCA3']['value'])
        exploration_results['mc'] = True

    if metafeatures['MeanCorrelation']['value'] != 'Too many features for correlation testing':
        if metafeatures['MaxCorrelation']['value'] > 0.5:
            print('At least two features have a high correlation value of %.2f' %
                  metafeatures['MaxCorrelation']['value'])
            exploration_results['mc'] = True
        if metafeatures['MinCorrelation']['value'] < -0.5:
            print('At least two features have a high negative correlation value of %.2f' %
                  metafeatures['MinCorrelation']['value'])
            exploration_results['mc'] = True

        if focus:
            feat = metafeatures['CorrelationOutlierFeatures']['value']
            out = [round(elem, 2) for elem in metafeatures['CorrelationOutliers']['value']]
            print("The combination of the features %s have a negative correlation of %s" % (feat[0:3], out[0:3]))
            print("The combination of the features %s have a positive correlation of %s" % (feat[3:6], out[3:6]))

    if plots:
        plt.show()

    return exploration_results

def _create_pandas_dataframe_dataset(X, y, features, classification=True):
    """ Make a pandas dataframe out of the numpy dataset

    :param X: A numpy matrix of the data. First axis corresponding to instances, second axis corresponding to samples
    :param y: A numpy array of the output. The length of the array should correspond to the size of the first
    axis of X
    :param features: A numpy array of the feature names. The length of the array should correspond to the size of the
    second axis of X
    :param classification: If the output is categorical. Default: True
    :return: dataframe dfX with data and series dfy with output
    """

    # Create dataframe
    dfX = pd.DataFrame(X, columns=features)

    if classification:
        dfy = pd.Series(y, dtype='category')
    else:
        dfy = pd.Series(y, dtype=float)

    dfy.name = "Output"

    return dfX, dfy

def _prepare_dataset(dfX, missing_values='Unknown'):
    """ Prepare the dataset by changing the missing values and data types to the correct type

    :param dfX: A pandas dataframe of the data. Every column corresponds to a feature, rows correspond to instances.
    :param missing_values: The way missing values are added to the data. Can be a list if missing values are portrayed
    in multiple ways. Default: 'Unknown' (several well-known ways of portraying missing values are checked)
    :return: dataframe dfX with data, with a correctly matching missing values and data types
    """

    dfX = _prepare_missing_values(dfX, missing_values)

    dfX = _prepare_data_types(dfX)

    return dfX

def _prepare_missing_values(dfX, missing_values='Unknown'):
    """ Prepare the dataset by changing the missing values

    :param dfX: A pandas dataframe of the data. Every column corresponds to a feature, rows correspond to instances.
    :param missing_values: The way missing values are added to the data. Can be a list if missing values are portrayed
    in multiple ways. Default: 'Unknown' (several well-known ways of portraying missing values are checked)
    :return: dataframe dfX with data, with a correctly matching missing values
    """

    # Change possible missing values to NaN values
    if type(missing_values) == list:
        for missing_value in missing_values:
            dfX = dfX.replace(missing_value, np.NaN)

    elif missing_values == 'Unknown':
        for missing_value in ['', '?', 'None']:
            dfX = dfX.replace(missing_value, np.NaN)

    else:
        dfX = dfX.replace(missing_values, np.NaN)

    return dfX

def _prepare_data_types(dfX):
    """ Prepare the dataset by changing the data types to the correct type

    :param dfX: A pandas dataframe of the data. Every column corresponds to a feature, rows correspond to instances.
    :return: dataframe dfX with data, with a correctly matching data types
    """

    for header in list(dfX):
        X_f = dfX[header].values
        try:
            X_f.astype(float)
            dfX[header] = pd.to_numeric(dfX[header], errors='coerce')
        except:
            dfX[header] = dfX[header].astype('category')

    return dfX


import sys
import pygame
from settings import Settings
from ship import Ship

class AlienInvasion:
    """клас для управления ресурсами и поведением игры"""
    def __init__(self):
        """Инициализирует игру и создает игровые ресурсы"""
        pygame.init()
        self.settings = Settings()
        # Назвачает размеры экрана из файла настроек
        self.screen = pygame.display.set_mode((self.settings.screen_width, self.settings.screen_height))
        pygame.display.set_caption("Alien Invasion")
        #назначаем цвет фона
        self.bg_color = (self.settings.bg_color)

        self.ship = Ship(self) #!!! в книге помарка вместо screen self

    def run_game(self):
        """запуск основного цикла игры"""
        while True:
            # Отслежиавание событий клавиатуры игры.
            self._check_events()
            self._update_screen()

    def _check_events(self):
        # Отслежиавание событий клавиатуры игры.
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()

    def _update_screen(self):
        """Обновление изображения на экране и отображает новый экран"""
        # При каждом проходе цикла перерисовывается экран
        self.screen.fill(self.settings.bg_color)
        self.ship.blitme()

        # Отоброжение последнего прикосновения экрна.
        pygame.display.flip()

if __name__ == '__main__':
    # Создание экземпляра и запуска игры
    ai = AlienInvasion()
    ai.run_game()


import sys

dial = ['ABC', 'DEF', 'GHI', 'JKL', 'MNO', 'PQRS', 'TUV', 'WXYZ']
time = 0

# 입력 받는 모든 문자는 대문자로 취급
input_str = sys.stdin.readline().upper()

for i in range(len(input_str)):
    for j in dial:
        if input_str[i] in j:
            time += dial.index(j) + 3

print(time)


import Algorithmia
import os

import tinify

from mysite.settings import BASE_DIR, ALGORITHMIA_KEY, TINYFY_KEY

# Get directory for file manipulation
DIR_PATH = os.path.dirname(os.path.realpath(__file__))

# Authenticate Algorithmia with API key
apiKey = ALGORITHMIA_KEY
# Create the Algorithmia client object
client = Algorithmia.client(apiKey)
# Path for client directory
client_dir = "data://ThatChocolateGuy/"

# Authenticate Tinify with API key
tinify.key = TINYFY_KEY

def get_images(image):
    """Create labeled dataset from image collection."""
    local_image_path = DIR_PATH + "/../.." + image.file.url
    image_file_name = image.file.name.split('/')[1]
    client_image_dir = client.dir(client_dir + "PFR/")
    client_image_path = client_dir + "PFR/" + image_file_name
    images = []

    # Create remote directory (if it doesn't exist)
    if client_image_dir.exists() is False:
        client_image_dir.create()
    # Upload image to client directory
    client.file(client_image_path).putFile(local_image_path)

    # Retrieve images from data collection
    for file in client_image_dir.list():
        path = file.path.split('_')
        first_name = file.path.split('/')[2].split('_')[0]
        last_name = path[1]
        # Create label from image name
        label = first_name + " " + last_name
        # Label image based on person
        images.append(
            {"url": "data://{0}".format(file.path), "person": label}
        )

    return images

def facial_recgnition_algo(input):
    """Call face recognition algo and pipe input in"""
    algo = client.algo('cv/FaceRecognition/0.2.2')

    print("\nPIPING INPUT:")
    print("\n" + input.__str__() + "\n")
    return algo.pipe(input).result

def train_images(images):
    """Train model from images"""
    input = {
        "action": "add_images",
        "data_collection": "FaceRecognitionStates",
        "name_space": "pfr",
        "images": images
    }
    return facial_recgnition_algo(input)

def model_predictions(image_src):
    """Predict a person based on unseen images using trained model"""
    client_image_dir = client.dir(client_dir + "FaceRecognitionOutput/")
    client_image_path = client_dir + "FaceRecognitionOutput/pfr_out_input.jpg"
    client.file(client_image_path).putFile("." + image_src)

    input = {
        "name_space": "pfr",
        "data_collection": "FaceRecognitionStates",
        "action": "predict",
        "images": [
            {
                "url": "data://ThatChocolateGuy/FaceRecognitionOutput/" +
                "pfr_out_input.jpg",
                "output": "data://ThatChocolateGuy/FaceRecognitionOutput/" +
                "pfr_out_processed.jpg"
            }
        ]
    }

    return facial_recgnition_algo(input)


import doctest
import unittest

import numpy as np

import fklab.segments
from fklab.segments import Segment
from fklab.segments import SegmentError

class TestBasicAlgorithm(unittest.TestCase):
    def setUp(self):  # Add here any steps you want alway run before 1 test
        self.vector = np.linspace(0, 12, 48)
        self.s1 = [[0, 10], [20, 30], [50, 100]]
        self.s2 = [[4, 6], [15, 25], [40, 200]]
        self.s3 = [[8, 20], [35, 60], [150, 180]]

    def tearDown(self):
        del self.s1
        del self.s2
        del self.s3

    def test_check_segment(self):
        issegment = fklab.segments.check_segments([[0, 4], [5, 12]])
        np.testing.assert_array_equal(issegment, np.array([[0, 4], [5, 12]]))

    def test_check_not_segment(self):
        self.assertRaises(
            ValueError, lambda: fklab.segments.check_segments([["test", 4], [5, 12]])
        )

    def test_as_index(self):
        segment = Segment([[0, 4], [5, 12]])
        expected = [[0, 15], [20, 46]]
        result = segment.asindex(self.vector)
        np.testing.assert_array_equal(np.asarray(result), expected)

    def test_as_index_full(self):
        segment = Segment([[0, 4], [4, 12]])
        expected = [[0, 15], [16, 46]]
        result = segment.asindex(self.vector)
        np.testing.assert_array_equal(np.asarray(result), expected)

    def test_issegment(self):
        self.assertTrue(Segment.issegment(Segment([[0, 10], [20, 30], [50, 100]])))

    def test_segment_construct_from_list_no_copy(self):
        s1 = Segment(self.s1)
        s = Segment(s1, copy=False)
        self.assertIsInstance(s, Segment)
        self.assertTrue(s == s1)

    def test_segment_construct_empty(self):
        s = Segment([])
        self.assertIsInstance(s, Segment)

    def test_sort_segment_empty(self):
        s = Segment([])
        self.assertEqual(s.sort(), Segment([]))

    def test_segment_iteration(self):
        s1 = Segment([[1, 2], [3, 4]])
        for index, seq in enumerate(s1):
            if index == 0:
                np.testing.assert_array_equal(seq, np.array([1, 2]))
            if index == 1:
                np.testing.assert_array_equal(seq, np.array([3, 4]))

    def test_segment_equal(self):
        s1 = Segment([[1, 2], [3, 4], [10, 20]])
        s2 = Segment([[1, 2], [3, 4], [10, 20]])
        self.assertIsInstance(s1, type(s2))
        self.assertTrue(s1 == s2)
        self.assertFalse(s1 == [[1, 1], [2, 4], [10, 20]])
        self.assertFalse(s1 == [[1, 1], [2, 4]])

    def test_segment_equal_2(self):
        self.assertRaises(ValueError, lambda: Segment([[1, 2], [10, 20]]) == "a")
        self.assertRaises(ValueError, lambda: Segment([[1, 2], [10, 20]]) != "a")

    def test_segment_inequal(self):
        s1 = Segment([[1, 2], [3, 4], [10, 20]])
        s2 = Segment([[1, 2], [3, 4], [10, 20]])

        self.assertFalse(s1 != s2)
        self.assertTrue(s1 != [[1, 1], [2, 4]])
        self.assertTrue(s1 != [[1, 1], [2, 4], [10, 20]])

    def test_get_set_item(self):
        s1 = Segment([[1, 2], [3, 4], [10, 20]])
        s1[0] = [2, 3]
        self.assertEqual(s1[0], [2, 3])
        del s1[0]
        self.assertEqual(s1, Segment([[3, 4], [10, 20]]))

    def test_segment_exclusive(self):
        s1 = Segment([[0, 10], [20, 30], [50, 100]])
        s2 = Segment([[4, 6], [15, 25], [40, 200]])
        s1 = s1.exclusive(s2)
        np.testing.assert_array_equal(s1._data, np.array([[0, 4], [6, 10], [25, 30]]))

    def test_segment_exclusive_2(self):
        s1 = Segment([[0, 10], [20, 30], [50, 100]])
        s2 = Segment([[4, 6], [15, 25], [40, 200]])
        s3 = Segment([[8, 20], [35, 60], [150, 180]])
        self.assertEqual(s1 & ~s2 & ~s3, s1.exclusive(s2, s3))

    def test_segment_union(self):
        s1 = Segment([[0, 10], [20, 30], [50, 100]])
        s2 = Segment([[4, 6], [15, 25], [40, 200]])
        s1 = s1.union(s2)
        np.testing.assert_array_equal(
            s1._data, np.array([[0, 10], [15, 30], [40, 200]])
        )

    def test_segment_union_2(self):
        s1 = Segment([[0, 10], [20, 30], [50, 100]])
        s2 = Segment([[4, 6], [15, 25], [40, 200]])
        s3 = Segment([[8, 20], [35, 60], [150, 180]])
        self.assertEqual(s1 | s2 | s3, s1.union(s2, s3))

    def test_segment_intersection(self):
        s1 = Segment([[0, 10], [20, 30], [50, 100]])
        s2 = Segment([[4, 6], [15, 25], [40, 200]])
        s1 = s1.intersection(s2)
        np.testing.assert_array_equal(s1._data, np.array([[4, 6], [20, 25], [50, 100]]))

    def test_segment_intersection_2(self):
        s1 = Segment([[0, 10], [20, 30], [50, 100]])
        s2 = Segment([[4, 6], [15, 25], [40, 200]])
        s3 = Segment([[8, 20], [35, 60], [150, 180]])
        self.assertEqual(s1 & s2 & s3, s1.intersection(s2, s3))

    def test_segment_difference(self):
        s1 = Segment([[0, 10], [20, 30], [50, 100]])
        s2 = Segment([[4, 6], [15, 25], [40, 200]])
        s1 = s1.difference(s2)

        np.testing.assert_array_equal(
            s1._data,
            np.array([[0, 4], [6, 10], [15, 20], [25, 30], [40, 50], [100, 200]]),
        )

def load_tests(loader, tests, ignore):
    tests.addTests(doctest.DocTestSuite(fklab.segments.segment))
    return tests

if __name__ == "__main__":
    unittest.main()


def main_door():
    print("\n A heavy door looms before you")
    main_door_choice = input(
        "\n Do you want to knock on the door ? (Yes/No) \n >")
    if main_door_choice == "No":
        print("\n You suddenly hear a noise at the window to your left.")
        print("\n You peek through the window")
        print("\n You observe through the thin curtain, many paintings of richly dressed men"
              "and women as well as the end of a long dining table")
    elif main_door_choice == "Yes":
        print("\n You hear the sound of a plate getting smashed")
        main_door_choice_2 = input(
            "\n Do you want to retry knock on the door ? (Yes/No) \n >")
        if main_door_choice_2 == "Yes":
            print("\nNobody seems to answer you")
    else:
        print("\n Should be Yes or No")
        main_door()

def wait():
    wait_choice = input("\n Do you want to try to wait? (Yes/No) \n >")
    if wait_choice == "Yes":
        print("\n You are waiting")
        wait()
    elif wait_choice == "No":
        print("\n You try to find a way in")
        print("\n After several minutes you discover another door at the back of the house")
    else:
        print("\n Should be Yes or No")
        wait()

def phase_three():
    main_door()
    wait()


print("Advent 2.a")

inputFile = open('input.txt', 'r')
inputList = inputFile.read().strip().split()
inputFile.close()
totals = [0,0]

def findDuplicates():
	for line in inputList:
		characters = list(line)
		characters.sort()
		duplicatesFound = False
		triplicatesFound = False

		letterCount = 1
		lastLetter = ''
		for letter in characters:
			if letter == lastLetter:
				letterCount = letterCount + 1
			else:
				lastLetter = letter
				duplicatesFound = duplicatesFound or isDuplicates(letterCount)
				triplicatesFound = triplicatesFound or isTriplicates(letterCount)
				letterCount = 1

		duplicatesFound = duplicatesFound or isDuplicates(letterCount)
		triplicatesFound = triplicatesFound or isTriplicates(letterCount)

def isDuplicates(letterCount):
	if letterCount == 2:
		totals[0] = totals[0] + 1
		return True

	return False

def isTriplicates(letterCount):
	if letterCount == 3:
		totals[1] = totals[1] + 1
		return True
	return False

findDuplicates()

#test = map(countXinARow, inputList)
print('twos: %d, threes: %d, multipled: %d' % (totals[0], totals[1], totals[0]*totals[1]))