import os
import time

import cv2
import numpy as np
import torch
import torch.backends.cudnn as cudnn
import torch.multiprocessing
import torch.optim
import torch.utils.data
import torch.utils.data.distributed
import torchvision.transforms

from EfficientHRNet.EfficientHRNet_Main import get_pose_net
from EfficientHRNet.lib.core.group import HeatmapParser
from EfficientHRNet.lib.utils.inference import get_outputs
from EfficientHRNet.lib.utils.transforms import get_final_preds
from EfficientHRNet.lib.utils.transforms import resize

from sklearn.ensemble import IsolationForest
import numpy as np
from EfficientHRNet.DetectionRegresser import DetectionRegresser

'''
def infer_efficient(net, img, net_input_height_size, stride, upsample_ratio, cpu,
               pad_value=(0, 0, 0), img_mean=(128, 128, 128), img_scale=1/256):
    height, width, _ = img.shape
    scale = net_input_height_size / height
    scaled_img = cv2.resize(img, (0, 0), fx=scale, fy=scale, interpolation=cv2.INTER_CUBIC)
    scaled_img = normalize(scaled_img, img_mean, img_scale)
    min_dims = [net_input_height_size, max(scaled_img.shape[1], net_input_height_size)]
    padded_img, pad = pad_width(scaled_img, stride, pad_value, min_dims)

    tensor_img = torch.from_numpy(padded_img).permute(2, 0, 1).unsqueeze(0).float()
    if not cpu:
        tensor_img = tensor_img.cuda()
    stages_output = net(tensor_img)
    stage2_heatmaps = stages_output[-2]
    heatmaps = np.transpose(stage2_heatmaps.squeeze().cpu().data.numpy(), (1, 2, 0))
    heatmaps = cv2.resize(heatmaps, (0, 0), fx=upsample_ratio, fy=upsample_ratio, interpolation=cv2.INTER_CUBIC)
    stage2_pafs = stages_output[-1]
    pafs = np.transpose(stage2_pafs.squeeze().cpu().data.numpy(), (1, 2, 0))
    pafs = cv2.resize(pafs, (0, 0), fx=upsample_ratio, fy=upsample_ratio, interpolation=cv2.INTER_CUBIC)

    return heatmaps, pafs, scale, pad
'''

class EfficientHRNetKeypoints:
    def __init__(self, pose_cfg,defaults_dict):
        self.colors = []
        self.pose_cfg = pose_cfg
        self.net = get_pose_net(pose_cfg, is_train=False)
        self.net.load_state_dict(torch.load(self.pose_cfg.TEST.MODEL_FILE, map_location='cpu'), strict=True)
        self.net.eval()
        self.eval_set = 2
        # self.net.cuda()
        self.d = dict()
        self.dr = DetectionRegresser(0, defaults_dict['window_length'], defaults_dict['iou_threshold'],
                                     defaults_dict['forgetfulness'], defaults_dict['regress_type'])
        self.parser = HeatmapParser(self.pose_cfg)
        cudnn.benchmark = self.pose_cfg.CUDNN.BENCHMARK
        torch.backends.cudnn.deterministic = self.pose_cfg.CUDNN.DETERMINISTIC
        torch.backends.cudnn.enabled = self.pose_cfg.CUDNN.ENABLED

        self.transforms = torchvision.transforms.Compose(
            [
                torchvision.transforms.ToTensor(),
                torchvision.transforms.Normalize(
                    mean=[0.485, 0.456, 0.406],
                    std=[0.229, 0.224, 0.225]
                )  # ,
                # torchvision.transforms.Resize(cfg.DATASET.INPUT_SIZE)
            ]
        )

    def runPoseEstimation(self, image):
        # final_heatmaps = None
        # tags_list = []

        image_resized, center, scale = resize(
            image, self.pose_cfg.DATASET.INPUT_SIZE
        )
        image_resized = self.transforms(image_resized)
        image_resized = image_resized.unsqueeze(0)  # .cuda()

        t = time.time()
        outputs, heatmaps, tags = get_outputs(
            self.pose_cfg, self.net, image_resized, with_flip=False,
            project2image=self.pose_cfg.TEST.PROJECT2IMAGE
        )
        t = time.time() - t
        # print(f'{t:.5f}')
        grouped, scores = self.parser.parse(
            heatmaps, tags, self.pose_cfg.TEST.ADJUST, self.pose_cfg.TEST.REFINE
        )
        final_results = get_final_preds(
            grouped, center, scale,
            [heatmaps.size(3), heatmaps.size(2)]
        )
        # filters redundant poses

        final_pts = []
        for i in range(len(final_results)):
            final_pts.insert(i, list())
            for pts in final_results[i]:
                if len(final_pts[i]) > 0:
                    diff = np.mean(np.abs(np.array(final_pts[i])[..., :2] - pts[..., :2]))
                    if np.any(diff < 3):
                        final_pts[i].append([-1, -1, pts[2], pts[3]])
                        continue
                final_pts[i].append(pts)
        final_results = final_pts
        for idx in range(len(final_results)):
            final_results[idx] = np.concatenate(final_results[idx], axis=0)
            final_results[idx] = np.reshape(final_results[idx], (-1, 4))
        # print("Final results after filter", len(final_results))

        keypoints = []
        h_scores = []
        x_coordinates = []
        y_coordinates = []
        for idx in range(len(final_results)):
            key_temp = []
            x_temp = []
            y_temp = []
            h_temp = []
            for i in range(len(final_results[idx])):
                keypoint = final_results[idx][i, :2]
                key_temp.append(keypoint)
                x_coor = final_results[idx][i, 0]
                x_temp.append(x_coor)
                y_coor = final_results[idx][i, 1]
                y_temp.append(y_coor)
                h_score = final_results[idx][i, 2]
                h_temp.append(h_score)

            keypoints.append(key_temp)
            x_coordinates.append(x_temp)
            y_coordinates.append(y_temp)
            h_scores.append(h_temp)
            keypoints[idx] = np.concatenate(keypoints[idx], axis=0)
            keypoints[idx] = np.reshape(keypoints[idx], (-1, 2))
        return keypoints, x_coordinates, y_coordinates, h_scores

    # this class should be here to pass data directly
    def getEfficientHRNetPoseData(self, image, outlier_thresh=-0.1, heatmap_th=0.075):
        # Calculate poses and regress bounding boxes from keypoints
        valid_keypoint_perc = []
        keypoints, x_coordinates, y_coordinates, h_scores = self.runPoseEstimation(image)
        bboxes = []
        final_keypoints = []

        # Iterate through each predicted person
        # TODO: if this code will be persisting for a while we may want to swtich
        #   to an enumerate(keypoints) for-each approach in the interest of legibility
        for idx in range(len(keypoints)):
            ####### Remove Outliers
            # Reshape this person's keypoint coordinates to n*2 array
            temp_xy = list(zip(x_coordinates[idx], y_coordinates[idx]))

            # Use scikit's IsolationForest to score how well each keypoint fits in this group
            clf = IsolationForest(random_state=0).fit(temp_xy)
            clf_scores = clf.decision_function(temp_xy)

            # Apply thresholding to remove outliers
            for clf_idx in range(len(clf_scores)):
                if clf_scores[clf_idx] < outlier_thresh:
                    keypoints[idx][clf_idx][0] = -1
                    keypoints[idx][clf_idx][1] = -1
            ####### End Remove Outliers

            num_found_keypoints = 0

            # Keep track of valid x,y to find bbox bounds
            x_ax = []
            y_ax = []

            # Iterate through this person's keypoints
            for i in range(len(keypoints[idx])):
                # Ignore thresholded outlier keypoints
                if (keypoints[idx][i][0] and keypoints[idx][i][1]) != -1:
                    # Ignore thresholded heatmap keypoints (?)
                    if h_scores[idx][i] >= heatmap_th:
                        num_found_keypoints += 1
                        x_coor = x_coordinates[idx][i]
                        x_ax.append(x_coor)
                        y_coor = y_coordinates[idx][i]
                        y_ax.append(y_coor)

            # Create a bbox only if valid keypoints have been found
            if len(x_ax) > 0 and len(y_ax) > 0:
                x_min = np.amin(x_ax)
                y_min = np.amin(y_ax)
                width = np.amax(x_ax) - x_min
                height = np.amax(y_ax) - y_min
                if (height >= width):
                    bboxes.append([x_min, y_min, width, height])
                    valid_keypoint_perc.append(num_found_keypoints / len(keypoints[idx]))
                    final_keypoints.append(keypoints[idx])

        # Run linear regression
        if final_keypoints is not None and bboxes is not None:
            self.dr.update(bboxes, final_keypoints, valid_keypoint_perc)
            try:
                bboxes, final_keypoints, valid_keypoint_perc = self.dr.predict()
            except TypeError:
                # this is only an issue if the DR has dropped detections (aka there were some, now none)
                if len(bboxes) > 0:
                    print('DetectionRegresser.predict() returned None!')

        bboxes = np.array(bboxes)
        final_keypoints = np.array(final_keypoints)
        valid_keypoint_perc = np.array(valid_keypoint_perc)
        return bboxes, final_keypoints, valid_keypoint_perc

    def draw_bboxes_and_keypoints(self,keypoints,bboxes,image):
        image_crops_list = []
        image1 = image.copy()
        self.d.clear()
        for i in range(len(bboxes)):
            color = (np.random.randint(0, 255), np.random.randint(0, 255), np.random.randint(0, 255))
            x, y, w, h = bboxes[i]
            x, y, w, h = int(x), int(y), int(w), int(h) #rectangle
            x1 = x
            y1 = y
            x2, y2 = x1 + w, y1 + h
            x1,y1,x2,y2 = x1-10,y1-10,x2+10,y2+10
            check_keypoints = True
            for j in keypoints[i]:
                x, y = j
                x, y = int(round(x,0)), int(round(y,0))
                if x<0 or y<0:
                    continue
                if not(x1 <= x <= x2 and y1 <= y <= y2):
                    #pass
                    check_keypoints=False #if you disable this then check for bb won't be performed
                    print('failed for BB :{} ,({},{})<=({},{})<=({},{})'.format(i,x1,y1,x,y,x2,y2))

            if check_keypoints:
                for j in keypoints[i]:
                    x, y = j
                    x, y = int(round(x, 0)), int(round(y, 0))
                    image = cv2.circle(image, (x, y), 2, color, 2)
                x1,y1,x2,y2 = x1+10,y1+10,x2-10,y2-10
                image = cv2.rectangle(image, (x1, y1), (x2, y2), color, 2)
                image_crops_list.append(image[y:y + h, x:x + w])
            else:
                self.d[i]='DELETE'

        return image, image_crops_list

    def draw_bboxes(self, bboxes, image):
        image_crops_list = []
        i = 0
        for box in bboxes:
            x, y, w, h = box
            x, y, w, h = int(x), int(y), int(w), int(h)
            image = cv2.rectangle(image, (x, y), (x + w, y + h), self.colors[i], 2)
            image_crops_list.append(image[y:y + h, x:x + w])
            i+=1
        return image, image_crops_list

    def draw_keypoints(self, keypoints, image):
        for i in keypoints:
            color = (np.random.randint(0, 255), np.random.randint(0, 255), np.random.randint(0, 255))
            self.colors.append(color)
            for j in i:
                x, y = j
                x, y = int(x), int(y)
                image = cv2.circle(image, (x, y), 2, color, 2)
        return image

    # Draw colored pose skeleton on the image frame
    def drawFramePoses(self, frame, image, ObjectHistoryList):

        for objhist in ObjectHistoryList:
            if (self.eval_set % 2 == 0):
                image = self.drawPoseCOCO18(image, objhist)

        return image

    # Draw one skeleton on the image frame
    def drawPoseCOCO18(self, image, objhist):
        kp_pairs = [[14, 16],
                    [13, 15],
                    [12, 14],
                    [11, 13],
                    [6, 8],
                    [8, 10],
                    [5, 7],
                    [7, 9],
                    [1, 3],
                    [2, 4],
                    [3, 5],
                    [4, 6],
                    [0, 1],
                    [0, 2],
                    [5, 11],
                    [6, 12],
                    [5, 6],
                    [11, 12]]

        keypoints = objhist.keypoints
        personID = objhist.sendObject

        if (objhist.reIDFlag == 1):
            coloridx = int(personID.label % 9)
            colorlist = bbox_colors[coloridx]
        else:
            colorlist = grey_box

        bbox = xywh2xyxy(personID.bbox)
        start_point = (bbox[0], bbox[1])
        color = (colorlist[0], colorlist[1], colorlist[2])
        font = cv2.FONT_HERSHEY_SIMPLEX
        scale = 0.7
        thickness = 2
        # id_label = str(int(personID.label / 1000000)) + "-{:01d}".format(int(personID.label % 1000000))
        # id_label = '{:d}'.format(int(personID.label / 1000000))
        # image = cv2.putText(image, id_label, start_point, font, scale, color, thickness)

        for pair in kp_pairs:
            # print(keypoints.shape)
            kp0 = keypoints[pair[0], :]
            kp1 = keypoints[pair[1], :]
            if (kp0[0] != -1) and (kp1[0] != -1):
                image = cv2.line(image, (int(kp0[0]), int(kp0[1])), (int(kp1[0]), int(kp1[1])), color, thickness)
            if (kp0[0] != -1):
                image = cv2.circle(image, (int(kp0[0]), int(kp0[1])), 3, color)
            if (kp1[0] != -1):
                image = cv2.circle(image, (int(kp1[0]), int(kp1[1])), 3, color)

        return image

    def things_to_do(self, image, image_output_path, frame):

        # 1) Getting Keypoints From Efficient HR Net
        bboxes, final_keypoints, valid_keypoints = self.getEfficientHRNetPoseData(image)
        # 2) Drawing bounding boxes and getting image crops list
        #image, image_crops_list = self.draw_bboxes(bboxes, image)
        # 3) Drawing Keypoints on image
        #image = self.draw_keypoints(final_keypoints, image)
        image,image_crops_list = self.draw_bboxes_and_keypoints(final_keypoints,bboxes,image)
        #image = self.drawFramePoses(final_keypoints,bboxes,image)
        # 4) Saving output to folder
        cv2.imwrite(image_output_path['EfficentHRNet'] + '/' + "{0:4d}".format(int(frame)) + '.jpg', image)

        for i in sorted(self.d.keys(),reverse=True):
            final_keypoints=np.delete(final_keypoints,i,axis=0)
            valid_keypoints=np.delete(valid_keypoints,i)
            bboxes=np.delete(bboxes,i,axis=0)
            #print(bboxes)

        return bboxes, final_keypoints, valid_keypoints, image, image_crops_list

    def run(self,frame,image,image_path,image_output_path):
        if image is not None:
            print("Efficient HRNet :- Processing Frame : {0:4d}".format(int(frame)))
            bboxes, final_keypoints, valid_keypoints, image, image_crops_list = self.things_to_do(image, image_output_path, frame)
            print("Efficient HRNet :- Completed Processing Frame : {0:4d}".format(int(frame)))
            return bboxes, final_keypoints, valid_keypoints, image, image_crops_list
        else:
            print("No Image Received " + image_path + '/' + "{0:4d}".format(int(frame)) + '.jpg')
            return None, None, None, None, None


import math
'''
side_1 float Перша сторона
side_2 float Друга сторона
angle float Кут між цими сторонами в радіанах
'''
#Ввести необхідні дані
side_1=float(input("Перша сторона : "))
side_2=float(input("Друга сторона : "))
angle=float(input("Кут між цими сторонами : "))
#Обчислення площі
s=0.5*side_1*side_2*math.sin(angle)
print ("Площа трикутника : {0}".format(s))


#!/usr/bin/env python3

import re
import sys
from datetime import datetime
from collections import namedtuple

import dateparser
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import matplotlib.lines
from scipy.interpolate import interp1d as interp
import numpy as np
import yaml

DATA_FILE = "data.yaml"
Datum = namedtuple("Datum", ["date", "age", "weight", "height", "bmi"])

UNIT_PATTERN = re.compile(r"(\d+(?:\.\d*)?|\.\d+)\s*(\w*)")
FT_IN_PATTERN = re.compile(r"(\d+)\s*(?:f|ft|foot|feet)\s*(\d+)\s*(?:i|in|inch|inches|inchs)?", re.I)

def parse_unit(rec):
    m = UNIT_PATTERN.match(rec)
    if not m:
        raise ValueError
    return m.groups()

def parse_feet_inches(rec):
    m = FT_IN_PATTERN.match(rec)
    if not m:
        raise ValueError
    return m.groups()

def parse_samples(samples, dob):
    data = []
    for sample in samples:
        print(sample)
        dateStr = sample['date']
        weightStr = sample['weight']
        heightStr = sample['height']

        d = dateparser.parse(dateStr, settings={'DATE_ORDER': 'DMY'})
        try:
            weight, wu = parse_unit(weightStr)
            if wu == 'kg':
                weight *= 0.453592
            else:
                print("warning: bad weight unit, expected kg or lb")
        except ValueError:
            print("error: bad weight record '%s'" % weightStr)
            continue

        try:
            height, hu = parse_unit(heightStr)
            if hu != 'cm':
                print("warning: bad height unit, expected cm or in")
        except ValueError:
            try:
                ft, inc = parse_feet_inches(heightStr)
                height = ft * 0.3048 + inc * 0.0254
            except ValueError:
                print("error: bad height record '%s'" % weightStr)
                continue

        delta = (d - dob)
        w = float(weight)
        h = float(height)
        bmi = w / (h/100)**2
        age = delta.total_seconds() / (365.2425 * 24 * 3600)
        age = int(age * 10) / 10.0
        data.append(Datum(d, age, w, h, bmi))
    return data

def main():
    with open(DATA_FILE, "r") as stream:
        root = yaml.safe_load(stream)
        dob = dateparser.parse(root['DOB'])
        data = parse_samples(root['samples'], dob)

    after = dob
    if len(sys.argv) > 1 and sys.argv[1].lower() == "after":
        after = dateparser.parse(' '.join(sys.argv[2:]))

    data = list(filter(lambda datum: datum.date >= after, data))

    #ax = plt.twiny()
    #TODO: interpolate dates
    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)

    maxy = int(max([max(d.weight, d.height, d.bmi) for d in data]) + 10)
    ax.set_yticks(list(range(0, maxy, 10)))
    ax.set_yticks(list(range(0, maxy, 5)), minor=True)

    interpolate = True
    if interpolate:
        ords = [x.date.toordinal() for x in data]
        fine = list(range(min(ords), max(ords)+1, 1))
        kind = "linear"
        #kind = "quadratic"
        height_interp = interp(ords, [x.height for x in data], kind=kind, fill_value="extrapolate")
        weight_interp = interp(ords, [x.weight for x in data], kind=kind, fill_value="extrapolate")
        wfit = np.polyfit(ords, [x.weight for x in data], 1)
        bfit = np.polyfit(ords, [x.weight / (x.height/100)**2 for x in data], 1)
        print("wfit:", wfit, "ords:", ords)
        #weight_interp = np.poly1d(wfit)

        hs = height_interp(fine)
        ws = weight_interp(fine)
        bms = ws / ((hs/100) ** 2)
        dws = np.diff(ws)
        dws = np.append(dws, dws[-1])
        dws = -dws * 100

        dates = [datetime.fromordinal(f) for f in fine]
        ax.plot_date(dates, hs, 'b-', label="Height in cm")
        ax.plot_date(dates, ws, 'r-', label="Weight in kg")
        ax.plot_date(dates, bms, 'g-', label="BMI")
        ax.plot_date(dates, dws, '-', label="-dW/d(decagrams per day)")

        #best fit 1d
        ords.append(ords[-1] + 100)
        ax.plot(ords, np.poly1d(wfit)(ords))
        ax.plot(ords, np.poly1d(bfit)(ords))

    else:
        #age
        xs = list(range(50))
        xt = [datetime(1995+i, 5, 24) for i in xs]
        #ax.set_xticks(xt, map(str, xs))

        #ax_age, ax_date = twiny();
        #x.set_xlabel("Age")

    #plots
    dates = [d.date for d in data]
    ax.plot_date(dates, [d.height for d in data], 'b.')
    ax.plot_date(dates, [d.weight for d in data], 'r.')
    ax.plot_date(dates, [d.bmi for d in data], 'g.')

    #yticks
    ax.grid(True, which="major", axis="y", ls="-", lw=1.0)
    ax.grid(True, which="minor", axis="y", ls="--", lw=0.5)

    #xticks
    years = mdates.YearLocator()
    months = mdates.MonthLocator()
    #ym_fmt = mdates.DateFormatter('%Y')
    month_fmt = mdates.DateFormatter('%b/%Y')
    ax.xaxis.set_major_locator(years)
    ax.xaxis.set_major_formatter(month_fmt)
    ax.xaxis.set_minor_locator(months)
    #ax.xaxis.set_minor_formatter(month_fmt)
    ax.grid(True, which="major", axis="x", ls="-", c="black", lw=1.5)
    ax.grid(True, which="minor", axis="x", ls="--", lw=0.5)

    #today
    today_x = matplotlib.dates.date2num(datetime.now())
    today = matplotlib.lines.Line2D([today_x, today_x], [-10, maxy], c="purple")
    ax.add_line(today)

    #bmi ranges
    bounds = [15, 18.5, 25, 30, 40, 50]
    cols = ["purple", "green", "yellow", "orange", "red"]
    for s, e, c in zip(bounds, bounds[1:], cols):
        ax.axhspan(s, e, color=c, alpha=0.4)

    ax.legend()
    plt.show()

if __name__ == "__main__":
    main()


#Sooter game code

#Creating the shooter character.
ShooterPlane = sprites.create(img("""
    ..ccc.........ffffff....
    ..f4cc.......fcc22ff....
    ..f44cc...fffccccff.....
    ..f244cccc22224442cc....
    ..f224cc2222222244b9c...
    ..cf222222222222b9999c..
    .c22c222222222911199b2c.
    f22ccccccc22229911b2222c
    fffffcc222c222222222222f
    .....f2224442222222222f.
    ....f222444fc2222222ff..
    ...c222444ffffffffff....
    ...c2222cfffc2f.........
    ...ffffffff2ccf.........
    .......ffff2cf..........
    ........fffff...........
"""), SpriteKind.player)

#Shooter stay on screen.
ShooterPlane.set_stay_in_screen(True)

#Set life to 4, game will if the shoot get hit by four bogeys.
info.set_life(8)

#Use the contorler buttons to move the shooter plane across the screen.
controller.move_sprite(ShooterPlane, 200, 200)

#When button A pressed, a Shooter will shoot a misslie towards enemy.
def on_event_pressed():
    missile = sprites.create_projectile_from_sprite(img("""
        . . . . . . . . . . . . . . . .
        . . . . . . . . . . . . . . . .
        . . . . . . . . . . . . . . . .
        . . . . . . . . . . . . . . . .
        . . . . . . . . . . . . . . . .
        . . . . . . . . . . . . . . . .
        . . . . . . . 4 4 . . . . . . .
        . . . . . . 4 5 5 4 . . . . . .
        . . . . . . 2 5 5 2 . . . . . .
        . . . . . . . 2 2 . . . . . . .
        . . . . . . . . . . . . . . . .
        . . . . . . . . . . . . . . . .
        . . . . . . . . . . . . . . . .
        . . . . . . . . . . . . . . . .
        . . . . . . . . . . . . . . . .
        . . . . . . . . . . . . . . . .
    """), ShooterPlane, 200, 0)
controller.A.on_event(ControllerButtonEvent.PRESSED, on_event_pressed)

#Every half a second an enemy bogey will pop up from the right edge of the screen.
def on_update_interval():
    bogey1 = sprites.create(img("""
        . . . . . . . . . c c 8 . . . .
        . . . . . . 8 c c c f 8 c c . .
        . . . c c 8 8 f c a f f f c c .
        . . c c c f f f c a a f f c c c
        8 c c c f f f f c c a a c 8 c c
        c c c b f f f 8 a c c a a a c c
        c a a b b 8 a b c c c c c c c c
        a f c a a b b a c c c c c f f c
        a 8 f c a a c c a c a c f f f c
        c a 8 a a c c c c a a f f f 8 a
        . a c a a c f f a a b 8 f f c a
        . . c c b a f f f a b b c c 6 c
        . . . c b b a f f 6 6 a b 6 c .
        . . . c c b b b 6 6 a c c c c .
        . . . . c c a b b c c c . . . .
        . . . . . c c c c c c . . . . .
    """), SpriteKind.enemy)

    #Setting how fast the bogey move accross the screen.
    bogey1.set_velocity(-80, 0)

    #Bogey will appear on the lft side of the screen.
    bogey1.left = scene.screen_width()
    bogey1.y = randint (0, scene.screen_height())

    #The nemey bogey will self destroy when it reach the end of the screen.
    bogey1.set_flag(SpriteFlag.AUTO_DESTROY, True)

game.on_update_interval(500, on_update_interval)

#Creating a second bogey; small and fast.
def on_update_interval2():
    bogey2 = sprites.create(img("""
        . . . b b . . .
        . . b 5 5 b . .
        . b 5 1 d 5 b .
        . b 5 1 3 5 b .
        . c d 1 3 5 c .
        . c d d 1 5 c .
        . . f d d f . .
        . . . f f . . .
    """), SpriteKind.enemy)

    #Setting how fast the bogey move accross the screen.
    bogey2.set_velocity(-150, 0)

    #Bogey will appear on the lft side of the screen.
    bogey2.left = scene.screen_width()
    bogey2.y = randint (0, scene.screen_height())

    #The emey bogey will self destroy when it reach the end of the screen.
    bogey2.set_flag(SpriteFlag.AUTO_DESTROY, True)

game.on_update_interval(2000, on_update_interval2)

#Creating the overlap event bogey and the ShooterPlane.
def on_overlap1(ShooterPlane, bogey1):
    bogey1.destroy()
    #On overlap, screen will shake, palyer will lose one life.
    ShooterPlane.start_effect(effects.ashes)
    info.change_life_by(-1)
sprites.on_overlap(SpriteKind.player, SpriteKind.enemy, on_overlap1)

#Creating the overlap event bogey and the ShooterPlane.
def on_overlap2(ShooterPlane, bogey2):
    bogey2.destroy()
    #On overlap, screen will shake, palyer will lose one life.
    ShooterPlane.start_effect(effects.fire)
    scene.camera_shake()
    info.change_life_by(-1)
sprites.on_overlap(SpriteKind.player, SpriteKind.enemy, on_overlap2)

#Creating the overlap event, missile and the bogey1.
def on_overlap3(missile, bogey):
    #On overlap, the bogey will destroy, player scores one point.
    bogey.destroy()
    bogey.start_effect(effects.fire)
    info.change_score_by(1)
sprites.on_overlap(SpriteKind.projectile, SpriteKind.enemy, on_overlap3)

#Creating the overlap event, missile and the bogey2.
def on_overlap4(missile, bogey):
    #On overlap, the bogey2 will destroy, player scores 2 point.
    bogey.destroy()
    bogey.start_effect(effects.fire)
    info.change_score_by(2)
sprites.on_overlap(SpriteKind.projectile, SpriteKind.enemy, on_overlap4)


import threading
import time

def handler(value_start=0, value_finish=0):
    print("handler is working")
    result = 0
    for i in range(value_start, value_finish):
        result += 1
    print("Result: ", result)

params_1 = {"value_finish": 2 ** 26}
task_1 = threading.Thread(target=handler, kwargs=params_1)

print("starting task_1")
time_start = time.time()
task_1.start()
print("joining task_1 to main thread")
task_1.join()     # <-- this line joins task_1 thread to main thread (main thread cant continue till task_1 finish its work)
print(f"time for task_1: {time.time() - time_start}")

print("\nstarting handler")
time_start = time.time()
handler(**params_1)
print(f"time for task_1: {time.time() - time_start}")


from PIL import Image
import argparse
import json
import numpy as np
import tensorflow as tf
import tensorflow_hub as hub

########################
# Function definitions #
########################

# Takes an image as a numpy, resizes to 224x224, and scales to a float value from 0 to 1
def process_image(image):
    tf_image = tf.convert_to_tensor(image)
    tf_image = tf.image.resize(tf_image, (224, 224))
    tf_image = tf.cast(tf_image, tf.float32)
    tf_image /= 255.
    return tf_image.numpy()

# Takes an image path, a loaded model, and an integer top_k, and calculates the top_k
# most likely classes and associated probabilities
def predict(image_path, model, top_k):
    image = Image.open(image_path)
    processed_image = process_image(np.asarray(image)) # shape (224, 224, 3)

    expanded_image = np.expand_dims(processed_image, axis=0) # shape (1, 224, 224, 3)
    prediction = model.predict(expanded_image)[0]
    int_labels = np.flip(np.argsort(prediction)) # gets the integer labels (0 to 101) from highest to lowest priority
    int_labels = int_labels[:top_k] # gets the highest top_k integer labels from highest to top_k-th highest priority
    classes = [str(i+1) for i in int_labels]

    probs = np.take(prediction, int_labels)
    return probs, classes

########
# Main #
########

# Parse arguments
parser = argparse.ArgumentParser(
    description='This script uses a pre-trained image classifier to classify flowers.',
)

parser.add_argument('image_path', action="store")
parser.add_argument('saved_model', action="store")
parser.add_argument('--top_k', action="store", nargs='?', metavar='K', default=5, type=int)
parser.add_argument('--category_names', action="store", nargs='?', default='label_map.json')

args = parser.parse_args()

# Load and build model
model = tf.keras.experimental.load_from_saved_model(args.saved_model, custom_objects={'KerasLayer':hub.KerasLayer})
model.build((None, 224, 224, 3))

# Predict top_k probabilities and classes
probs, classes = predict(args.image_path, model, args.top_k)

# Load class names
with open(args.category_names, 'r') as f:
    class_names = json.load(f)

# Map classes to names
named_classes = [class_names[key] for key in classes]

# Build result to print
result = {}
for label, probability in zip(named_classes, probs):
    result[label] = '{:.2%}'.format(probability)

# Print results
print("=============================================================================================")
print("The model predicts the following classes with associated probabilities as being most likely: ")
for key, value in result.items():
    print(f"\t{key}: {value}")


from __future__ import annotations

import re
from typing import Union, Any, Iterable, Optional, List

from stereotype.fields.annotations import AnnotationResolver
from stereotype.fields.base import Field
from stereotype.utils import Missing, ConfigurationError, PathErrorType, ValidationContextType, Validator

class _AtomicField(Field):
    atomic = True

    def init_from_annotation(self, parser: AnnotationResolver):
        if parser.annotation is not self.type:
            raise parser.incorrect_type(self)

class BoolField(_AtomicField):
    """
    Boolean value (annotation ``bool``), accepting boolean values or true/yes/false/no strings.

    :param default: Means the field isn't required, used as default directly or called if callable
    :param hide_none: If the field's value is None, it will be hidden from serialized output
    :param hide_false: If the field's value is False, it will be hidden from serialized output
    :param primitive_name: Changes the key used to represent the field in serialized data - input or output
    :param to_primitive_name: Changes the key used to represent the field in serialized data - output only
    :param validators: Optional list of validator callbacks - they raise ``ValueError`` if the value is invalid
    """

    __slots__ = Field.__slots__
    type = bool
    type_repr = 'bool'
    empty_value = False

    def __init__(self, *, default: Any = Missing, hide_none: bool = False, hide_false: bool = False,
                 primitive_name: Optional[str] = Missing, to_primitive_name: Optional[str] = Missing,
                 validators: Optional[List[Validator]] = None):
        super().__init__(default=default, hide_none=hide_none, hide_empty=hide_false,
                         primitive_name=primitive_name, to_primitive_name=to_primitive_name, validators=validators)

    def convert(self, value: Any) -> Any:
        if value is Missing:
            return self._fill_missing()
        if value is None:
            return None
        if value is False or value is True:
            return value
        if value in {'true', 'True', 'yes', 'Yes'}:
            return True
        if value in {'false', 'False', 'no', 'No'}:
            return False
        raise TypeError('Value must be a boolean or a true/false/yes/no string value')

class _BaseNumberField(_AtomicField):
    __slots__ = Field.__slots__ + ('min_value', 'max_value')
    min_value: Union[int, float, None]
    max_value: Union[int, float, None]

    def _set_min_max_value_validation(self, min_value: Union[int, float, None], max_value: Union[int, float, None]):
        if min_value is not None and max_value is not None:
            self.native_validate = self._validate_min_max_value
        elif min_value is not None:
            self.native_validate = self._validate_min_value
        elif max_value is not None:
            self.native_validate = self._validate_max_value

    def _validate_min_max_value(self, value: Any, _: ValidationContextType) -> Iterable[PathErrorType]:
        if not (self.min_value <= value <= self.max_value):
            yield (), f'Must be between {self.min_value} and {self.max_value}'

    def _validate_min_value(self, value: Any, _: ValidationContextType) -> Iterable[PathErrorType]:
        if value < self.min_value:
            yield (), f'Must be at least {self.min_value}'

    def _validate_max_value(self, value: Any, _: ValidationContextType) -> Iterable[PathErrorType]:
        if value > self.max_value:
            yield (), f'Must be at most {self.max_value}'

class IntField(_BaseNumberField):
    """
    Integer value (annotation ``int``), accepting integer values, whole float values or strings with integer values.

    :param default: Means the field isn't required, used as default directly or called if callable
    :param hide_none: If the field's value is None, it will be hidden from serialized output
    :param hide_zero: If the field's value is 0, it will be hidden from serialized output
    :param primitive_name: Changes the key used to represent the field in serialized data - input or output
    :param to_primitive_name: Changes the key used to represent the field in serialized data - output only
    :param min_value: Validation enforces the number is greater than or equal to this value
    :param max_value: Validation enforces the number is lower than or equal to this value
    :param validators: Optional list of validator callbacks - they raise ``ValueError`` if the value is invalid
    """

    __slots__ = _BaseNumberField.__slots__
    type = int
    type_repr = 'int'
    empty_value = 0

    def __init__(self, *, default: Any = Missing, hide_none: bool = False, hide_zero: bool = False,
                 primitive_name: Optional[str] = Missing, to_primitive_name: Optional[str] = Missing,
                 min_value: Optional[int] = None, max_value: Optional[int] = None,
                 validators: Optional[List[Validator]] = None):
        super().__init__(default=default, hide_none=hide_none, hide_empty=hide_zero,
                         primitive_name=primitive_name, to_primitive_name=to_primitive_name, validators=validators)
        self.min_value = min_value
        self.max_value = max_value
        self._set_min_max_value_validation(min_value, max_value)

    def convert(self, value: Any) -> Any:
        if value is Missing:
            return self._fill_missing()
        if value is None:
            return None
        if isinstance(value, float) and value != int(value):
            raise TypeError(f'Numeric value {value} is not an integer')
        try:
            return int(value)
        except (ValueError, TypeError):
            raise TypeError(f'Value {value!r} is not an integer number')

class FloatField(_BaseNumberField):
    """
    Floating point value (annotation ``float``), accepting float values, integers or strings with float values.

    :param default: Means the field isn't required, used as default directly or called if callable
    :param hide_none: If the field's value is None, it will be hidden from serialized output
    :param hide_zero: If the field's value is 0.0, it will be hidden from serialized output
    :param primitive_name: Changes the key used to represent the field in serialized data - input or output
    :param to_primitive_name: Changes the key used to represent the field in serialized data - output only
    :param min_value: Validation enforces the number is greater than or equal to this value
    :param max_value: Validation enforces the number is lower than or equal to this value
    :param validators: Optional list of validator callbacks - they raise ``ValueError`` if the value is invalid
    """

    __slots__ = _BaseNumberField.__slots__
    type = float
    type_repr = 'float'
    empty_value = 0.

    def __init__(self, *, default: Any = Missing, hide_none: bool = False, hide_zero: bool = False,
                 primitive_name: Optional[str] = Missing, to_primitive_name: Optional[str] = Missing,
                 min_value: Optional[float] = None, max_value: Optional[float] = None,
                 validators: Optional[List[Validator]] = None):
        super().__init__(default=default, hide_none=hide_none, hide_empty=hide_zero,
                         primitive_name=primitive_name, to_primitive_name=to_primitive_name, validators=validators)
        self.min_value = min_value
        self.max_value = max_value
        self._set_min_max_value_validation(min_value, max_value)

class StrField(_AtomicField):
    """
    String value (annotation ``str``), accepting string values, or anything that can be cast to a string.

    :param default: Means the field isn't required, used as default directly or called if callable
    :param hide_none: If the field's value is None, it will be hidden from serialized output
    :param hide_empty: If the field's value is an empty string, it will be hidden from serialized output
    :param primitive_name: Changes the key used to represent the field in serialized data - input or output
    :param to_primitive_name: Changes the key used to represent the field in serialized data - output only
    :param min_length: Validation enforces the string has a minimum number of characters (1 => non-empty)
    :param max_length: Validation enforces the string has a maximum number of characters
    :param choices: Validation enforces the string matches (case-sensitive) one of these choices
    :param regex: Validation enforces the string matches the regular expression
    :param validators: Optional list of validator callbacks - they raise ``ValueError`` if the value is invalid
    """

    __slots__ = _AtomicField.__slots__ + ('min_length', 'max_length', 'choices', 'regex')
    type = str
    type_repr = 'str'
    empty_value = ''

    def __init__(self, *, default: Any = Missing, hide_none: bool = False, hide_empty: bool = False,
                 primitive_name: Optional[str] = Missing, to_primitive_name: Optional[str] = Missing,
                 min_length: int = 0, max_length: Optional[int] = None, choices: Optional[Iterable[str]] = None,
                 regex: str | re.Pattern | None = None, validators: Optional[List[Validator]] = None):
        super().__init__(default=default, hide_none=hide_none, hide_empty=hide_empty,
                         primitive_name=primitive_name, to_primitive_name=to_primitive_name, validators=validators)
        if sum([min_length > 0 or max_length is not None, choices is not None, regex is not None]) > 1:
            raise ConfigurationError('Can only validate length, choices or regex; not combinations of these')
        self.min_length = min_length
        self.max_length = max_length
        self.choices = {choice: None for choice in choices} if choices is not None else None  # Sets are not ordered
        self.regex = re.compile(regex) if isinstance(regex, str) else regex
        if self.choices is not None:
            self.native_validate = self._validate_choices
        elif min_length > 0 and max_length is not None:
            self.native_validate = self._validate_min_max_length
        elif min_length == 1:
            self.native_validate = self._validate_not_empty
        elif min_length > 0:
            self.native_validate = self._validate_min_length
        elif max_length is not None:
            self.native_validate = self._validate_max_length
        elif regex is not None:
            self.native_validate = self._validate_regex

    def _validate_choices(self, value: str, _: ValidationContextType) -> Iterable[PathErrorType]:
        if value not in self.choices:
            yield (), f'Must be one of: {", ".join(self.choices)}'

    def _validate_min_max_length(self, value: str, _: ValidationContextType) -> Iterable[PathErrorType]:
        if not (self.min_length <= len(value) <= self.max_length):
            if self.min_length == self.max_length:
                yield (), f'Must be exactly {self.min_length} character{"s" if self.min_length > 1 else ""} long'
            else:
                yield (), f'Must be {self.min_length} to {self.max_length} characters long'

    # Note: the validation methods that are put in place of native_validate may not be static
    # noinspection PyMethodMayBeStatic
    def _validate_not_empty(self, value: str, _: ValidationContextType) -> Iterable[PathErrorType]:
        if not value:
            yield (), 'This value cannot be empty'

    def _validate_min_length(self, value: str, _: ValidationContextType) -> Iterable[PathErrorType]:
        if len(value) < self.min_length:
            yield (), f'Must be at least {self.min_length} characters long'

    def _validate_max_length(self, value: str, _: ValidationContextType) -> Iterable[PathErrorType]:
        if len(value) > self.max_length:
            yield (), f'Must be at most {self.max_length} character{"s" if self.max_length > 1 else ""} long'

    def _validate_regex(self, value: str, _: ValidationContextType) -> Iterable[PathErrorType]:
        if not self.regex.match(value):
            case = " (case insensitive)" if self.regex.flags & re.I else ""
            yield (), f'Must match regex `{self.regex.pattern}`{case}'

ATOMIC_TYPE_MAPPING = {
    bool: BoolField,
    int: IntField,
    float: FloatField,
    str: StrField,
}


from model.ice_cream import IceCream
from typing import List
from model.sort_type import SortType

class DairyProductManagerUtils:

    def __init__(self, ice_cream_list: List[IceCream]):
        self.ice_cream_list = ice_cream_list

    def sort_by_warranty_period(self, sort_type: SortType) -> List[IceCream]:
        """
        Sorts list of ice-creams by warranty period

        >>> list_of_ice_cream = [IceCream( warranty_period_in_days=100), IceCream( warranty_period_in_days=120),\
                              IceCream( warranty_period_in_days=150),IceCream( warranty_period_in_days=80)]
        >>> util_manager=DairyProductManagerUtils(list_of_ice_cream)
        >>> ice_creams_sorted_by_warranty_period_ascending = util_manager.sort_by_warranty_period(SortType.ASCENDING)
        >>> [ice_cream.warranty_period_in_days for ice_cream in ice_creams_sorted_by_warranty_period_ascending]
        [80, 100, 120, 150]

        >>> ice_creams_sorted_by_warranty_period_descending = util_manager.sort_by_warranty_period(SortType.DESCENDING)
        >>> [ice_cream.warranty_period_in_days for ice_cream in ice_creams_sorted_by_warranty_period_descending]
        [150, 120, 100, 80]
        """

        if sort_type == SortType.ASCENDING:
            sorted_ice_creams = sorted(self.ice_cream_list, key=lambda ice_cream: ice_cream.warranty_period_in_days)
        elif sort_type == SortType.DESCENDING:
            sorted_ice_creams = sorted(self.ice_cream_list, key=lambda ice_cream: ice_cream.warranty_period_in_days,
                                       reverse=True)
        return sorted_ice_creams

    def sort_by_producer(self, sort_type: SortType) -> List[IceCream]:
        """
        Sorts ice-creams by name of their producer

        >>> list_of_ice_cream = [IceCream(producer="Limo"), IceCream(producer="Laska"),\
                              IceCream(producer="Rud"), IceCream(producer="Lasunka")]
        >>> util_manager=DairyProductManagerUtils(list_of_ice_cream)
        >>> ice_creams_sorted_by_producer_ascending = util_manager.sort_by_producer(SortType.ASCENDING)
        >>> [ice_cream.producer for ice_cream in ice_creams_sorted_by_producer_ascending]
        ['Laska', 'Lasunka', 'Limo', 'Rud']
         >>> ice_creams_sorted_by_producer_descending = util_manager.sort_by_producer(SortType.DESCENDING)
        >>> [ice_cream.producer for ice_cream in ice_creams_sorted_by_producer_descending]
        ['Rud', 'Limo', 'Lasunka', 'Laska']
        """
        if sort_type == SortType.ASCENDING:
            sorted_ice_creams = sorted(self.ice_cream_list, key=lambda ice_cream: ice_cream.producer)
        elif sort_type == SortType.DESCENDING:
            sorted_ice_creams = sorted(self.ice_cream_list, key=lambda ice_cream: ice_cream.producer,
                                       reverse=True)
        return sorted_ice_creams

if __name__ == "__main__":
    import doctest
    doctest.testmod(verbose=True)


from tally_ho.apps.tally.models.result_form import \
    sanity_check_final_results
from tally_ho.apps.tally.models.quality_control import QualityControl
from tally_ho.apps.tally.models.quarantine_check import QuarantineCheck
from tally_ho.libs.models.enums.entry_version import EntryVersion
from tally_ho.libs.tests.test_base import (
    create_reconciliation_form,
    create_result_form, create_result, create_candidates, create_audit,
    TestBase
    )

class TestResultForm(TestBase):
    def setUp(self):
        self._create_and_login_user()

    def test_quality_control(self):
        """Test result form quality control"""
        result_form = create_result_form()
        quality_control = QualityControl.objects.create(
            result_form=result_form,
            user=self.user
            )
        QualityControl.objects.create(
            result_form=result_form,
            user=self.user,
            active=False
            )

        self.assertEqual(result_form.qualitycontrol, quality_control)

    def test_reconciliation_match(self):
        """Test result form reconciliation match"""
        result_form = create_result_form()
        create_reconciliation_form(result_form, self.user)
        re_form = create_reconciliation_form(result_form, self.user)
        re_form.entry_version = EntryVersion.DATA_ENTRY_2
        re_form.save()

        self.assertTrue(result_form.reconciliation_match)

    def test_sanity_check_results(self):
        """Test sanity checks for final results"""
        votes = 12
        result_form = create_result_form()
        create_candidates(
            result_form, votes=votes, user=self.user,
            num_results=1
            )
        for result in result_form.results.all():
            result.entry_version = EntryVersion.FINAL
            result.save()
            # create duplicate final results
            create_result(result_form, result.candidate, self.user, votes)
        self.assertEqual(result_form.results_final.filter().count(), 4)
        sanity_check_final_results(result_form)
        self.assertEqual(result_form.results_final.filter().count(), 2)

    def test_audit_quarantine_check_name_property_method(self):
        """Test audit quarantine check name property method"""
        result_form = create_result_form()
        quarantine_check = QuarantineCheck.objects.create(
            user=self.user,
            name='1',
            method='1',
            value=1
            )
        audit = create_audit(result_form, self.user)
        audit.quarantine_checks.add(quarantine_check)
        self.assertQuerySetEqual(
            result_form.audit_quaritine_checks,
            audit.quarantine_checks.all().values('name')
            )


# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def recoverTree(self, root: Optional[TreeNode]) -> None:
        """
        Do not return anything, modify root in-place instead.
        """
        prev,curr,drops = TreeNode(float("-inf")), root, []
        while curr:
            if curr.left:
                temp = curr.left
                while temp.right and temp.right != curr:temp = temp.right
                if not temp.right:
                    temp.right,curr = curr,curr.left
                    continue
                temp.right = None
            if curr.val < prev.val: drops.append((prev,curr))
            prev,curr = curr, curr.right
        drops[0][0].val,drops[-1][-1].val = drops[-1][-1].val, drops[0][0].val


from bs4 import BeautifulSoup
import requests
import urllib.request
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time

source = "4C +01.02"  # Source name for which other catalog names should be found
driver = webdriver.Chrome() # Used Google Chrome WEB browser
driver.get("https://openuniverse.asi.it/open_universe.html") # This page is used for scraping
driver.maximize_window()
element = driver.find_element_by_id('stringa_inserita_su_homepage') #Firstly need to fill input tag of a web page with source name
element.send_keys(source)    # Tag ID of an input tag is "stringa_inserita_su_homepage "
time.sleep(2)    # Need a delay maybe connection is not good

#found_source = driver.find_element_by_id('page').click() # If source name is found click on a main page to see more about source
found_source=element.send_keys(Keys.RETURN)
time.sleep(1) # Wait 5 seconds

try:
    time.sleep(2) # Again wait 20 second the whole page should be loaded
    titles = driver.find_element(By.XPATH, '/html/body/div[1]/div/div[8]/table/tbody/tr/td[1]/div[1]/div[2]/a/span') #Find a span tag which contains other catalogs names
    html = titles.get_attribute('innerHTML') # Get inner text of tha span tag
    names = html.split("
") # Make a list using split function.
 tag was used for new line in HTML
    del names[-1] # Last
 tag replaced by "," and this should be deleted from the list
    print(names)
    driver.delete_all_cookies()
finally:
    driver.quit() # Anyway close the browser
#names =[ 'BZQJ2232+1143', 'PKS2230+114', 'WMAP47']

browser = webdriver.Chrome()
browser.get('http://www.google.com') # Search using all names in google.com
browser.maximize_window() #maximize chrome window after opening
clear_links=[] # gather all links in this list connected with source name
if names:
    for name in names:
       search = browser.find_element_by_name('q') # find search box
       search.send_keys(name) # fill search box with a source name
       search.send_keys(Keys.RETURN) # hit return after you entering source name
       time.sleep(2) # sleep for 5 seconds so you can see the results
       search_result = browser.find_elements_by_class_name("yuRUbf") #Each result has a class with name yuRUbf
       links = []
       for i in search_result:
           child = i.find_elements_by_tag_name("a") # separate  tags which contains searching result links
           for j in child:
               links.append(j.get_attribute('href')) #from  tag get only href
       browser.find_element_by_name('q').clear() # after filling search box and finding results clear searched name
       time.sleep(2)
       valid_links=[k for k in links if  "https://translate.google.com/" not in k] # links list contain other links which need to be removed
       if valid_links:
           for link in valid_links:
               clear_links.append(link)
browser.quit() # after getting all results close the browser
if clear_links:
    open_links = webdriver.Chrome() # then need to open browser again to open gathered links
    open_links.maximize_window()
    for info_link in range(len(clear_links)):
        open_links.get(clear_links[info_link])
        if (info_link != len(clear_links) - 1):
            open_links.execute_script("window.open('');") # open a new tab for each new link from clear_links
            chwd = open_links.window_handles
            open_links.switch_to.window(chwd[-1])
        time.sleep(2)


# -*- coding: utf-8 -*-
import scrapy
from scrapy.selector import Selector
from scrapy.spiders import CrawlSpider, Rule
from datetime import datetime
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
import time

class Yes24CrawlSpider(CrawlSpider):
    name = 'yes24_selenium'
    allowed_domains = ['yes24.com']
    start_urls = [
                'http://www.yes24.com/24/Category/Display/001001046001?ParamSortTp=01',
            ]

    def __init__(self):
        scrapy.Spider.__init__(self)
        self.driver = webdriver.Chrome('C:/chromedriver')
        # self.driver = webdriver.PhantomJS("C:/phantomjs-2.1.1-windows/phantomjs-2.1.1-windows/bin/phantomjs")

    def __del__(self):
        self.driver.close()

    def parse(self, response):
        pageNum = 3
        self.driver.get(response.url)
        time.sleep(1)
        for i in range(5):
            n = 1
            for j in range(20):
                try:
                    xpath = '//*[@id="category_layout"]/ul/li[%d]/div/div[1]/div[2]/a[1]' % n
                    elem = self.driver.find_element_by_xpath(xpath).click()
                except NoSuchElementException:
                    xpath = '//*[@id="category_layout"]/ul/li[%d]/div/div[1]/div[1]/a[1]' % n
                    elem = self.driver.find_element_by_xpath(xpath).click()
                n += 1
                time.sleep(3)
                html = self.driver.find_element_by_xpath('//*').get_attribute('outerHTML')
                selector = Selector(text=html)
                item = {}
                item['book_site'] = 'yes24'
                item['book_isbn'] = selector.xpath('//*[@id="infoset_specific"]/div[2]/div/table/tbody/tr[3]/td/text()')[0].extract()
                item["book_cat"] = selector.xpath('//*[@id="yLocation"]/div/div[3]/a/text()')[0].extract().strip()
                item["book_title"] = selector.xpath('//*[@id="yDetailTopWrap"]/div[2]/div[1]/div/h2/text()')[0].extract().strip()
                item["book_price"] = selector.xpath('//*[@id="yDetailTopWrap"]/div[2]/div[2]/div[1]/div[1]/table/tbody/tr[2]/td/span/em/text()')[0].extract()
                item["book_author"] = selector.xpath('//*[@id="yDetailTopWrap"]/div[2]/div[1]/span[2]/span[1]/a/text()')[0].extract().strip()
                item["book_publish"] = selector.xpath('//*[@id="yDetailTopWrap"]/div[2]/div[1]/span[2]/span[2]/a/text()')[0].extract()
                item["book_publish_date"] = selector.xpath('//*[@id="yDetailTopWrap"]/div[2]/div[1]/span[2]/span[3]/text()')[0].extract()
                item["book_img"] = selector.xpath('//*[@id="yDetailTopWrap"]/div[1]/div[1]/span/em/img/@src')[0].extract()
                item["book_url"] = self.driver.current_url
                item['book_img'] = item['book_img'] + ".jpg"
                item["crawl_time"] = datetime.now()
                yield item
                self.driver.execute_script('window.history.go(-1)')
            page = '//*[@id="cateSubWrap"]/div[2]/div[3]/div[2]/span[1]/div/a[%d]' % pageNum
            pageNum += 1
            elem = self.driver.find_element_by_xpath(page).click()


import torch.nn as nn
from torch import Tensor

from openspeech.modules.conformer_attention_module import MultiHeadedSelfAttentionModule
from openspeech.modules.conformer_convolution_module import ConformerConvModule
from openspeech.modules.conformer_feed_forward_module import FeedForwardModule
from openspeech.modules.residual_connection_module import ResidualConnectionModule

class ConformerBlock(nn.Module):
    r"""
    Conformer block contains two Feed Forward modules sandwiching the Multi-Headed Self-Attention module
    and the Convolution module. This sandwich structure is inspired by Macaron-Net, which proposes replacing
    the original feed-forward layer in the Transformer block into two half-step feed-forward layers,
    one before the attention layer and one after.

    Args:
        encoder_dim (int, optional): Dimension of conformer encoders
        num_attention_heads (int, optional): Number of attention heads
        feed_forward_expansion_factor (int, optional): Expansion factor of feed forward module
        conv_expansion_factor (int, optional): Expansion factor of conformer convolution module
        feed_forward_dropout_p (float, optional): Probability of feed forward module dropout
        attention_dropout_p (float, optional): Probability of attention module dropout
        conv_dropout_p (float, optional): Probability of conformer convolution module dropout
        conv_kernel_size (int or tuple, optional): Size of the convolving kernel
        half_step_residual (bool): Flag indication whether to use half step residual or not

    Inputs: inputs
        - **inputs** (batch, time, dim): Tensor containing input vector

    Returns: outputs
        - **outputs** (batch, time, dim): Tensor produces by conformer block.
    """

    def __init__(
        self,
        encoder_dim: int = 512,
        num_attention_heads: int = 8,
        feed_forward_expansion_factor: int = 4,
        conv_expansion_factor: int = 2,
        feed_forward_dropout_p: float = 0.1,
        attention_dropout_p: float = 0.1,
        conv_dropout_p: float = 0.1,
        conv_kernel_size: int = 31,
        half_step_residual: bool = True,
    ) -> None:
        super(ConformerBlock, self).__init__()
        if half_step_residual:
            self.feed_forward_residual_factor = 0.5
        else:
            self.feed_forward_residual_factor = 1

        self.sequential = nn.Sequential(
            ResidualConnectionModule(
                module=FeedForwardModule(
                    encoder_dim=encoder_dim,
                    expansion_factor=feed_forward_expansion_factor,
                    dropout_p=feed_forward_dropout_p,
                ),
                module_factor=self.feed_forward_residual_factor,
            ),
            ResidualConnectionModule(
                module=MultiHeadedSelfAttentionModule(
                    d_model=encoder_dim,
                    num_heads=num_attention_heads,
                    dropout_p=attention_dropout_p,
                ),
            ),
            ResidualConnectionModule(
                module=ConformerConvModule(
                    in_channels=encoder_dim,
                    kernel_size=conv_kernel_size,
                    expansion_factor=conv_expansion_factor,
                    dropout_p=conv_dropout_p,
                ),
            ),
            ResidualConnectionModule(
                module=FeedForwardModule(
                    encoder_dim=encoder_dim,
                    expansion_factor=feed_forward_expansion_factor,
                    dropout_p=feed_forward_dropout_p,
                ),
                module_factor=self.feed_forward_residual_factor,
            ),
            nn.LayerNorm(encoder_dim),
        )

    def forward(self, inputs: Tensor) -> Tensor:
        return self.sequential(inputs)


from card import Card
from deck import Deck

class Player:
    '''
    _deck – a reference to the deck of cards that both the player and the dealer use.
    _hand – a list of Cards that the player is currently holding.
    '''
    def __init__(self, deck) -> None:
        self._deck = deck
        self._hand = []
        for _ in range(2):
           self.hit()

    def hit(self):
        card = self._deck.draw_card()
        self._hand.append(card)
        self._hand.sort()

    def score(self):
        total_score = 0
        # card_values = [2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11]
        for card in self._hand:
            if card.rank == 'Ace':
                if total_score <= 11:
                    total_score += 11
                else:
                    total_score += 1
            elif card.rank in ['Jack', 'Queen', 'King']:
                total_score += 10
            else:
                total_score += int(card.rank)
        return total_score

    def __str__(self) -> str:
        cards = "\n".join([str(card) for card in self._hand])
        return (f'{cards}'
                f'\nScore = {self.score()}\n')
        # hand_str = ""
        # for card in self._hand:
        #     hand_str += str(card) + "\n"
        # return hand_str + 'Score = ' + str(self.score()) + "\n"


from enum import Enum
import numpy as np
import random

class DNAException(Exception):
  pass

class CrossoverType(Enum):
  N_POINT = 1
  N_POINT_WITH_IDENTITY = 2
  X_POINT = 3
  pass

class AbstractDNA():
  DICT_REPRESENTATION = 'representation'
  """Non functional DNA base class.

  Use this class as parent for your own dna representation.
  """

  def __init__(self, **kwargs):
    self._representation = kwargs.get(self.DICT_REPRESENTATION, None)
    self._crossover = None
    self._mutation = None
    self._distance = None
    pass

  def __hash__(self):
    return super(object, self).__hash__()

  def __eq__(self, other):
    if not isinstance(other, self.__class__):
      return False
    return self._representation == other._representation

  def __ne__(self, other):
    return not self.__eq__(other)

  def __getstate__(self):
    result = dict()
    result[self.DICT_REPRESENTATION] = self._representation
    return result

  def __setstate__(self, state):
    self.__init__(**state)

  def __mod__(self, probability):
    """
    DNA Mutation
    :param probability: Mutation probability [0,1]
    :return: new DNA object
    """
    if self._mutation is None:
      raise DNAException('ERROR: You need to assign a mutation function to _mutation!')
    return self._mutation(probability)

  def __pow__(self, DNA):
    """
    DNA Crossover
    :param DNA: other DNA object
    :return: Complementary offsprings
    """
    if not isinstance(DNA, self.__class__):
      raise DNAException('ERROR: You can only crossbreed DNA of the same type!')
    if self._crossover is None:
      raise DNAException('ERROR: You need to assign a crossover function to _crossover!')
    return self._crossover(DNA)

  def __sub__(self, DNA):
    """
    DNA Distance
    :param DNA: other DNA object
    :return: Distance of DNA objects
    """
    if not isinstance(DNA, self.__class__):
      raise DNAException('ERROR: You can only calculate the distance of DNA objects with the same type!')
    if self._crossover is None:
      raise DNAException('ERROR: You need to assign a distance function to _distance!')
    return self._distance(DNA)

  @property
  def representation(self):
    return self._representation

  pass

class IndirectLinearDNA(AbstractDNA):
  DICT_CROSSOVER_TYPE = 'crossover_type'
  DICT_POINTS = 'points'

  def __init__(self, **kwargs):
    super(IndirectLinearDNA, self).__init__(**kwargs)
    self._crossoverType = kwargs.get(self.DICT_CROSSOVER_TYPE, CrossoverType.N_POINT)
    self._points = kwargs.get(self.DICT_POINTS, 2)

  def __getstate__(self):
    result = super(IndirectLinearDNA, self).__getstate__()
    result[self.DICT_CROSSOVER_TYPE] = self._crossoverType
    result[self.DICT_POINTS] = self._points
    return result

  """
  Crossover functions for list based representations
  """

  def _cross_x_point(self, other):
    __len = min(len(self._representation), len(other._representation))

    positions = range(1, __len)
    positions = random.sample(positions, min(self._points, len(positions)))
    positions.sort()

    tmp1, tmp2 = self._representation, other._representation
    descendant_a, descendant_b = [], []

    prev_p = 0
    for p in positions:
      descendant_a += tmp1[prev_p:p]
      descendant_b += tmp2[prev_p:p]
      prev_p = p
      tmp1, tmp2 = tmp2, tmp1

    descendant_a += tmp1[prev_p:len(tmp1)]
    descendant_b += tmp2[prev_p:len(tmp2)]

    if random.random() > 0.5:
      descendant_a, descendant_b = descendant_b, descendant_a

    return [self._new_DNA(descendant) for descendant in [descendant_a, descendant_b]]

  def _cross_n_point(self, other):
    __len = min(len(self._representation), len(other._representation))
    while True:
      crossing = np.random.randint(2, size=__len)
      __sum = np.sum(crossing)
      if 0 < __sum < __len:
        break

    descendant_a = [p1 if b else p2 for p1, p2, b in zip(self._representation, other._representation, crossing)]
    descendant_b = [p2 if b else p1 for p1, p2, b in zip(self._representation, other._representation, crossing)]

    tail_1, tail_2 = self._representation[__len:len(self._representation)], other._representation[
                                                                            __len:len(other._representation)]
    if not crossing[-1]:
      tail_1, tail_2 = tail_2, tail_1

    descendant_a += tail_1
    descendant_b += tail_2

    return [self._new_DNA(descendant) for descendant in [descendant_a, descendant_b]]

  def _cross_n_point_u_identity(self, other):
    __len = min(len(self._representation), len(other._representation))
    crossing = np.random.randint(2, size=__len)
    descendant_a = [p1 if b else p2 for p1, p2, b in zip(self._representation, other._representation, crossing)]
    descendant_b = [p2 if b else p1 for p1, p2, b in zip(self._representation, other._representation, crossing)]

    tail_1, tail_2 = self._representation[__len:len(self._representation)], other._representation[
                                                                            __len:len(other._representation)]
    if not crossing[-1]:
      tail_1, tail_2 = tail_2, tail_1

    descendant_a += tail_1
    descendant_b += tail_2

    return [self._new_DNA(descendant) for descendant in [descendant_a, descendant_b]]

  def _new_DNA(self, representation):
    state = self.__getstate__()
    state[self.DICT_REPRESENTATION] = representation
    new = self.__class__(**state)
    return new

  pass

class MNIST625DNA(IndirectLinearDNA):
  class DistanceType(Enum):
    SEARCH_SPACE = 1
    PARAMETER_SPACE = 2

  class MutationType(Enum):
    NEIGHBOR = 1
    RANDOM = 2
    EXCLUSIVE = 3

  __conv = [3, 5, 7, 9, 11]
  __pool = [1, 2, 3, 4, 5]
  _search_mat = [__conv, __pool, __conv, __pool]

  def __init__(self, **kwargs):
    super(MNIST625DNA, self).__init__(**kwargs)
    if self._representation is None:
      self._representation = self._random_representation()

    self.__representation_indexed = np.asarray(
      [__values.index(a) for a, __values in zip(self._representation, self._search_mat)])

    self._crossover = {CrossoverType.N_POINT: self._cross_n_point,
                       CrossoverType.N_POINT_WITH_IDENTITY: self._cross_n_point_u_identity,
                       CrossoverType.X_POINT: self._cross_x_point,
                       }.get(self._crossoverType)

    self._mutationType = kwargs.get('mutation_type', MNIST625DNA.MutationType.NEIGHBOR)
    self._mutation = {MNIST625DNA.MutationType.NEIGHBOR: self.__mut_neighbor,
                      MNIST625DNA.MutationType.RANDOM: self.__mut_random,
                      MNIST625DNA.MutationType.EXCLUSIVE: self.__mut_exclusive,
                      }.get(self._mutationType)

    self._distanceType = kwargs.get('distance_type', MNIST625DNA.DistanceType.PARAMETER_SPACE)
    self._distance = {MNIST625DNA.DistanceType.PARAMETER_SPACE: self._distance_euclidean,
                      MNIST625DNA.DistanceType.SEARCH_SPACE: self.__distance_search_space,
                      }.get(self._distanceType)

  def __getstate__(self):
    result = super(MNIST625DNA, self).__getstate__()
    result['mutation_type'] = self._mutationType
    result['distance_type'] = self._distanceType
    return result

  def __setstate__(self, state):
    self.__init__(**state)

  def __hash__(self):
    return hash(tuple(self._representation))

  def __eq__(self, other):
    if not isinstance(other, self.__class__):
      return False
    return self._representation == other._representation

  def __ne__(self, other):
    if not isinstance(other, self.__class__):
      return True
    return self._representation != other._representation

  def _random_representation(self):
    conv1 = np.random.choice(self.__conv, 1)[0]
    pool1 = np.random.choice(self.__pool, 1)[0]
    conv2 = np.random.choice(self.__conv, 1)[0]
    pool2 = np.random.choice(self.__pool, 1)[0]
    return [conv1, pool1, conv2, pool2]

  """
  Distance
  """

  def _distance_euclidean(self, other):
    if not isinstance(other, self.__class__):
      return float('inf')
    d = np.linalg.norm(np.asarray(self._representation) - np.asarray(other._representation))
    return d

  def __distance_search_space(self, other):
    if not isinstance(other, self.__class__):
      return float('inf')
    d = np.linalg.norm(self.__representation_indexed - other.__representation_indexed)
    return d

  """
  Mutation
  """

  def __mut_neighbor(self, prob):
    representation = [__v[(__v.index(a) + int(np.sign(p))) % len(__v)] if abs(p) < prob else a
                      for p, a, __v in zip(np.random.uniform(-1, 1, size=len(self._representation)),
                                           self._representation, self._search_mat)]
    return [self._new_DNA(representation)]

  def __mut_exclusive(self, prob):
    representation = [random.choice([cp for i, cp in enumerate(t) if i != t.index(a)])
                      if a_p < prob else a for a_p, a, t in
                      zip(np.random.uniform(0, 1, size=len(self._representation)), self._representation,
                          self._search_mat)]
    return [self._new_DNA(representation)]

  def __mut_random(self, prob):
    new_dna = [random.choice(__values) if p < prob else a for p, a, __values in
               zip(np.random.uniform(0, 1, size=len(self._representation)), self._representation, self._search_mat)]
    return [self._new_DNA(new_dna)]

  pass

class MNIST625DNADual(MNIST625DNA):
  def __init__(self, **kwargs):
    super(MNIST625DNA, self).__init__(**kwargs)
    self._crossover = self.__cross_dual
    self._mutation = self.__mut_dual_2
    self._distance = self._distance_euclidean

    self.__dna_one = kwargs.get('dna_one')
    self.__dna_two = kwargs.get('dna_two')

    if not self.DICT_REPRESENTATION in kwargs:
      if not self.__dna_one:
        self.__dna_one = self._random_representation()
      if not self.__dna_two:
        self.__dna_two = self._random_representation()
      self._representation = random.choice([self.__dna_one, self.__dna_two])
      self.__representation_indexed = np.asarray(
        [__values.index(a) for a, __values in zip(self._representation, self._search_mat)])
    else:
      if not self.__dna_one or not self.__dna_two:
        raise DNAException('This Should not happen!')

    pass

  def __getstate__(self):
    result = super(MNIST625DNA, self).__getstate__()
    result['dna_one'] = self.__dna_one
    result['dna_two'] = self.__dna_two
    return result

  def __mut_dual(self, prob):
    representation = [random.choice([__v[(__v.index(a) + int(np.sign(p))) % len(__v)],
                                     b]) if abs(p) < prob else a
                      for p, a, b, __v in zip(np.random.uniform(-1, 1, size=len(self._representation)),
                                              self._representation,
                                              self.__dna_one if self._representation !=
                                                                self.__dna_one else self.__dna_two,
                                              self._search_mat)]
    state = self.__getstate__()
    state['representation'] = representation
    state['dna_one'] = self.__dna_one if self._representation != self.__dna_one else representation
    state['dna_two'] = self.__dna_two if self._representation != self.__dna_two else representation
    return [MNIST625DNADual(**state)]

  def __mut_dual_2(self, prob):
    prob_list = np.random.uniform(0, 1, size=len(self._representation))
    is_one = self._representation == self.__dna_one
    representation = [b if abs(p) < prob else a
                      for p, a, b in zip(prob_list,
                                         self._representation,
                                         self.__dna_two if is_one else self.__dna_one, )]
    rep = [a if abs(p) < prob else b
           for p, a, b in zip(prob_list,
                              self._representation,
                              self.__dna_two if is_one else self.__dna_one, )]

    state = self.__getstate__()
    state['representation'] = representation
    state['dna_one'] = rep if is_one else representation
    state['dna_two'] = representation if is_one else rep
    return [MNIST625DNADual(**state)]

  def __cross_dual(self, other):
    self_a, self_b = random.choice([(self.__dna_one, self.__dna_two), (self.__dna_two, self.__dna_one)])
    other_a, other_b = random.choice([(other.__dna_one, other.__dna_two), (other.__dna_two, other.__dna_one)])
    state = self.__getstate__()
    state['representation'] = None
    state['dna_one'] = self_a
    state['dna_two'] = other_a
    ind_a = MNIST625DNADual(**state)
    state = self.__getstate__()
    state['representation'] = None
    state['dna_one'] = self_b
    state['dna_two'] = other_b
    ind_b = MNIST625DNADual(**state)
    return [ind_a, ind_b]

  pass


from __future__ import division
# -*- coding: utf-8 -*-

import numpy as np

def multiclass_log_loss( y_true, y_pred, eps=1e-15 ):
    """
    Multi class version of Logarithmic Loss metric.
    https://www.kaggle.com/wiki/MultiClassLogLoss

    idea from this post:
    http://www.kaggle.com/c/emc-data-science/forums/t/2149/
        is-anyone-noticing-difference-betwen-validation-and-leaderboard-error/12209#post12209

	implementation adopted from ephes, cf.
	https://github.com/ephes/scikit-learn/blob/multiclass_log_loss/sklearn/metrics/metrics.py

    Parameters
    ----------
    y_true : array, shape = [ n_samples ]
    y_pred : array, shape = [ n_samples, n_classes ]

    Returns
    -------
    loss : float
    """
    predictions = np.clip( y_pred, eps, 1 - eps )
    predictions /= predictions.sum(axis=1)[:, np.newaxis]

    groundtruth = np.zeros( y_pred.shape )
    rows = groundtruth.shape[ 0 ]
    groundtruth[ np.arange(rows), y_true.astype(int) ] = 1
    logloss = np.sum( groundtruth * np.log( predictions ))
    return -1.0 / rows * logloss


import os
import signal
import time
import tempfile
import shutil
import asyncio

from openpype.hosts.tvpaint.api.communication_server import (
    BaseCommunicator,
    CommunicationWrapper
)
from openpype_modules.job_queue.job_workers import WorkerJobsConnection

from .worker_job import ProcessTVPaintCommands

class TVPaintWorkerCommunicator(BaseCommunicator):
    """Modified commuicator which cares about processing jobs.

    Received jobs are send to TVPaint by parsing 'ProcessTVPaintCommands'.
    """
    def __init__(self, server_url):
        super().__init__()

        self.return_code = 1
        self._server_url = server_url
        self._worker_connection = None

    def _start_webserver(self):
        """Create connection to workers server before TVPaint server."""
        loop = self.websocket_server.loop
        self._worker_connection = WorkerJobsConnection(
            self._server_url, "tvpaint", loop
        )
        asyncio.ensure_future(
            self._worker_connection.main_loop(register_worker=False),
            loop=loop
        )

        super()._start_webserver()

    def _open_init_file(self):
        """Open init TVPaint file.

        File triggers dialog missing path to audio file which must be closed
        once and is ignored for rest of running process.
        """
        current_dir = os.path.dirname(os.path.abspath(__file__))
        init_filepath = os.path.join(current_dir, "init_file.tvpp")
        with tempfile.NamedTemporaryFile(
            mode="w", prefix="a_tvp_", suffix=".tvpp"
        ) as tmp_file:
            tmp_filepath = tmp_file.name.replace("\\", "/")

        shutil.copy(init_filepath, tmp_filepath)
        george_script = "tv_LoadProject '\"'\"{}\"'\"'".format(tmp_filepath)
        self.execute_george_through_file(george_script)
        self.execute_george("tv_projectclose")
        os.remove(tmp_filepath)

    def _on_client_connect(self, *args, **kwargs):
        super()._on_client_connect(*args, **kwargs)
        self._open_init_file()
        # Register as "ready to work" worker
        self._worker_connection.register_as_worker()

    def stop(self):
        """Stop worker connection and TVPaint server."""
        self._worker_connection.stop()
        self.return_code = 0
        super().stop()

    @property
    def current_job(self):
        """Retrieve job which should be processed."""
        if self._worker_connection:
            return self._worker_connection.current_job
        return None

    def _check_process(self):
        if self.process is None:
            return True

        if self.process.poll() is not None:
            asyncio.ensure_future(
                self._worker_connection.disconnect(),
                loop=self.websocket_server.loop
            )
            self._exit()
            return False
        return True

    def _process_job(self):
        job = self.current_job
        if job is None:
            return

        # Prepare variables used for sendig
        success = False
        message = "Unknown function"
        data = None
        job_data = job["data"]
        workfile = job_data["workfile"]
        # Currently can process only "commands" function
        if job_data.get("function") == "commands":
            try:
                commands = ProcessTVPaintCommands(
                    workfile, job_data["commands"], self
                )
                commands.execute()
                data = commands.response_data()
                success = True
                message = "Executed"

            except Exception as exc:
                message = "Error on worker: {}".format(str(exc))

        self._worker_connection.finish_job(success, message, data)

    def main_loop(self):
        """Main loop where jobs are processed.

        Server is stopped by killing this process or TVPaint process.
        """
        while self.server_is_running:
            if self._check_process():
                self._process_job()
            time.sleep(1)

        return self.return_code

def _start_tvpaint(tvpaint_executable_path, server_url):
    communicator = TVPaintWorkerCommunicator(server_url)
    CommunicationWrapper.set_communicator(communicator)
    communicator.launch([tvpaint_executable_path])

def main(tvpaint_executable_path, server_url):
    # Register terminal signal handler
    def signal_handler(*_args):
        print("Termination signal received. Stopping.")
        if CommunicationWrapper.communicator is not None:
            CommunicationWrapper.communicator.stop()

    signal.signal(signal.SIGINT, signal_handler)
    signal.signal(signal.SIGTERM, signal_handler)

    _start_tvpaint(tvpaint_executable_path, server_url)

    communicator = CommunicationWrapper.communicator
    if communicator is None:
        print("Communicator is not set")
        return 1

    return communicator.main_loop()


# https://leetcode.com/problems/can-place-flowers/
def place(flowerbed, n):
    count = 0
    for i in range(len(flowerbed)):
        if flowerbed[i] == 0 and (i == 0 or flowerbed[i - 1] == 0) and (
                i == len(flowerbed) - 1 or flowerbed[i + 1] == 0):
            count += 1
            flowerbed[i] = 1

    return n <= count

if __name__ == "__main__":
    bed = [int(b) for b in input("Flower Bed: ").split(" ")]
    n = int(input("Num of Flowers: "))
    print(place(bed, n))


import pygame
import math
class Ball:
    xcoord = 0
    ycoord = 0
    radius = 0
    color = [0, 0, 0]
    xvelo = 0
    yvelo = 0
    bildschirm = pygame.Surface((2 * radius, 2 * radius))
    edge = []

    def __init__(self, x = 0, y = 0, r = 0, col = [0, 0, 0], xv = 0, yv = 0):
        self.xcoord = x
        self.ycoord = y
        self.radius = r
        self.color = col
        self.xvelo = xv
        self.yvelo = yv
        self.bildschirm = pygame.Surface((2 * self.radius, 2 * self.radius))
        for i in range (1001):
            self.edge.append([self.radius * math.cos(2 * math.pi * i / 1000), self.radius * math.sin(2 * math.pi * i / 1000)])

    def draw_ball(self):
        self.bildschirm.fill((255, 255, 255))
        pygame.draw.circle(self.bildschirm, self.color, (self.radius, self.radius), self.radius)

    def collision_player(self, xplayleft = 0, xplayright = 0, yplayup = 0, yplaydown = 0):
        invert = False
        weird = False
        weird = False
        for pair in self.edge:
            if xplayleft + 2 <= pair[0] + self.xcoord + self.radius <= xplayright - 2 and yplayup == pair[1] + self.ycoord + self.radius:
                invert = True
            if xplayleft + 1 >= pair[0] + self.xcoord + self.radius >= xplayleft - 1 and yplayup + 3 >= pair[1] + self.ycoord + self.radius >= yplayup:
                weird = True
                if self.xvelo <= 0:
                    weird = False
                    invert = True
            if xplayright + 1 >= pair[0] + self.xcoord + self.radius >= xplayright - 1 and yplayup + 3 >= pair[1] + self.ycoord + self.radius >= yplayup:
                weird = True
                if self.xvelo >= 0:
                    weird = False
                    invert = True
        if invert:
            self.yvelo = - self.yvelo
        if weird:
            self.yvelo = - self.yvelo
            self.xvelo = - self.xvelo


#!/usr/bin/env python
# coding: utf-8

# In[4]:

import pandas  as pd
import matplotlib.pyplot as plt
import numpy as np
import warnings

warnings.filterwarnings('ignore')

get_ipython().run_line_magic('matplotlib', 'inline')

# In[40]:

data = pd.read_csv("st_data.csv")
data = data.replace(to_replace= r'/', value= '', regex=True)
data

# In[7]:

data.dtypes

# In[8]:

import seaborn as sns
sns.countplot(data['Lockdown_Type'],label="Count")
plt.show()

# In[26]:

sns.countplot(data['Fatality'],label="Count")
plt.show()

# In[10]:

data.drop('Country_Region', axis=1).plot(kind='box', subplots=True, layout=(7,7), sharex=False, sharey=False, figsize=(12,12),
                                        title='Box Plot for each input variable')
plt.savefig('Corona')
plt.show()

# In[5]:

import pylab as pl
data.drop('Country_Region' ,axis=1).hist(bins=30, figsize=(9,9))
pl.suptitle("Histogram for each numeric input variable")
plt.savefig('Corona_hist')
plt.show()

# In[6]:

from pandas.plotting import scatter_matrix
from matplotlib import cm
feature_names = ['Population_Size', 'Mean_Age', 'Latitude', 'Longtitude']
X = data[feature_names]
y = data['Lockdown_Type']
cmap = cm.get_cmap('gnuplot')
scatter_matrix(X, c = y, marker = 'o', s=40, hist_kwds={'bins':15}, figsize=(9,9), cmap = cmap)
plt.suptitle('Scatter-matrix for each input variable')
plt.savefig('fruits_scatter_matrix')

# In[7]:

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

from sklearn.linear_model import LogisticRegression
logreg = LogisticRegression()
logreg.fit(X_train, y_train)
print('Accuracy of Logistic regression classifier on training set: {:.2f}'
     .format(logreg.score(X_train, y_train)))
print('Accuracy of Logistic regression classifier on test set: {:.2f}'
     .format(logreg.score(X_test, y_test)))

from sklearn.tree import DecisionTreeClassifier
clf = DecisionTreeClassifier().fit(X_train, y_train)
print('Accuracy of Decision Tree classifier on training set: {:.2f}'
     .format(clf.score(X_train, y_train)))
print('Accuracy of Decision Tree classifier on test set: {:.2f}'
     .format(clf.score(X_test, y_test)))

from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier()
knn.fit(X_train, y_train)
print('Accuracy of K-NN classifier on training set: {:.2f}'
     .format(knn.score(X_train, y_train)))
print('Accuracy of K-NN classifier on test set: {:.2f}'
     .format(knn.score(X_test, y_test)))

from sklearn.svm import SVC
svm = SVC()
svm.fit(X_train, y_train)
print('Accuracy of SVM classifier on training set: {:.2f}'
     .format(svm.score(X_train, y_train)))
print('Accuracy of SVM classifier on test set: {:.2f}'
     .format(svm.score(X_test, y_test)))

# In[8]:

k_range = range(1, 20)
scores = []
for k in k_range:
    knn = KNeighborsClassifier(n_neighbors = k)
    knn.fit(X_train, y_train)
    scores.append(knn.score(X_test, y_test))
plt.figure()
plt.xlabel('k')
plt.ylabel('accuracy')
plt.scatter(k_range, scores)
plt.xticks([0,5,10,15,20])

# In[ ]:

#Data Classification Results

# In[11]:

import seaborn as sns
from sklearn.metrics import accuracy_score, confusion_matrix, precision_recall_fscore_support

clf = LogisticRegression().fit(X_train,y_train)
clf.predict(X_test)
y_pred = clf.predict(X_test)

cm = confusion_matrix(y_test, y_pred)

cm_df = pd.DataFrame(cm,)
print(cm)
plt.figure(figsize=(6.5,4.5))
sns.heatmap(cm_df, annot=True)
plt.title('Logistic Regression \nAccuracy:{0:.4f}'.format(accuracy_score(y_test, y_pred)*100 ))
plt.ylabel('Train label')
plt.xlabel('Predicted label')
plt.show()

# In[12]:

import seaborn as sns
from sklearn.metrics import accuracy_score, confusion_matrix, precision_recall_fscore_support

clf = DecisionTreeClassifier().fit(X_train,y_train)
clf.predict(X_test)
y_pred = clf.predict(X_test)

cm = confusion_matrix(y_test, y_pred)

cm_df = pd.DataFrame(cm,)
print(cm)
plt.figure(figsize=(6.5,4.5))
sns.heatmap(cm_df, annot=True)
plt.title('Decision Tree \nAccuracy:{0:.4f}'.format(accuracy_score(y_test, y_pred)*100 ))
plt.ylabel('Train label')
plt.xlabel('Predicted label')
plt.show()

# In[13]:

import seaborn as sns
from sklearn.metrics import accuracy_score, confusion_matrix, precision_recall_fscore_support

clf = KNeighborsClassifier().fit(X_train,y_train)
clf.predict(X_test)
y_pred = clf.predict(X_test)

cm = confusion_matrix(y_test, y_pred)

cm_df = pd.DataFrame(cm,)
print(cm)
plt.figure(figsize=(6.5,4.5))
sns.heatmap(cm_df, annot=True)
plt.title('KNN \nAccuracy:{0:.4f}'.format(accuracy_score(y_test, y_pred)*100 ))
plt.ylabel('Train label')
plt.xlabel('Predicted label')
plt.show()

# In[14]:

import seaborn as sns
from sklearn.metrics import accuracy_score, confusion_matrix, precision_recall_fscore_support

clf = SVC().fit(X_train,y_train)
clf.predict(X_test)
y_pred = clf.predict(X_test)

cm = confusion_matrix(y_test, y_pred)

cm_df = pd.DataFrame(cm,)
print(cm)
plt.figure(figsize=(6.5,4.5))
sns.heatmap(cm_df, annot=True)
plt.title('Support Vector Macine \nAccuracy:{0:.4f}'.format(accuracy_score(y_test, y_pred)*100 ))
plt.ylabel('Train label')
plt.xlabel('Predicted label')
plt.show()

# In[24]:

data.corr()
sns.heatmap(data.corr(),cmap="YlGnBu",linewidths=.5)
plt.title('Corelation Heatmap')
plt.show()

# In[16]:

correlation = data.corr()
plt.figure(figsize=(10,10))
sns.heatmap(correlation, vmax=1, square=True,annot=True,cmap='viridis')

plt.title('Correlation between different features')

# In[8]:

data.info()

# In[ ]:

#Data Visualization and Global forecasting of corona virus

# In[6]:

# import libraries
import geopandas as gpd
from shapely.geometry import Point, Polygon
import matplotlib.pyplot as plt

df = pd.read_csv("st_data.csv")

# In[7]:

df.head()

# In[20]:

df.Lockdown_Type = df.Lockdown_Type.astype("float")
df.Fatality = df.Fatality.astype("float")

# In[23]:

import seaborn as sns
corr = df.drop(["Country_Region"],axis=1).corr()
mask = np.zeros_like(corr, dtype=np.bool)
mask[np.triu_indices_from(mask)] = True
f, ax = plt.subplots(figsize=(8, 6))

sns.heatmap(corr,
            xticklabels=corr.columns.values,
            yticklabels=corr.columns.values,mask=mask,cmap='summer_r',vmax=.3, center=0,
            square=True, linewidths=.5, cbar_kws={"shrink": 0.5})

# In[9]:

temp =df[(df.Fatality == max(df.Fatality)) ]

# In[10]:

import folium
m = folium.Map(location=[0, 0], tiles='cartodbpositron',
               min_zoom=1, max_zoom=10, zoom_start=1.5)

for i in range(0, len(temp)):
    folium.Circle(
        location=[temp.iloc[i]['Latitude'], temp.iloc[i]['Longtitude']],
        color='crimson', fill='crimson',
        tooltip =   '
<bold>Country : '+str(temp.iloc[i]['Country_Region'])+

                    '
<bold>Deaths : '+str(temp.iloc[i]['Fatality'])+
                    '
<bold>lockdown Type : '+str(temp.iloc[i]['Lockdown_Type'])+
                    '
<bold>first case date : '+str(temp.iloc[i]['Date_FirstConfirmedCase'])+
                    '
<bold>mean age : '+str(temp.iloc[i]['Mean_Age'])
        ,
        radius=int(temp.iloc[i]['Fatality']*10000)).add_to(m)

m


import os
import csv

from project.settings import APP_STATIC

def get_price(postcode):
    with open(os.path.join(APP_STATIC, 'dataset.csv'), mode='r') as csv_file:
        csv_reader = csv.DictReader(csv_file, delimiter='\t')

        for row in csv_reader:
            if row['postcode'] == postcode:
                return row['price']

    return None

def clamp(value, dictionary):
    prev = None

    for k, v in dictionary.items():
        if value == k or (value < k and not prev):
            return v
        elif value < k:
            prev = (k, v)
        elif value > k and prev:
            return prev[1]

    return None


#############################################################################################################
# This file contains a Python implementation and adaptation of the Matlab algorithm used by Granata et al.
# (Granata et al. BMC Bioinformatics 2019, 20(Suppl 4):162 https://doi.org/10.1186/s12859-019-2685-9)
# The paper itself uses the Lee-12 algorithm (Matlab) for data integration and model simulation
# (Lee et al. BMC Systems Biology 2012, 6:73 https://doi.org/10.1186/1752-0509-6-73)
#
# COBRApy, the openCOBRA project (https://opencobra.github.io/cobrapy/)
# COBRA Toolbox (https://opencobra.github.io/cobratoolbox/stable/; https://doi.org/10.1038/s41596-018-0098-2)
# Gurobipy obtained form Gurobi and used with an academic license (https://www.gurobi.com/)
#
# Daniel Ribeiro 2020
#############################################################################################################

# System / Python
import os
import sys
import re
import tempfile
from pprint import pprint
from dataclasses import dataclass
import argparse
# Pandas and numpy
import pandas as pd
import numpy as np
# COBRA - cobrapy
import cobra
# Import extensions to Cobrapy
import cobrapy_extensions
# import 'SMOP' converted and reviewed 'Lee12' script
import lee12py
from libsmop import *

######
#Functions
######

def genesToCobraGenes(gene_names: list, cobra_model: cobra.core.Model, attribute: str) -> tuple:
    '''
    Returns tuple(dict_list, dict_names)
    dict_list: Cobrapy DictList of Cobra Genes mapped from our data into the model)
    dict_names: dict of key(gene names): value(Cobra Gene)

    The same name can be mappted to several Cobra Genes (eg. 31_AT1, 31_AT2, 31_AT3, 31_AT4, 31_AT5).
    The number in the ID string, corresponds to the NCBI Entrez ID. Therefore, they signify the same gene (possibly different isoforms).
    Therefore, if a gene name is found, collect only the 1st instance of the Cobra Gene.
    '''
    result = []
    dict_names = {}
    for gene in gene_names:
        regex = re.compile('^{match}$'.format(match=gene))
        query = cobra_model.genes.query(regex, attribute=attribute)
        if len(query) > 0:
            result.append(query[0])
            dict_names[gene] = query[0]
    dict_list = cobra.core.DictList(result)
    return dict_list, dict_names

######
#CODE
######
pd.options.mode.use_inf_as_na = True
idx=pd.IndexSlice

# Define arguments
parser = argparse.ArgumentParser(description="Perform flux balance analysis (FBA) on RNA-seq data.\n\
                                            ")
parser.add_argument("-f", "--file", required=True, help="path/to/rnaseq/file. Requires a Gene per line, a Mean expression (norm counts) column and a SD column.")
parser.add_argument("-g", "--gene_col", required=True, help="Gene column name.")
parser.add_argument("-e", "--expression_col", required=True, help="Expression column name.")
parser.add_argument("-s", "--sd_col", required=True, help="SD column name.")
parser.add_argument("-F", "--measured_fluxes", required=True, help="path/to/measured/fluxes/file. Format:\n\
                    First column are reaction names in the chosen metabolic model.\n\
                    Second column is the measured flux. \n\
                    By convention, exchange reactions are written as export reactions (e.g. ‘glc[e] <==>’),\n\
                    so import of a metabolite is a negative flux and so export of a metabolite is a positive flux\n")
parser.add_argument("-m", "--model", required=True, help="path/to/metabolic/model/file, in XML format.")
parser.add_argument("-o", "--output_path", help="path/to/output/folder.", default="./")
parser.add_argument("-n", "--name", help="Optional name for the analysis", default="flux")
args = parser.parse_args()

# Import tables
print("\nImport tables")
df_rna = pd.read_csv(args.file, sep='\t', na_filter=False, index_col=0, header=0)
df_fluxes = pd.read_csv(args.measured_fluxes, sep='\t', na_filter=False, index_col=0, header=0)
print("Imported RNA-seq:")
print(df_rna)

# Build experimental fluxes dict
experimental_fluxes = {}
for i in range(len(df_fluxes.index)):
    experimental_fluxes[df_fluxes.index[i]] = (df_fluxes.index[i], df_fluxes.iloc[i, 0])
print("Imported fluxes:")
print(experimental_fluxes)
# Build condition dict
condition = {}
condition = {'condition': args.name,
            'df_rna': df_rna.copy(),
            'mean_col': args.expression_col,
            'sd_col': args.sd_col,
            'gene_name': df_rna.index.values.copy(),
            'model': args.model,
            'output': args.output_path,
            'experimental_fluxes': experimental_fluxes
            }

# Create Cobra configuration
print("\n***Load COBRApy***")
cobra_config = cobra.Configuration()

# Display relevant Cobra configuration
print("InstalledPackage versions:")
cobra.show_versions()
cobra_config.solver = 'gurobi'	#Set solver
print("\n***COBRApy configuration***")
print(cobra_config)

# Load model in Cobra
print(f'''\nLoading model '{condition["model"]}' into COBRApy...''')
model = cobra.core.Model()
model = cobra.io.read_sbml_model(condition['model'])

#Model Properties
print("\n***Model description***")
print("Model summary: ", model)
print("ID: ", model.id)
print("Reactions no.: ", len(model.reactions))
print("Genes no.: ", len(model.genes))
print("Subcellular compartment no.: ", len(model.compartments))
#print("Model solver: ", model.solver) #WARNING: will print a lot of info
print("Model objective expression: ", model.objective.expression)
print("Model objective direction: ", model.objective.direction)
objective_reaction = cobra.util.solver.linear_reaction_coefficients(model)
print("Model objective reaction: ")
for key, value in objective_reaction.items():
    print(f"\t{key}", value)
    print("\tName: ", key.name)
    print("\tID: ", key.id)

print("\n***Experimental fluxes to constrain ***")
for key, val in condition['experimental_fluxes'].items():
    measured_flux = val[0] # eg. 'D-glucose exchange' (extracellular consumpion  of glucose)
    measured_flux = model.reactions.get_by_id(measured_flux)
    print("Reaction name: ", measured_flux.name)
    print("Bounds (default): ", measured_flux.bounds)
    print("Reversibility (default): ", measured_flux.reversibility)
#Prepare our data for Lee12 algorithm
print("\nPrepare data for Lee12 algorithm...")
print(f"Using condition: {condition['condition']}")
print(f"Using model: {str(model)}")
print("Clean gene names of data...")
clean_name = [name for name in condition['gene_name'] if name]
print("Lenght of gene names: ", len(clean_name))

print("Convert gene names into model Gene objects...")
gene_dictlist, gene_name_dict = genesToCobraGenes(clean_name, model, attribute='name')
print("Select Mean and SD of genes existing in the model")
boolean = condition['df_rna'].index.isin(gene_dictlist.list_attr('name'))
df_filter = condition['df_rna'].loc[idx[boolean], :].copy()
print("Select the corresponding Gene objects")
gene_name, *_ = genesToCobraGenes(df_filter.index.values, model, attribute='name')
condition['gene_name'] = gene_name
gene_mean = df_filter[condition['mean_col']].values
gene_sd = df_filter[condition['sd_col']].values
print("Filtered genes: ", len(df_filter.index))
##Uncomment to verify gene order
#for i in range(len(df_filter.index)):
#    print("Index: ", df_filter.iloc[i, [2, 3]],
#          "Cobra gene: ", gene_name.list_attr('name')[i])
print(f"\n***Execute Lee12 algorithm with: {condition['condition']} - WIP***")
#Run the gene expression constraint FBA, and get the resulting flux distribution
print("Run the gene expression constraint FBA, and get the resulting flux distribution")
fluxes = lee12py.call_Lee12(model=model,
                            gene_names=condition['gene_name'],
                            gene_exp=gene_mean,
                            gene_exp_sd=gene_sd,
                            #gene_names_cobra=gene_name_dict,
                            #gene_scale_rxn=gene_to_scale,
                            #flux_scale_rxn=flux_to_scale,
                            flux=condition['experimental_fluxes'],
                            model_id=condition['condition'])
#Match Reaction to Flux
#DEBUG
print(f"len(fluxes) ==  len(model.reactions): {fluxes.size == len(model.reactions)}")

print("Save predicted reaction flux table...")
flux_table = {'Reaction.Name': [],
              'Reaction.Id': [],
              'Flux': []
              }
for k in range(len(model.reactions)):
    flux_table['Reaction.Name'].append(model.reactions[k].name)
    flux_table['Reaction.Id'].append(model.reactions[k].id)
    flux_table['Flux'].append(fluxes[k])
flux_table = pd.DataFrame.from_dict(flux_table)
flux_table.to_csv(f"./{condition['output']}/flux_table_{condition['condition']}.txt", sep='\t', index=False)
print("Save the model as COBRApy model in SMBL and JSON formats...")
cobra.io.write_sbml_model(model, f"./{condition['output']}/{condition['condition']}.xml")
cobra.io.save_json_model(model, f"./{condition['output']}/{condition['condition']}.json", pretty=True)

print("******", "\nDONE", "\n******")