############## Playing Card Detector Functions ###############
#
# Author: Evan Juras
# Date: 9/5/17
# Description: Functions and classes for CardDetector.py that perform
# various steps of the card detection algorithm

import cv2
import math
# Import necessary packages
import numpy as np
import os
from scipy.spatial import distance

# Constants #

# Adaptive threshold levels

BKG_THRESH = 60
CARD_THRESH = 30

# Width and height of card corner, where rank and suit are
CORNER_WIDTH = 32
CORNER_HEIGHT = 84
WIDTH_TO_HEIGHT_RATIO = 1.45
# Dimensions of rank train images
RANK_WIDTH = 70
RANK_HEIGHT = 125

# Dimensions of suit train images
SUIT_WIDTH = 70
SUIT_HEIGHT = 100

RANK_DIFF_MAX = 2000
SUIT_DIFF_MAX = 700

CARD_MAX_AREA = 2000000
CARD_MIN_AREA = 25000

font = cv2.FONT_HERSHEY_SIMPLEX

def preprocces_image(image, i):
    # cv2.imshow('Card class recieved image', image)

    blur = cv2.GaussianBlur(image, (9, 9), 0)

    edges = cv2.Canny(blur, 50, 150, True)

    kernel = np.ones((3, 3), np.uint8)
    dilate = cv2.dilate(edges, kernel, iterations=1)

    return dilate

# Structures to hold query card and train card information #

def distances(xy1, xy2):
    d0 = np.subtract.outer(xy1[:, 0], xy2[:, 0])
    d1 = np.subtract.outer(xy1[:, 1], xy2[:, 1])
    return np.hypot(d0, d1)

class Query_card:
    """Structure to store information about query cards in the camera image."""

    def __init__(self):
        self.contour = []  # Contour of card
        self.width, self.height = 0, 0  # Width and height of card
        self.corner_pts = []  # Corner points of card
        self.center = []  # Center point of card
        self.warp = []  # 200x300, flattened, grayed, blurred image
        self.rank_img = []  # Thresholded, sized image of card's rank
        self.suit_img = []  # Thresholded, sized image of card's suit
        self.best_rank_match = "Unknown"  # Best matched rank
        self.best_suit_match = "Unknown"  # Best matched suit
        self.rank_diff = 0  # Difference between rank image and best matched train rank image
        self.suit_diff = 0  # Difference between suit image and best matched train suit image

class Train_ranks:
    """Structure to store information about train rank images."""

    def __init__(self):
        self.img = []  # Thresholded, sized rank image loaded from hard drive
        self.name = "Placeholder"

class Train_suits:
    """Structure to store information about train suit images."""

    def __init__(self):
        self.img = []  # Thresholded, sized suit image loaded from hard drive
        self.name = "Placeholder"

# Functions ###
def load_ranks(filepath):
    """Loads rank images from directory specified by filepath. Stores
    them in a list of Train_ranks objects."""

    train_ranks = []
    i = 0

    for Rank in os.listdir(filepath):
        if Rank.endswith(".jpg"):
            train_ranks.append(Train_ranks())
            train_ranks[i].name = os.path.splitext(Rank)[0]
            filename = Rank
            train_ranks[i].img = cv2.imread(filepath + filename, cv2.IMREAD_GRAYSCALE)
            i = i + 1

    return train_ranks

def load_suits(filepath):
    """Loads suit images from directory specified by filepath. Stores
    them in a list of Train_suits objects."""

    train_suits = []
    i = 0

    for Suit in os.listdir(filepath):
        if Suit.endswith(".jpg"):
            train_suits.append(Train_suits())
            train_suits[i].name = os.path.splitext(Suit)[0]
            filename = Suit
            train_suits[i].img = cv2.imread(filepath + filename, cv2.IMREAD_GRAYSCALE)
            i = i + 1

    return train_suits

def find_cards(thresh_image):
    """Finds all card-sized contours in a thresholded camera image.
    Returns the number of cards, and a list of card contours sorted
    from largest to smallest."""

    # Find contours and sort their indices by contour size
    cnts, hier = cv2.findContours(thresh_image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    index_sort = sorted(range(len(cnts)), key=lambda i: cv2.contourArea(cnts[i]), reverse=True)

    # If there are no contours, do nothing
    if len(cnts) == 0:
        return [], [], []

    # Otherwise, initialize empty sorted contour and hierarchy lists
    cnts_sort = []
    hier_sort = []
    cnt_is_card = np.zeros(len(cnts), dtype=int)

    # Fill empty lists with sorted contour and sorted hierarchy. Now,
    # the indices of the contour list still correspond with those of
    # the hierarchy list. The hierarchy array can be used to check if
    # the contours have parents or not.
    for i in index_sort:
        cnts_sort.append(cnts[i])
        hier_sort.append(hier[0][i])

    # Determine which of the contours are cards by applying the
    # following criteria: 1) Smaller area than the maximum card size,
    # 2), bigger area than the minimum card size, 3) have no parents,
    # and 4) have four corners
    crns = []
    box = []
    for i in range(len(cnts_sort)):
        size = cv2.contourArea(cnts_sort[i])
        peri = cv2.arcLength(cnts_sort[i], True)
        # approx = cv2.approxPolyDP(cnts_sort[i], 0.01 * peri, True)
        rect = cv2.minAreaRect(cnts_sort[i])
        box = cv2.boxPoints(rect)

        if ((size < CARD_MAX_AREA) and (size > CARD_MIN_AREA)
                and (hier_sort[i][3] == -1) and (len(box) == 4)):
            cnt_is_card[i] = 1
            # print("Hello")
            crns = box

    return cnts_sort, cnt_is_card, crns

def preprocess_card(image, pts, w, h, qCard):
    """Uses contour to find information about the query card. Isolates rank
    and suit images from the card."""

    # Initialize new Query_card object

    qCard.corner_pts = pts

    # Assign the width and height of the bounding rectangle.
    qCard.width, qCard.height = w, h

    # Find center point of card by taking x and y average of the four corners.
    average = np.sum(pts, axis=0) / len(pts)
    cent_x = int(average[0])
    cent_y = int(average[1])
    qCard.center = [cent_x, cent_y]

    # Warp card into 200x300 flattened image using perspective transform
    qCard.warp = flattener(image, pts)
    cv2.imshow("200x300 card", qCard.warp)

    # Tager fat i nederste højre hjørner og zoomer x4
    Qcorner = qCard.warp[300 - CORNER_HEIGHT:295, 200 - CORNER_WIDTH:190]
    Qcorner_zoom = cv2.resize(Qcorner, (0, 0), fx=4, fy=4)

    # Flipper det så det vender ordenligt
    Qcorner_zoom = cv2.flip(Qcorner_zoom, -1)
    # cv2.imshow('Qcorner', Qcorner_zoom)

    # Laver det om så vi kan bruge cv2.threshold.
    gray_Qcorner = cv2.cvtColor(Qcorner_zoom, cv2.COLOR_BGR2GRAY)

    # Retval bruges ikke - OTSU giver den rigtige thresh baseret på hvilke farver der eksisterer.
    (thresh, im_bw) = cv2.threshold(gray_Qcorner, 128, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)

    # cv2.imshow('im', im_bw)
    # Split in to top and bottom half (top shows rank, bottom shows suit)
    Qrank = im_bw[20:190, 0:135]
    Qsuit = im_bw[170:336, 0:135]

    cv2.imshow('Qrank thresh', Qrank)
    cv2.imshow('Qsuit thresh', Qsuit)

    # Find rank contour and bounding rectangle, isolate and find largest contour
    Qrank_cnts, hier = cv2.findContours(Qrank, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    Qrank_cnts = sorted(Qrank_cnts, key=cv2.contourArea, reverse=True)

    # Find bounding rectangle for largest contour, use it to resize query rank
    # image to match dimensions of the train rank image
    if len(Qrank_cnts) != 0:
        x1, y1, w1, h1 = cv2.boundingRect(Qrank_cnts[0])
        Qrank_roi = Qrank[y1:y1 + h1, x1:x1 + w1]
        Qrank_sized = cv2.resize(Qrank_roi, (RANK_WIDTH, RANK_HEIGHT), 0, 0)
        qCard.rank_img = Qrank_sized
        # cv2.imshow('qCard.rank_img', qCard.rank_img)

    # Find suit contour and bounding rectangle, isolate and find largest contour
    Qsuit_cnts, hier = cv2.findContours(Qsuit, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    Qsuit_cnts = sorted(Qsuit_cnts, key=cv2.contourArea, reverse=True)

    # Find bounding rectangle for largest contour, use it to resize query suit
    # image to match dimensions of the train suit image
    if len(Qsuit_cnts) != 0:
        x2, y2, w2, h2 = cv2.boundingRect(Qsuit_cnts[0])
        Qsuit_roi = Qsuit[y2:y2 + h2, x2:x2 + w2]
        Qsuit_sized = cv2.resize(Qsuit_roi, (SUIT_WIDTH, SUIT_HEIGHT), 0, 0)
        qCard.suit_img = Qsuit_sized
        # cv2.imshow('qCard.suit', qCard.suit_img)

    return qCard

def match_card(qCard, train_ranks, train_suits):
    """Finds best rank and suit matches for the query card. Differences
    the query card rank and suit images with the train rank and suit images.
    The best match is the rank or suit image that has the least difference."""

    best_rank_match_diff = 10000
    best_suit_match_diff = 10000
    best_rank_match_name = "Unknown"
    best_suit_match_name = "Unknown"
    i = 0

    # If no contours were found in query card in preprocess_card function,
    # the img size is zero, so skip the differencing process
    # (card will be left as Unknown)
    if (len(qCard.rank_img) != 0) and (len(qCard.suit_img) != 0):

        # Difference the query card rank image from each of the train rank images,
        # and store the result with the least difference
        for Trank in train_ranks:

            diff_img = cv2.absdiff(qCard.rank_img, Trank.img)
            rank_diff = int(np.sum(diff_img) / 255)

            if rank_diff < best_rank_match_diff:
                best_rank_diff_img = diff_img
                best_rank_match_diff = rank_diff
                best_rank_name = Trank.name

        # Same process with suit images
        for Tsuit in train_suits:

            diff_img = cv2.absdiff(qCard.suit_img, Tsuit.img)
            suit_diff = int(np.sum(diff_img) / 255)

            if suit_diff < best_suit_match_diff:
                best_suit_diff_img = diff_img
                best_suit_match_diff = suit_diff
                best_suit_name = Tsuit.name

    # Combine best rank match and best suit match to get query card's identity.
    # If the best matches have too high of a difference value, card identity
    # is still Unknown
    if best_rank_match_diff < RANK_DIFF_MAX:
        best_rank_match_name = best_rank_name

    if best_suit_match_diff < SUIT_DIFF_MAX:
        best_suit_match_name = best_suit_name

    # Shorten the name since we match on pics with weird names.
    best_suit_match_list = best_suit_match_name.split('_')
    best_suit_match_name = best_suit_match_list[0]

    best_rank_match_list = best_rank_match_name.split('_')
    best_rank_match_name = best_rank_match_list[0]

    # Return the identiy of the card and the quality of the suit and rank match
    if best_rank_match_name == "Unknown" and best_suit_match_name == "Unknown":
        return qCard.best_rank_match, qCard.best_suit_match, best_rank_match_diff, best_suit_match_diff

    elif best_rank_match_name == "Unknown":
        return qCard.best_rank_match, best_suit_match_name, best_rank_match_diff, best_suit_match_diff

    elif best_suit_match_name == "Unknown":
        return best_rank_match_name, qCard.best_suit_match, best_rank_match_diff, best_suit_match_diff

    return best_rank_match_name, best_suit_match_name, best_rank_match_diff, best_suit_match_diff

def draw_results(image, qCard):
    """Draw the card name, center point, and contour on the camera image."""

    x = qCard.center[0]
    y = qCard.center[1]
    cv2.circle(image, (x, y), 5, (255, 0, 0), -1)

    rank_name = qCard.best_rank_match
    suit_name = qCard.best_suit_match

    # Draw card name twice, so letters have black outline
    cv2.putText(image, (rank_name + ' of'), (x - 60, y - 10), font, 1, (0, 0, 0), 3, cv2.LINE_AA)
    cv2.putText(image, (rank_name + ' of'), (x - 60, y - 10), font, 1, (50, 200, 200), 2, cv2.LINE_AA)

    cv2.putText(image, suit_name, (x - 60, y + 25), font, 1, (0, 0, 0), 3, cv2.LINE_AA)
    cv2.putText(image, suit_name, (x - 60, y + 25), font, 1, (50, 200, 200), 2, cv2.LINE_AA)

    # Can draw difference value for troubleshooting purposes
    # (commented out during normal operation)
    # r_diff = str(qCard.rank_diff)
    # s_diff = str(qCard.suit_diff)
    # cv2.putText(image,r_diff,(x+20,y+30),font,0.5,(0,0,255),1,cv2.LINE_AA)
    # cv2.putText(image,s_diff,(x+20,y+50),font,0.5,(0,0,255),1,cv2.LINE_AA)

    return image

def flattener(image, pts):
    """Flattens an image of a card into a top-down 200x300 perspective.
    Returns the flattened, re-sized, grayed image.
    See www.pyimagesearch.com/2014/08/25/4-point-opencv-getperspective-transform-example/"""
    temp_rect = np.zeros((4, 2), dtype="float32")
    s = np.sum(pts, axis=1)
    # Vi starter med at udregne hvor vores 4 hjørner er i forhold til vores kort.
    # Bare 4 store tal
    topcornerlist = np.array([[1000000, 10000000], [100000000, 100000000]])
    # Loop over for at finde de to øverste punkter
    for corn in pts:
        if corn[1] < topcornerlist[0][1]:
            topcornerlist[1] = topcornerlist[0]
            topcornerlist[0] = corn

        elif corn[1] < topcornerlist[1][1]:
            topcornerlist[1] = corn

    bottomcornerlist = np.array([[0, 0], [0, 0]])
    # Loop til at finde de to nederste
    for corn in pts:
        if corn[1] > bottomcornerlist[0][1]:
            bottomcornerlist[1] = bottomcornerlist[0]
            bottomcornerlist[0] = corn

        elif corn[1] > bottomcornerlist[1][1]:
            bottomcornerlist[1] = corn

    # Please være søde ikke at rette i det her - Gustav

    # Denne udregning er hvis kortet står i en 90* vinkel, og hælder derfor hverken mod venstre eller højre
    if int(topcornerlist[0][1]) == int(topcornerlist[1][1]):
        temp_rect[0] = pts[np.argmin(s)]
        temp_rect[2] = pts[np.argmax(s)]
        # now, compute the difference between the points, the
        # top-right point will have the smallest difference,
        # whereas the bottom-left will have the largest difference
        diff = np.diff(pts, axis=1)
        temp_rect[1] = pts[np.argmin(diff)]
        temp_rect[3] = pts[np.argmax(diff)]

    # Hvis kortet hælder mod højre
    # top1 er venstre hjørne, top2 er højre hjørne
    # bot1 er højre hjørne bot2 er venstre hjørne

    elif topcornerlist[0][0] < topcornerlist[1][0]:
        temp_rect[0] = topcornerlist[0]
        temp_rect[1] = topcornerlist[1]
        temp_rect[2] = bottomcornerlist[0]
        temp_rect[3] = bottomcornerlist[1]
    # Nu skifter vi. Den der har den laveste y værdi er nu modsatte hjørne.
    else:
        temp_rect[0] = topcornerlist[1]
        temp_rect[1] = topcornerlist[0]
        temp_rect[2] = bottomcornerlist[1]
        temp_rect[3] = bottomcornerlist[0]

    # de her tal definerer det 200x300 warp vi trækker ud.
    maxWidth = 200
    maxHeight = 300

    # Create destination array, calculate perspective transform matrix,
    # and warp card image
    dst = np.array([[0, 0], [maxWidth - 1, 0], [maxWidth - 1, maxHeight - 1], [0, maxHeight - 1]], np.float32)
    M = cv2.getPerspectiveTransform(temp_rect, dst)
    warp = cv2.warpPerspective(image, M, (maxWidth, maxHeight))
    # warp = cv2.cvtColor(warp,cv2.COLOR_BGR2GRAY)

    return warp

def CalculateCardPosition(crns, image, oldlines):
    runs = False
    cornerlist = np.array([[0, 0], [0, 0]])
    # Finder de to højeste y værdier i vores array. De højeste y-værdier er de nederste punkter.

    for corn in crns:
        if corn[1] >= cornerlist[0][1]:
            cornerlist[1] = cornerlist[0]
            cornerlist[0] = corn

        elif corn[1] >= cornerlist[1][1]:
            cornerlist[1] = corn

    while True:
        vector = None
        if cornerlist[1][0] <= cornerlist[0][0]:
            vector = cornerlist[1] - cornerlist[0]
        else:
            vector = cornerlist[0] - cornerlist[1]

        # Den ortogonale vektor bruges til at udrenge approximationen for de to top punkter.
        orthogonal_vector = [-1 * WIDTH_TO_HEIGHT_RATIO * vector[1], WIDTH_TO_HEIGHT_RATIO * vector[0]]
        # width
        w = math.sqrt(math.pow(vector[0], 2) + math.pow(vector[1], 2))
        # height
        h = w * WIDTH_TO_HEIGHT_RATIO

        topcorner1 = cornerlist[0] + orthogonal_vector
        topcorner2 = cornerlist[1] + orthogonal_vector

        intersections = houghLinesCorners(image, cornerlist[0], cornerlist[1], topcorner1, topcorner2, oldlines)
        if intersections == None or runs == True:
            if runs is True:
                cv2.putText(image, ("Locked!"), (500, 50), font, 1, (0, 255, 0), 3, cv2.LINE_AA)
            else:
                cv2.putText(image, ("Locking..."), (500, 50), font, 1, (0, 255, 255), 3, cv2.LINE_AA)

            return w, h, topcorner1, topcorner2, cornerlist[0], cornerlist[1]
        cornerlist[0] = intersections[0]
        cornerlist[1] = intersections[1]
        # topcorner1 = intersections[2]
        # topcorner2 = intersections[3]
        runs = True

def houghLinesCorners(image, b1, b2, t1, t2, oldintersections):
    """---------------------Hough Lines---------------------------"""

    # Finds Maximum and minimum x and y af the points supplied to find where to crop the image
    xmin = None
    xmax = None
    ymin = None
    ymax = None
    for p in [b1, b2, t1, t2]:
        if xmin is None:  # Initialise the variables
            xmin = p[0]
        if xmax is None:
            xmax = p[0]
        if ymin is None:
            ymin = p[1]
        if ymax is None:
            ymax = p[1]

        if p[0] < xmin:  # Find min and max
            xmin = p[0]
        elif p[0] > xmax:
            xmax = p[0]
        if p[1] < ymin:
            ymin = p[1]
        elif p[1] > ymax:
            ymax = p[1]

    offsetX1 = -8  # An adjustable offset to fine tune the cropping
    offsetX2 = 8
    offsetY1 = 40
    offsetY2 = 20

    cropX1 = int(
        np.heaviside(0, xmin + offsetX1))  # Uses the heavyside/unit step function to make sure that the cropping points
    cropX2 = int(np.heaviside(0, xmax + offsetX2))  # are inside the picture i.e. if they are < 0 make them 0
    cropY1 = int(np.heaviside(0, ymin + offsetY1))
    cropY2 = int(np.heaviside(0, ymax + offsetY2))

    magfactor = 2  # factor for magnifying the image that is being worked on, called løl "name subject to change"

    # cv2.imshow("what i crop", image)
    lel = image[cropY1:cropY2, cropX1:cropX2]  # The function works on a cropped and magnified image "løl"
    if len(lel) == 0:  # if "løl" is empty, due to bad cropping or bad points fed to the function,
        # print("bad search") # return non and print bad search
        return None

    # Hvis kortet ligger helt ude til siden prøver den at tage et billede udenfor billedet, og den exception skal fanges
    try:
        lel = cv2.resize(lel, (0, 0), fx=magfactor,
                         fy=magfactor)  # magnify løl by the magfactor for better line/ edge detection
    except cv2.error:
        return None

    edges = cv2.Canny(lel, 150, 400, apertureSize=3)  # find edges

    ##cv2.circle(image, (cropX1, cropY1), 6, (255, 0, 255), -1)
    ##cv2.circle(image, (cropX2, cropY2), 6, (255, 0, 255), -1)

    lines = cv2.HoughLines(edges, 1, np.pi / 180, 125)  #
    # lines = [[[-184, 3.0717795]]]
    # print(lines)
    vlines = []
    hlines = []

    # Returnerer vi ikke bare de gamle her?
    if len(oldintersections[0]) != 0 and lines is None:
        if distance.euclidean(oldintersections[0], b1) > distance.euclidean(oldintersections[1], b1):
            if distance.euclidean(oldintersections[1], b1) > 200:
                return [b1, b2]
            else:
                return oldintersections
        else:
            if distance.euclidean(oldintersections[1], b1) > 200:
                return [b1, b2]
            else:
                return oldintersections

    if lines is not None:
        # print("found lines")
        for i in lines:
            rho = i[0][0]
            theta = i[0][1]

            # Determine if lines are vertical based on the angle theta from origin (origo) to the normal of the line
            if (theta >= 0 and theta < np.pi / 4) or (theta > 3 * np.pi / 4 and theta < 5 * np.pi / 4) or (
                    theta > 7 * np.pi / 4 and theta < 8 * np.pi / 4):
                vlines.append(i)

            # Determine if lines are horizontal based on the angle theta from origin (origo) to the normal of the line
            if (theta > np.pi / 4 and theta < 3 * np.pi / 4) or (theta > 5 * np.pi / 4 and theta < 7 * np.pi / 4):
                hlines.append(i)
            """
            a = np.cos(theta)
            b = np.sin(theta)
            x0 = a * rho
            y0 = b * rho
            x1 = int(x0 + 1000 * (-b))
            y1 = int(y0 + 1000 * (a))
            x2 = int(x0 - 1000 * (-b))
            y2 = int(y0 - 1000 * (a))

            #cv2.line(frame, (x1, y1), (x2, y2), (188, 0, 188), 2)
            cv2.line(edges, (x1, y1), (x2, y2), (188, 0, 188), 1)
            """

        # print("vlines")
        # print(vlines)
        # print("hlines")
        # print(hlines)

        while len(vlines) > 2:
            mTheta = 0  # mean angle of the horizontal lines in radians
            sumTheta = 0
            j = 0
            outlinerX = 0  # index of the line whose angle deviates the most from the mean
            outlinerV = 0  # Variance of the line whose angle deviates the most
            for hl in vlines:
                sumTheta += hl[0][1]
            mTheta = sumTheta / len(vlines)
            for hl in vlines:
                currentV = (hl[0][1] - mTheta) ** 2
                if currentV > outlinerV:
                    outlinerV = currentV
                    outlinerX = j
                j += 1
            # print(outlinerV)
            del vlines[outlinerX]
        # print(len(vlines))

        for i in vlines:
            rho = i[0][0]
            theta = i[0][1]

            a = np.cos(theta)
            b = np.sin(theta)
            x0 = a * rho
            y0 = b * rho
            x1 = int(x0 + 1000 * (-b))
            y1 = int(y0 + 1000 * (a))
            x2 = int(x0 - 1000 * (-b))
            y2 = int(y0 - 1000 * (a))

            # cv2.line(frame, (x1, y1), (x2, y2), (188, 0, 188), 2)
            cv2.line(edges, (x1, y1), (x2, y2), (188, 0, 188), 1)

        for i in hlines:
            rho = i[0][0]
            theta = i[0][1]

            a = np.cos(theta)
            b = np.sin(theta)
            x0 = a * rho  # Find the first coordinate of the point on the line where it is orthogonal with the line to origin
            y0 = b * rho  # Find seccond coordinate here
            x1 = int(x0 + 1000 * (-b))
            y1 = int(y0 + 1000 * (a))
            x2 = int(x0 - 1000 * (-b))
            y2 = int(y0 - 1000 * (a))

            # cv2.line(frame, (x1, y1), (x2, y2), (188, 0, 188), 2)
            cv2.line(edges, (x1, y1), (x2, y2), (188, 0, 188), 1)

        if len(vlines) == 2 and len(hlines) > 0:

            rline = 0
            lline = 0
            bline = hlines[0]

            if abs(vlines[0][0][0]) > abs(vlines[1][0][0]):
                rline = vlines[0]
                lline = vlines[1]
            else:
                rline = vlines[1]
                lline = vlines[0]

            for ln in hlines:
                if abs(ln[0][0]) > abs(bline[0][0]):
                    bline = ln

            # Calculate instersections
            intersections = []

            ah = -(np.cos(bline[0][1]) / np.sin(bline[0][1]))
            bh = bline[0][0] / np.sin(bline[0][1])

            for vl in [lline, rline]:

                if vl[0][1] == 0:  # if the current vertical line is exactly vertical (slope of line = ∞) with theta = 0
                    pointX = vl[0][0]
                    pointY = ah * pointX + bh

                elif vl[0][1] == np.pi:  # if theta = pi (perfectly vertical line flipped 180 degrees)
                    pointX = -vl[0][0]
                    pointY = ah * pointX + bh

                else:
                    av = -(np.cos(vl[0][1]) / np.sin(vl[0][1]))
                    bv = vl[0][0] / np.sin(vl[0][1])

                    pointX = (bh - bv) / (av - ah)
                    pointY = (av * bh - ah * bv) / (av - ah)

                intersections.append([pointX, pointY])

            estimates = []

            sideRelationFactor = 1.5

            # Pythagoras theorem to find distance between intersections
            intrsctwidth = np.sqrt(
                ((intersections[1][0] - intersections[0][0]) ** 2) + ((intersections[1][1] - intersections[0][1]) ** 2))

            # calculates the angle between the x-axis and the line for each side of the card
            if lline[0][0] >= 0:
                lsideangle = (lline[0][1] + 3 * np.pi / 2) % (2 * np.pi)
            else:
                lsideangle = (lline[0][1] + np.pi / 2) % (2 * np.pi)

            if rline[0][0] >= 0:
                rsideangle = (rline[0][1] + 3 * np.pi / 2) % (2 * np.pi)
            else:
                rsideangle = (rline[0][1] + np.pi / 2) % (2 * np.pi)

            lestimate = [intersections[0][0] + np.cos(lsideangle) * intrsctwidth * sideRelationFactor,
                         intersections[0][1] + np.sin(lsideangle) * intrsctwidth * sideRelationFactor]

            restimate = [intersections[1][0] + np.cos(rsideangle) * intrsctwidth * sideRelationFactor,
                         intersections[1][1] + np.sin(rsideangle) * intrsctwidth * sideRelationFactor]

            intersections.append(lestimate)
            intersections.append(restimate)

            cv2.circle(edges, (int(intersections[0][0]), int(intersections[0][1])), 6, (0, 255, 255), -1)
            cv2.circle(edges, (int(intersections[1][0]), int(intersections[1][1])), 6, (0, 255, 255), -1)
            cv2.circle(lel, (int(restimate[0]), int(restimate[1])), 6, (0, 255, 255), -1)
            cv2.circle(lel, (int(lestimate[0]), int(lestimate[1])), 6, (0, 255, 255), -1)

            # cv2.circle(løl, (int(intersections[0][0]), int(intersections[0][1])), 6, (0, 255, 255), -1)
            # cv2.circle(løl, (int(intersections[1][0]), int(intersections[1][1])), 6, (0, 255, 255), -1)

            for p in intersections:
                p[0] = p[0] / magfactor
                p[1] = p[1] / magfactor

                p[0] += cropX1
                p[1] += cropY1

            # cv2.circle(image, (int(intersections[0][0]), int(intersections[0][1])), 6, (0, 255, 255), -1)
            # cv2.circle(image, (int(intersections[1][0]), int(intersections[1][1])), 6, (0, 255, 255), -1)

            # print("Have found lines")
            # cv2.imshow("Lel", lel)
            # cv2.imshow("Lines", edges)

            if len(oldintersections[0]) != 0:
                if distance.euclidean(oldintersections[0], b1) < distance.euclidean(intersections[0], b1):
                    return oldintersections
                else:
                    return intersections

            return intersections

    # print("have not found lines")
    # cv2.imshow("Lel", lel)
    cv2.imshow("Lines", edges)
    return None

    """
        for i in [bline]:
            rho = i[0][0]
            theta = i[0][1]

            a = np.cos(theta)
            b = np.sin(theta)
            x0 = a * rho  # Find the first coordinate of the point on the line where it is orthogonal with the line to origin
            y0 = b * rho  # Find seccond coordinate here
            x1 = int(x0 + 1000 * (-b))
            y1 = int(y0 + 1000 * (a))
            x2 = int(x0 - 1000 * (-b))
            y2 = int(y0 - 1000 * (a))
    """

def rank_converter(rank):
    switcher = {
        "ACE": "1",
        "TWO": "2",
        "THREE": "3",
        "FOUR": "4",
        "FIVE": "5",
        "SIX": "6",
        "SEVEN": "7",
        "EIGHT": "8",
        "NINE": "9",
        "TEN": "10",
        "JACK": "J",
        "QUEEN": "Q",
        "KING": "K",
        "UNKNOWN": "U"
    }
    return switcher.get(rank, " ")


def get_neighbor_coords(grid: list, c: tuple):
    neighbor_list = []
    x, y = c[0], c[1]
    north = y > 0
    west = x > 0
    east = x < len(grid[y])-1
    south = y < len(grid)-1
    if north:
        neighbor_list.append((x, y-1))
    if west:
        neighbor_list.append((x-1, y))
    if east:
        neighbor_list.append((x+1, y))
    if south:
        neighbor_list.append((x, y+1))
    return neighbor_list

def get_neighbor_heights(grid: list, c: tuple):
    neighbor_coords = get_neighbor_coords(grid, c)
    return [grid[y][x] for (x, y) in neighbor_coords]

def check_if_lowpoint(grid: list, c: tuple):
    x, y = c[0], c[1]
    neighbors = sorted(get_neighbor_heights(grid, (x, y)))
    return (grid[y][x] < neighbors[0])

def check_basin_size_recursively(input_map, output_map, c: tuple):
    neighbor_coords = get_neighbor_coords(input_map, c)
    x, y = c[0], c[1]
    output_map[y][x] = 1
    size = 1
    for (n_x, n_y) in neighbor_coords:
        if output_map[n_y][n_x] == 0:
            if input_map[n_y][n_x] == 9:
                output_map[n_y][n_x] = 9
            else:
                size += check_basin_size_recursively(input_map, output_map, (n_x, n_y))
    return size

with open('day9.in') as input:
    heightmap = [[int(c) for c in l.strip()] for l in input.readlines()]
low_point_list = []

# part one
risk_level_sum = 0
for y, row in enumerate(heightmap):
    for x, cell in enumerate(row):
        is_lowpoint = check_if_lowpoint(heightmap, (x, y))
        if is_lowpoint:
            low_point_list.append((x,y))
            risk_level_sum += 1 + cell
        # print(f"lp@({x:2},{y:2}): risk {1 + cell}")
print(f"part 1: global_risk_level= {risk_level_sum}")

# part two
basin_map = [[0 for c in row] for row in heightmap]
basin_list = []
for lp in low_point_list:
    basin_list.append(check_basin_size_recursively(heightmap, basin_map, lp))
biggest_basin_size_list = sorted(basin_list, reverse=True)[:3]
size_product = biggest_basin_size_list[0]
for b in biggest_basin_size_list[1:]:
    size_product *= b
print(f"part 2: biggest_basins= {biggest_basin_size_list}, product_of_sizes= {size_product}")


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

from django.core.urlresolvers import reverse, NoReverseMatch
from django.utils.safestring import mark_safe
from .base import Column

class LinkColumn(Column):
    def __init__(self, links, delimiter=u' ', *args, **kwargs):
        super(LinkColumn, self).__init__(*args, **kwargs)
        self.links = links
        self.delimiter = delimiter
        self.searchable = False
        self.safe = False

    def render(self, obj):
        return self.delimiter.join([link.as_html(obj) for link in self.links])

class Link(object):
    """ Represents a link element in html.
    """
    def __init__(self, text, viewname, args=[], kwargs={}, urlconf=None, current_app=None):
        self.text = text
        self.viewname = viewname
        self.args = args
        self.kwargs = kwargs
        self.urlconf = urlconf
        self.current_app = current_app

    def resolve(self, obj):
        """ Resolving URL paths to the corresponding object. See:
            https://docs.djangoproject.com/en/dev/ref/urlresolvers/#reverse
        """
        viewname = self.viewname
        params = {}

        if self.args:
            params['args'] = [getattr(obj, attr) for attr in self.args]
        if self.kwargs:
            params['kwargs'] = {}
            for key, value in self.kwargs.itmes:
                params['kwargs'][key] = getattr(obj, value)
        if self.urlconf:
            params['urlconf'] = self.urlconf
        if self.current_app:
            params['current_app'] = self.current_app

        try:
            url = reverse(viewname, **params)
        except NoReverseMatch:
            url = ''
        return url

    def as_html(self, obj):
        url = self.resolve(obj)
        html = '%s' % (url, self.text)
        return mark_safe(html)


import torch
from torch import nn
import matplotlib.pyplot as pyplot
from transformers import BertModel
from transformers import BertTokenizer

torch_device = "cuda" if torch.cuda.is_available() else "cpu"
print(f'Using {torch_device} device')

"""
(embeddings): BertEmbeddings(
    (word_embeddings): Embedding(30522, 768, padding_idx=0)
    (position_embeddings): Embedding(512, 768)
    (token_type_embeddings): Embedding(2, 768)
    (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)
    (dropout): Dropout(p=0.1, inplace=False)
  )
"""

class InputOptimizer(nn.Module):
  def __init__(self, model, input_vectors):
    super(InputOptimizer, self).__init__()
    self.model = model
    self.input_vectors = nn.parameter.Parameter(input_vectors)
    self.register_parameter('input_vector', self.input_vectors)
    #print('parameters after register:')
    #for i, p in enumerate(self.parameters()):
    #  print(f'  {i}: {p.shape}')
    #  print(p)
    #  raise Exception('stop')
  def forward(self):
    return self.model(self.input_vectors)

class BertEmbeddings1Hot(nn.Module):
  def __init__(self,
               embedding_matrix,
               token_type_vector,
               position_embedding_vector,
               layer_normalization_module):
    super(BertEmbeddings1Hot, self).__init__()
    self.embedding_matrix = embedding_matrix
    self.token_type_vector = token_type_vector
    self.position_embedding_vector = position_embedding_vector
    self.layer_normalization = layer_normalization_module
  def forward(self, x):
    y = torch.matmul(x, self.embedding_matrix)
    y = y + self.position_embedding_vector + self.token_type_vector
    y = embedding_layer_norm(y)
    return y

bert_model_name = 'bert-base-uncased'
bert_model = BertModel.from_pretrained(bert_model_name)
bert_model = bert_model.to(torch_device)

bert_tokenizer = BertTokenizer.from_pretrained(bert_model_name)
model_input_length = bert_tokenizer.max_model_input_sizes[bert_model_name]
max_token = len(bert_tokenizer.vocab)

def encode_text_as_input(text):
  return bert_tokenizer.encode(text,
                      return_tensors='pt',
                      max_length=model_input_length,
                      pad_to_max_length=True)

embedding = bert_model.embeddings
word_embedding = embedding.word_embeddings
position_embedding = embedding.position_embeddings
token_type_embedding = embedding.token_type_embeddings
embedding_layer_norm = embedding.LayerNorm

embedding_matrix = word_embedding.state_dict()['weight']
position_embedding_vector = position_embedding.state_dict()['weight']
token_type_vector = token_type_embedding.state_dict()['weight'][0,:]

bert_embedding_model = BertEmbeddings1Hot(embedding_matrix,
                                          token_type_vector,
                                          position_embedding_vector,
                                          embedding_layer_norm)

#

start_sentence = 'There is no place like home.'
end_sentence_one_word = 'There is no place like Italy.'
end_sentence_keep_meaning = 'No place is like home.'
end_sentence_different = 'The cat jumps over the fence.'

encoded_sentence = encode_text_as_input(start_sentence)
encoded_sentence_1hot = nn.functional.one_hot(encoded_sentence, num_classes=bert_tokenizer.vocab_size).float()
start_input = encoded_sentence_1hot

embedding.eval()
start_output = embedding(encoded_sentence)
expected_output = start_output

# ---

perturbation_size = 0.1

input_parameter = start_input * (1. + perturbation_size * torch.rand(start_input.shape))

input_optimizer = InputOptimizer(bert_embedding_model, input_parameter).to(torch_device)

loss_function = nn.MSELoss(reduction='sum')
parameters_to_optimize = [ input_optimizer.input_vectors ]
optimizer = torch.optim.Adam(parameters_to_optimize, lr=0.0001)

input_optimizer.train()

"""
############### test step
optimizer.zero_grad()
current_output = input_optimizer()
bert_optimizer_loss(current_output, expected_output).backward(retain_graph=True)
optimizer.step()
#current_output.last_hidden_state.detach_()

##########################
"""

loss_values = []

for i in range(140):
  optimizer.zero_grad()
  current_output = input_optimizer()
  loss = loss_function(current_output, expected_output)
  loss.backward(retain_graph=True)
  #current_output.last_hidden_state.detach_()
  loss_values.append(loss.item())
  optimizer.step()

pyplot.plot(loss_values)
pyplot.show()

"""
1. extract the embedding matrix: only parameters of word_embedding (shape: nb_token X 768)
2. create a model from embedding where the word_embeddings layer is replaced by a linear map with the matrix
3. tokenize inputs then 1-hotize them

"""

"""
import numpy

x=torch.tensor(numpy.array([254, 18], dtype=int), dtype=torch.int32)
embedding.word_embeddings(x).shape
>   torch.Size([2, 768])

"""


def parse_input(path):
    rocks = set()
    max_y = 0
    with open(path) as fh:
        for line in fh.readlines():
            coords = line.strip().split(" -> ")
            for idx in range(1, len(coords)):
                coord = list(map(int, coords[idx].split(",")))
                prev_coord = list(map(int, coords[idx - 1].split(",")))
                mn, mx = sorted([prev_coord[0], coord[0]])
                mx_y = max(prev_coord[1], coord[1])
                max_y = mx_y if max_y == 0 else max(max_y, mx_y)
                for x in range(mn, mx + 1):
                    rocks.add((x, coord[1]))
                mn, mx = sorted([prev_coord[1], coord[1]])
                for y in range(mn, mx + 1):
                    rocks.add((coord[0], y))

    return rocks, max_y

def solution(path):
    rocks, max_y = parse_input(path)
    flr = max_y + 2

    units_of_sand = 0
    while True:
        sand = (500, 0)
        while True:
            proposed = [
                (sand[0], sand[1] + 1),
                (sand[0] - 1, sand[1] + 1),
                (sand[0] + 1, sand[1] + 1),
            ]
            for prop in proposed:
                if prop not in rocks and prop[1] < flr:
                    sand = prop
                    break
            else:
                rocks.add(sand)
                units_of_sand += 1
                if sand == (500, 0):
                    return units_of_sand
                break

test_part2 = solution("../sample.txt")
assert test_part2 == 93, test_part2
answer_part2 = solution("../input.txt")
print(f"Part 2 => {answer_part2}")


from .models import Event, EventNotification, UserEventPlan, Notice, Event, GroupEvent, UserEvent
from django.utils.html import conditional_escape as esc
from django.forms.formsets import formset_factory
from .methods import get_notice
from .groupMethods import has_edit_privileges_for_group
from .forms import EventNotificationForm
import datetime
def get_event(event_id):
    try:
        return Event.objects.get(id=event_id)
    except Event.DoesNotExist:
        return None

def get_event_notification_by_notice_event(notice, event):
    try :
        return EventNotification.objects.get(notice=notice, event=event)
    except EventNotification.DoesNotExist:
        return None
def display_event(event_id):
    event = get_event(event_id)
    if event is None:
        return "
Event does not exist
"
    else:
        invites = EventNotification.objects.filter(event =event)
        responses = UserEventPlan.objects.filter(event=event)
        toReturn = ""
        toReturn += "

%s
" % esc(event.name)
        toReturn +="Go to event page" %esc(event.id)
        toReturn +="
Location: %s
" %esc(event.main_location)
        toReturn +="
Start: %s
" %esc(event.start_time)
        toReturn +="
End: %s
" %esc(event.end_time)
        toReturn +="
%s users invited
" %invites.count()
        toReturn +="
%s are committed
" % responses.filter(status=0).count()
        toReturn +="
%s are probably going
" % responses.filter(status=2).count()
        toReturn +="
%s are not sure
" % responses.filter(status=1).count()
        toReturn +="
%s are unlikely to show up
" % responses.filter(status=4).count()
        toReturn +="
%s have declined
" % responses.filter(status=3).count()

        toReturn += "
"
    return toReturn

def get_user_event_notifications(squirl):
    event_formset = formset_factory(EventNotificationForm, extra=0)
    event_notifications = EventNotification.objects.filter(notice__user = squirl, notice__viewed=0)

    initial_list = []
    for event in event_notifications:
        initial_list.append({'eventName': event.event.name, 'noticeId': event.notice.id,'response': 0, 'eventId': event.event.id,})

    return event_formset(initial=initial_list, prefix = 'event_notices')

def validate_event_notifications_formset(formset, squirl):
    for form in formset:
        if form.is_valid():
            data = form.cleaned_data
            event = get_event(data['eventId'])
            print(event.name)
            if event is None:
                print("event does not exist")
                return False

            notice = get_notice(int(data['noticeId']))
            if notice is None:
                print("notice does not exist")
                return False
            if notice.user != squirl:
                print("wrong user")
                return False

            print(notice.id)
            event_notice = get_event_notification_by_notice_event(notice, event)

            if event_notice is None:
                print("event notice does not exist")
                return False
            response = int(data['response'])
            if response > 5 or response <0:
                print("response not valid")
                return False

        else:
            return False

    return True
def create_from_event_notification_formset(formset, squirl):
    for form in formset:
        data = form.cleaned_data
        response = int(data['response'])
        if response != 0:
            notice = get_notice(data['noticeId'])
            event = get_event(data['eventId'])
            event_notice = get_event_notification_by_notice_event(notice, event)
            notice.viewed = True
            notice.save()
            if response != 1:
                userPlan = UserEventPlan()
                userPlan.squirl_user = squirl
                userPlan.event = event
                if response == 2:
                    userPlan.status= 1
                if response == 3:
                    userPlan.status=0
                if response == 4:
                    userPlan.status=2
                if response ==5:
                    userPlan.status =4
                userPlan.save()

#actually gets user event plans
def get_user_upcoming_events(squirl):
    now = datetime.datetime.now().replace(hour=0,minute=0,second=0)
    events = UserEventPlan.objects.filter(squirl_user = squirl, event__end_time__gte = now).order_by('event__start_time')
##    to_exclude = events.filter(start_time__date__year = now.date.year, start_time__date__month__lt = now.date.month).values('id')
##
##    events = events.exclude(id__in=to_exclude)
##
##    to_exclude = events.filter(start_time__date__year = now.date.year, start_time__date__month = now.date.month, start_time__date__day__lt = now.date.day).values('id')
##
##    events = events.exclude(id__in=to_exclude)

    #the below line is wrong.
    #events = events.filter(start_time__year >=now.year, start_time__month >=now.month, start_time__day >= now.day)

    return events

def get_event_notification_by_user_and_event(squirl, event):
    try:
        toReturn = EventNotification.objects.get(notice__user = squirl, event= event)
        return toReturn
    except EventNotification.DoesNotExist:
        return None

def can_user_edit_event(squirl, event):
    u_event = None
    try:
        u_event = GroupEvent.objects.get(event=event)
        return has_edit_privileges_for_group(squirl, u_event.group)
    except GroupEvent.DoesNotExist:
        u_event = None
    if u_event is None:
        try:
            u_event = UserEvent.objects.get(event=event)
            if u_event.creator == squirl:
                return True
        except UserEvent.objects.DoesNotExist:
            print("Event is not associated with anyone")
            return False

    return false


import os
import shutil

os.environ['DISPLAY']='localhost:12.0'
import pickle
from cv2 import cv2
from tqdm import tqdm
from mmdet.datasets import build_dataset
from mmcv import Config
import os.path as osp
from glob import glob
import matplotlib.pyplot as plt

cfg = Config.fromfile('../configs/faster_rcnn/faster_rcnn_r50_fpn_llvip.py')
show_epoch = not 'epoch_4.pth'
pkl_root = '../runs_llvip/FasterRCNN_r50wMask_ROIFocalLoss5_CIOU20_cosineSE_notDetach_negEntropy1'
save_root = osp.join(pkl_root, 'detection_results')
if osp.exists(save_root):
    shutil.rmtree(save_root)
os.makedirs(osp.join(save_root, 'lwir'), exist_ok=True)
os.makedirs(osp.join(save_root, 'visible'), exist_ok=True)
score_thres = 0.5
nms_thres = None

# init detection results
test_names = sorted(glob(osp.join('/home/zx/cross-modality-det/datasets/LLVIP/LLVIP/lwir/test', '*.jpg')))

pkl_file = osp.join(pkl_root, 'epoch_7.pkl')
with open(pkl_file, 'rb') as f:
    det_bboxes = pickle.load(f)
# test_mode表示是否过滤没有标注GT的图片，True表示不过滤，False表示过滤。
dataset = build_dataset(cfg.data.test, dict(test_mode=True))
data_infos = dataset.data_infos
assert len(data_infos) == len(det_bboxes)

for idx, (info, det) in tqdm(enumerate(zip(data_infos, det_bboxes)), total=len(data_infos)):
    lwir_file = info['file_name']
    rgb_file = lwir_file.replace('lwir', 'visible')
    lwir_img = cv2.imread(lwir_file)
    rgb_img = cv2.imread(rgb_file)
    # ground-truth boxes
    for anno in dataset.get_ann_info(idx)['bboxes']:
        x0, y0, x1, y1 = list(map(int, anno))
        cv2.rectangle(rgb_img, (x0, y0), (x1, y1), (0, 255, 0), 5)
        cv2.rectangle(lwir_img, (x0, y0), (x1, y1), (0, 255, 0), 5)
    # detection boxes
    det_boxes = det[0]
    for box in det_boxes:
        (x0, y0, x1, y1), s = list(map(int, box[:4])), box[4]
        if s<score_thres:
            continue
        cv2.rectangle(rgb_img, (x0, y0), (x1, y1), (0, 0, 255), 5)
        cv2.rectangle(lwir_img, (x0, y0), (x1, y1), (0, 0, 255), 5)
    cv2.imwrite(osp.join(save_root, 'lwir', osp.basename(lwir_file)), lwir_img)
    cv2.imwrite(osp.join(save_root, 'visible', osp.basename(rgb_file)), rgb_img)


import time
from NaiveBayes import NaiveBayes
from KNN import KNN
from SVM import SVM
import numpy as np

filename = "dataset/spambase.data"
file = open(filename, "r")
dataset = np.loadtxt(file, delimiter = ",")

#small tidbit just to make the dataset count even to 4600 (easier k-fold splitting)
dataset = dataset[:-1]

#randomized in the beginning so everyone have the same dataset
np.random.shuffle(dataset)

run = input('Wanna try with Naive Bayes? [y/n] ')
if run == 'y' or run == '':
    nb = NaiveBayes(dataset)
    print('------- NAIVE BAYES -------')
    start = time.time()
    nb.perform(10)
    print("Time elapsed: {} seconds".format(round(time.time() - start,4)))
    print('')

run = input('Wanna try with KNN? [y/n] ')
if run == 'y' or run == '':
    knn = KNN(dataset)
    print('------- K-NEAREST NEIGHBORS -------')
    start = time.time()
    knn.perform(10, 5)
    print("Time elapsed: {} seconds".format(round(time.time() - start,4)))
    print('')

run = input('Wanna try with SVM? [y/n] ')
if run == 'y' or run == '':
    svm = SVM(dataset)
    print('------- SVM -------')
    svm.perform(10, 'linear')
    svm.perform(10, 'poly', 2)
    svm.perform(10, 'rbf')
    svm.perform(10, 'linear', 3, True)
    svm.perform(10, 'poly', 2, True)
    svm.perform(10, 'rbf', 3, True)


import re

def n_gram(arr, n):
    return zip(*(arr[_:] for _ in range(n)))

d = dict()
with open("Extra Material 2 - keyword list_with substring.csv") as f:
    f.readline()
    for line in f:
        line = line.split(',')
        grp, words = int(line[0]), line[1:]
        for w in words:
            w = w.strip('" \n').lower()
            if w in d:
                d[w] = min(d[w], grp)
            else:
                d[w] = grp

out_file = "index,groups_found\n"
with open("Keyword_spam_question.csv", encoding="utf8") as f:
    f.readline()
    for line in f:
        line = line.split(',')
        idx, line = int(line[0]), ''.join(line[1:])
        line = re.sub(r'[^a-z0-9]', ' ', line.strip().lower())
        line = re.sub(r'[ ]+', ' ', line.strip())

        arr = line.split(' ')
        print(idx)
        # print(arr)

        length = len(arr)
        out = set()
        while length > 0:
            # print(f"Length {length}")
            for gram in n_gram(arr, length):
                key = ' '.join(gram)
                if key in d:
                    out.add(d[key])
                    line = line.replace(key, '')
                    line = re.sub(r'[ ]+', ' ', line)
                    arr = line.split(' ')
                    # print(key, arr)
            length -= 1
            if len(arr) < length:
                length = len(arr)
        # print(sorted(out))
        if len(out) == 1:
            out_file += f'{idx},{list(out)}\n'
        else:
            out_file += f'{idx},"{sorted(out)}"\n'

with open("out.csv", 'w', encoding="utf8") as f:
    f.write(out_file)
print("done")


"""Command line scripts for managing dependencies."""

from __future__ import division
from __future__ import absolute_import
from __future__ import print_function
from __future__ import unicode_literals

import argparse
import os
import shlex
import subprocess
import sys

def common_arguments():
    """Generate a parser with all common arguments configured."""
    parser = argparse.ArgumentParser(description='Manage Python dependencies.')
    parser.add_argument(
        '--target',
        required=True,
        help='The target Python package to install dependencies in.',
    )
    parser.add_argument(
        '--pymodule-name',
        default='.pymodules',
        help='The name of the pymodules directory to create.',
    )
    return parser

def install_arguments(parser=None):
    """Attach a subparser for the install command."""
    parser = parser or common_arguments()
    sub_parser = parser.add_subparsers().add_parser('install')
    sub_parser.add_argument(
        'dependencies',
        nargs='+',
    )
    return parser

def generate_install_command(target, pymodule='.pymodule', dependencies=()):
    """Generate a pip command to install dependencies."""
    if not dependencies:

        raise ValueError('Must install at least one dependency.')

    target = os.path.abspath(target)
    command = 'pip install --target {0} --upgrade '.format(
        os.path.join(target, pymodule)
    )
    command_args = []
    for dependency in dependencies:

        if os.path.isfile(dependency):

            command_args.append('-r {0} '.format(dependency))
            continue

        command_args.append('{0} '.format(dependency))

    command = (command + ''.join(command_args)).encode('ascii')
    if sys.version_info[0] > 2:

        command = command.decode('utf8')

    return shlex.split(command)

def install(argv=None):
    """Install a dependency."""
    parser = install_arguments()
    args = parser.parse_args(argv)
    command = generate_install_command(
        args.target,
        args.pymodule_name,
        args.dependencies,
    )
    subprocess.check_call(command)


import pygame.font
from pygame.sprite import Group

from lifecounter import Lifeboat
from install_compatibility import *

class Scoreboard:
	"""A class to report scoring information"""

	def __init__(self,ai_game):
		"""Initialize scorekeeping attributes"""
		self.ai_game = ai_game
		self.screen = ai_game.screen
		self.screen_rect = ai_game.screen.get_rect()
		self.settings = ai_game.settings
		self.stats = ai_game.stats

		# Font setting for scoring information
		self.text_color = (235, 223, 12)
		self.font = pygame.font.SysFont('lucidaconsole',48)
		self.level_font = pygame.font.SysFont('lucidaconsole',32)
		self.message_font = pygame.font.SysFont('lucidaconsole',16)

		# Prepare the initial score image
		self.prep_score()
		self.prep_highscore()
		self.prep_level()
		self.prep_ships()
		self.prep_message()

	def prep_score(self):
		"""Render score onto screen"""
		score_str = "{:,}".format(int(self.stats.score))
		self.score_image = self.font.render(score_str, True,
			self.text_color,self.settings.bg_color)
		self.score_image.set_colorkey(self.settings.bg_color)

		# Display score at top right corner of the screen
		self.score_rect = self.score_image.get_rect()
		self.score_rect.right = self.screen_rect.right - 20
		self.score_rect.top = 5

	def prep_highscore(self):
		"""Turn the high score into a rendered image"""
		highscore = int(self.stats.highscore)
		highscore_str = "Highscore:"+"{:,}".format(highscore)
		self.highscore_image = self.font.render(highscore_str, True,
				self.text_color, self.settings.bg_color)
		self.highscore_image.set_colorkey(self.settings.bg_color)

		# Center highscore on the top center of the screen
		self.highscore_rect = self.highscore_image.get_rect()
		self.highscore_rect.centerx = self.screen_rect.centerx
		self.highscore_rect.top = self.score_rect.top

	def prep_level(self):
		"""Turn level into a rendered image. What else you think moron?"""
		level_str = str(self.stats.level)
		self.level_image = self.level_font.render(level_str, True,
				self.text_color,self.settings.bg_color)
		self.level_image.set_colorkey(self.settings.bg_color)

		# Postition level below the score
		self.level_rect = self.level_image.get_rect()
		self.level_rect.right = self.score_rect.right
		self.level_rect.top = self.score_rect.bottom +10

	def prep_message(self):
		"""Tell the player how to quit the game"""
		message = "(<-) or (->) to move     (^) or (SPACE) to fire     Press (esc) to quit"
		self.mes_image = self.message_font.render(message, True,
				self.text_color,self.settings.bg_color)
		self.mes_image.set_colorkey(self.settings.bg_color)

		# Postition level below the score
		self.mes_rect = self.mes_image.get_rect()
		self.mes_rect.right = self.score_rect.right
		self.mes_rect.bottom = self.screen_rect.bottom - 5

	def prep_ships(self):
		"""Show how many ships are left"""
		self.ships = Group()
		for ship_number in range(self.stats.ships_left):
			ship = Lifeboat(self.ai_game)
			ship.rect.x = 10 + ship_number * (ship.rect.width + 10)
			ship.rect.y = 10
			self.ships.add(ship)

	def show_score(self):
		"""Show score, level, and lives left on the screen"""
		self.screen.blit(self.score_image,self.score_rect)
		self.screen.blit(self.highscore_image,self.highscore_rect)
		self.screen.blit(self.level_image,self.level_rect)
		self.screen.blit(self.mes_image,self.mes_rect)
		self.ships.draw(self.screen)

	def check_highscore(self):
		"""Check to see if there is a new highscore and then update it"""
		if self.stats.score > self.stats.highscore:
			with open(resource_path("highscore.txt"),'w') as f:
				f.write(str(self.stats.score))
			self.stats.highscore = self.stats.score
			self.prep_highscore()


import time
import numpy as np
from deephyper.problem import HpProblem

d = 10
domain = (-32.768, 32.768)
hp_problem = HpProblem()
for i in range(d):
    hp_problem.add_hyperparameter(domain, f"x{i}")

def ackley(x, a=20, b=0.2, c=2*np.pi):
    d = len(x)
    s1 = np.sum(x ** 2)
    s2 = np.sum(np.cos(c * x))
    term1 = -a * np.exp(-b * np.sqrt(s1 / d))
    term2 = -np.exp(s2 / d)
    y = term1 + term2 + a + np.exp(1)
    return y

def run(config):
    time.sleep(1)
    x = np.array([config[f"x{i}"] for i in range(d)])
    x = np.asarray_chkfinite(x)  # ValueError if any NaN or Inf
    return -ackley(x)


import torch
import torch.nn as nn
import torch.nn.functional as F
from transformer.Transformer_EncDec import Encoder, EncoderLayer
from transformer.SelfAttention import FullAttention, AttentionLayer
from NRN_MLP import distance_encoder
import numpy as np
from einops.layers.torch import Rearrange

class NRN_a(nn.Module):
    def __init__(self, features, K_neighbor, depth, d_model, n_heads, drop_out=0.4):
        super(NRN_a, self).__init__()

        self.features = features
        self.K_neighbor = K_neighbor
        self.inputRearrange = Rearrange('b x -> b 1 x')
        self.drop_out = nn.Dropout(p=drop_out)

        self.enc_embedding = distance_encoder(features, d_model)

        self.encoder = Encoder(
            [
                EncoderLayer(
                    AttentionLayer(
                        FullAttention(False), d_model, n_heads),
                    d_model
                ) for l in range(depth)
            ],
            norm_layer=torch.nn.LayerNorm(d_model)
        )
        self.fc = nn.Sequential(
            nn.LayerNorm(d_model),
            Rearrange(' b n d -> b d n'),
            nn.Linear(K_neighbor, 1),
            Rearrange(' b d n -> b (d n)')
        )
        self.decoder = nn.Sequential(
            nn.Linear(d_model, d_model),
            nn.GELU(),
            nn.Linear(d_model, features)
        )
    def forward(self, x):

        x = self.inputRearrange(x)
        x_k_split = torch.chunk(x, self.K_neighbor, dim=2)
        cat_list =[]
        for i in range(self.K_neighbor):
            k_i = x_k_split[i]
            if i==0:
                _x_0 = x_k_split[i]
                k_i = self.drop_out(k_i)
            cat_list.append(k_i)
        x = torch.cat(cat_list, dim=1)

        # [B, N, D]

        enc_out = self.enc_embedding(x)
        enc_out, attns = self.encoder(enc_out, attn_mask=None)
        dec_out = self.decoder(self.fc(enc_out))

        _x_0 = _x_0.squeeze(1)
        missing_pos = (_x_0 != 0)
        _x0_masked = torch.masked_select(_x_0, missing_pos)
        _reconst_masked = torch.masked_select(dec_out, missing_pos).reshape(-1)
        mse = torch.mean(torch.square(_x0_masked - _reconst_masked))
        return dec_out, mse  # [B, D]

if __name__ == "__main__":

    K = 5
    features = 10

    in_x = torch.randn(2, K * features)

    print(in_x.shape)
    x_ = torch.chunk(in_x, K, dim=1)
    print(x_[0].shape)
    m = NRN_a(features=features, K_neighbor=K, depth=2, d_model=128, n_heads=4)

    out_x, loss = m(in_x)
    print(out_x.shape)
    o = out_x.squeeze(1).reshape(-1, features)
    print(o.shape)


import threading
from markov.log_handler.deepracer_exceptions import GenericRolloutException
import rospy
from collections import OrderedDict

from markov.domain_randomizations.constants import GazeboServiceName
from markov.rospy_wrappers import ServiceProxyWrapper
from markov.gazebo_tracker.abs_tracker import AbstractTracker
import markov.gazebo_tracker.constants as consts
from deepracer_msgs.srv import (SetVisualColors, SetVisualColorsRequest,
                                SetVisualColorResponse)

class SetVisualColorTracker(AbstractTracker):
    """
    SetVisualColorTracker Tracker class
    """
    _instance_ = None

    @staticmethod
    def get_instance():
        """Method for getting a reference to the SetVisualColor Tracker object"""
        if SetVisualColorTracker._instance_ is None:
            SetVisualColorTracker()
        return SetVisualColorTracker._instance_

    def __init__(self):
        if SetVisualColorTracker._instance_ is not None:
            raise GenericRolloutException("Attempting to construct multiple SetVisualColor Tracker")

        self.lock = threading.RLock()
        self.visual_name_map = OrderedDict()
        self.link_name_map = OrderedDict()
        self.ambient_map = OrderedDict()
        self.diffuse_map = OrderedDict()
        self.specular_map = OrderedDict()
        self.emissive_map = OrderedDict()

        rospy.wait_for_service(GazeboServiceName.SET_VISUAL_COLORS.value)
        self.set_visual_colors = ServiceProxyWrapper(GazeboServiceName.SET_VISUAL_COLORS.value,
                                                     SetVisualColors)

        SetVisualColorTracker._instance_ = self
        super(SetVisualColorTracker, self).__init__(priority=consts.TrackerPriority.LOW)

    def set_visual_color(self, visual_name, link_name, ambient, diffuse, specular, emissive, blocking=False):
        """
        Set Material that will be updated in next update call
        Args:
            visual_name (str): name of visual
            link_name (str):  name of the link holding visual
            ambient (ColorRBGA): ambient color
            diffuse (ColorRBGA): diffuse color
            specular (ColorRBGA): specular color
            emissive (ColorRBGA): emissive color
            blocking (bool): flag to block or not
        Returns:
            msg (SetVisualColorResponse)
        """
        msg = SetVisualColorResponse()
        msg.success = True
        key = (visual_name, link_name)
        with self.lock:
            if blocking:
                if key in self.visual_name_map:
                    del self.visual_name_map[key]
                    del self.link_name_map[key]
                    del self.ambient_map[key]
                    del self.diffuse_map[key]
                    del self.specular_map[key]
                    del self.emissive_map[key]

                req = SetVisualColorsRequest()
                req.visual_names = [visual_name]
                req.link_names = [link_name]
                req.ambients = [ambient]
                req.diffuses = [diffuse]
                req.speculars = [specular]
                req.emissives = [emissive]
                res = self.set_visual_colors(req)
                msg.success = res.success and res.status[0]
                msg.status_message = res.messages[0] if res.success else res.status_message
            else:
                self.visual_name_map[key] = visual_name
                self.link_name_map[key] = link_name
                self.ambient_map[key] = ambient
                self.diffuse_map[key] = diffuse
                self.specular_map[key] = specular
                self.emissive_map[key] = emissive
        return msg

    def update_tracker(self, delta_time, sim_time):
        """
        Update all color materials tracking to gazebo

        Args:
            delta_time (float): delta time
            sim_time (Clock): simulation time
        """
        with self.lock:
            if self.visual_name_map.values():
                req = SetVisualColorsRequest()

                req.visual_names = self.visual_name_map.values()
                req.link_names = self.link_name_map.values()
                req.ambients = self.ambient_map.values()
                req.diffuses = self.diffuse_map.values()
                req.speculars = self.specular_map.values()
                req.emissives = self.emissive_map.values()
                self.set_visual_colors(req)

            self.visual_name_map = OrderedDict()
            self.link_name_map = OrderedDict()
            self.ambient_map = OrderedDict()
            self.diffuse_map = OrderedDict()
            self.specular_map = OrderedDict()
            self.emissive_map = OrderedDict()


"""initial migartion

Revision ID: 75ae68cc0403
Revises:
Create Date: 2018-11-29 10:25:40.774874

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '75ae68cc0403'
down_revision = None
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('reviews',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('review', sa.String(), nullable=True),
    sa.Column('posted', sa.DateTime(), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_table('reviews')
    # ### end Alembic commands ###


from os import strerror

try:
    binary_file = open('file.bin', 'rb')
    data = bytearray(binary_file.read())
    binary_file.close()

    for b in data:
        print(hex(b), end=' ')

except IOError as e:
    print("An I/O error occurred:", strerror(e.errno))

MISCELANEOS/Trabajando con archivos reales/bytearray3.py


import _thread, usocket, uhashlib, os, time, ubinascii

threadnumber = 2 #Thread number
username = "username"

def mining(i, username):
    addr = usocket.getaddrinfo('51.15.127.80', 2811)[0][-1]
    soc = usocket.socket()
    soc.connect(addr)
    soc.recv(3).decode()
    while True:
        try:
            soc.send(bytes("JOB,"+str(username)+",ESP","utf8")) # Send job request
            job = soc.recv(1024).decode() # Get work from pool
            job = job.split(",") # Split received data to job (job and difficulty)
            difficulty = job[2]
            start = time.time()
            for result in range(100 * int(difficulty) + 1): # Calculate hash with difficulty
                ducos1 = str(ubinascii.hexlify(uhashlib.sha1(str(job[0] + str(result))).digest()))
                if job[1] == ducos1[2:42]:
                    end = time.time()
                    hastime  = end - start
                    hashrate = result / hastime
                    soc.send(bytes(str(result) + "," + ",Multithread ESP32 MicroPython", "utf8"))
                    feedback = soc.recv(1024).decode()
                    if feedback == "GOOD": # If result was good
                        print("Thread:", i, "Accepted share", result, "Difficulty", difficulty, "Hashrate", hashrate, "H/s", "Hashtime", hastime)
                        break
                    elif feedback == "BAD": # If result was bad
                        print("Thread:", i, "Rejected share", result, "Difficulty", difficulty)
                        break
        except Exception as err:
            print(err)

print("ESP32 MicroPython Multithreaded Miner")
for i in range(threadnumber):
    _thread.start_new_thread(mining, (i, username))
    print("Starting thread:", i)


import os
import sys

# restarts the current program.
# Note: this function does not return. Any cleanup action (like saving data) must be done before calling this function.
def restart_program():
    python = sys.executable
    os.execl(python, python, * sys.argv)

ui = input("test: ")

if ui == "1":
    print(ui)
elif ui == "2":
    print(ui)
else:
    restart_program()


'''
Created on Apr 20, 2016

@author: minhtran
'''
import tensorflow as tf
from encoder import AutoEncoder
from configuration import Config

# The main function
def main(_):
    # Load configuration
    config = Config()

    # Build the graph and run session
    with tf.Graph().as_default(), tf.Session() as sess:
        autoEncoder = AutoEncoder(config)
        autoEncoder.build_model()
        sess.run(tf.initialize_all_variables())
        for epoch in range(config.num_epoch):
            with open(config.data_path, 'r') as data_file:
                mse = autoEncoder.run_epoch(sess, data_file)
            if epoch % 1 == 0:
                print ('Epoch %d has mean square error: %g' % (epoch, mse))

        saver = tf.train.Saver(tf.all_variables())
        saver.save(sess, config.save_path)

if __name__ == "__main__":
    tf.app.run()


'''
 @Author: Ritika Patidar
 @Date: 2021-02-17 23:15:10
 @Last Modified by: Ritika Patidar
 @Last Modified time: 2021-02-18 23:15:38
 @Title : count occurance of element in array problem
'''
from array import *
import sys
import os
sys.path.insert(0, os.path.abspath('LogFile'))
import loggerfile

def occurance_element(type_array,element):
    """
    Description:
        this function is define for count occurance of given element
    Parameter:
        type_array (array) : user_defind array
        element (int) : element which occourance will count
    Return:
        return occourace of given element
    """
    return type_array.count(element)

def main():
    """
    Description:
        this main function for defind array and call occurance_element function
    Parameter:
        None
    Return:
        None
    """

    type_array=array("i",[1,2,2,4,3,4,4,5,6])
    element=4
    print("============================ Occurance of element is here =========================================")
    print("occurence of {0} in {1} is : {2}".format(element,list(type_array),occurance_element(type_array,element)))
    loggerfile.Logger("info","get occurance of element successfully")

main()


from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup

import sys
import pathlib
from time import sleep
from urllib.request import urlretrieve
import json

class InvenLostArkItemDictParser:
    def __init__(self):
        super().__init__()

        self.base_link = 'http://lostark.inven.co.kr/dataninfo/item/'

        self.options = webdriver.ChromeOptions()
        self.options.add_argument("user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36")

        self.driver = webdriver.Chrome('chromedriver.exe')
        self.driver.implicitly_wait(5)
        self.driver.get(self.base_link)

    def setBattleItemTable(self):
        html = self.driver.page_source
        soup = BeautifulSoup(html, 'html.parser')
        _ls = soup.select("#lostarkDb > div.lostark.db_filter > table > tbody > tr:nth-child(10) > td > a")

        _target = None
        for _link in _ls:
            if _link.get_text() == "배틀 아이템":
                _target = _link["href"]
                break

        # Go BattleItem Table in Inven
        _target = self.base_link + _target
        self.driver.get(_target)

        html = self.driver.page_source
        soup = BeautifulSoup(html, 'html.parser')
        _ls = soup.select('#lostarkDb > div.lostark.db_board.db_item > table > tbody')

        _tdict = {
            "name":[],
            "link":[],
            "img":[]
        }

        # Get Item Name & page link
        _result = _ls[0].select("a[class='name']")
        for link in _result:
            real_name = ""
            if link.select_one('span') is not None:
                temp = link.select_one('span').get_text()
                real_name = link.get_text().replace(temp, '')
            else:
                real_name = link.get_text()
            _tdict["name"].append(real_name.rstrip())
            _tdict["link"].append(link["href"])

        # Get Item Image link
        _img_link = _ls[0].select("a > div > img")
        for i in range(0, len(_img_link)):
            _tdict["img"].append(_img_link[i]["src"])

        _duplicate_num = []
        for i in range(0, len(_tdict["name"])):
            if "귀속" in _tdict["name"][i]:
                continue
            _duplicate_num.append(i)

        path = pathlib.Path("resources")
        path.mkdir(parents=True, exist_ok=True)
        (path/"battleitem").mkdir(parents=True,exist_ok=True)
        battle_path = path/"battleitem"
        (battle_path/"img").mkdir(parents=True,exist_ok=True)

        for i in _duplicate_num:
            (battle_path/_tdict["name"][i]).mkdir(parents=True,exist_ok=True)
            temp = {
                'name':_tdict["name"][i],
                'link': self.base_link + _tdict["link"][i]
            }
            with (battle_path/_tdict["name"][i]/(_tdict["name"][i]+'.json')).open('w', encoding='UTF-8-sig') as json_file:
                json_file.write(json.dumps(temp, indent=4, ensure_ascii=False))
            url = _tdict["img"][i]
            urlretrieve(url, "./resources/battleitem/"+_tdict["name"][i] + '/' +_tdict["name"][i]+'.png')

    def getLifeContentsItems(self):
        element = self.driver.find_element_by_xpath('//*[@id="lostark-wrapper"]/div/main/div/div/div/div[1]/form/fieldset/div[2]/div[1]/label[11]/input')
        self.driver.execute_script("arguments[0].click();", element)
        sleep(2)
        element = self.driver.find_element_by_xpath('//*[@id="lostark-wrapper"]/div/main/div/div/div/div[1]/form/fieldset/div[2]/div[2]/label[2]/input')
        self.driver.execute_script("arguments[0].click();", element)
        sleep(2)

        html = self.driver.page_source
        soup = BeautifulSoup(html, 'html.parser')
        _ls = soup.select('#lostark-wrapper > div > main > div > div > div > div.itemdic-contents > div.list > div > ul > li')

        for n in _ls:
            _msg = n.text.strip().split("\n")
            print(_msg[0])

def run():
    loaDriver = InvenLostArkItemDictParser()
    loaDriver.setBattleItemTable()

if __name__ == "__main__":
    run()


"""
This file is meant to plot the pairwise box plot of the good region
for the first test in the offline ekf paper
"""

import altair as alt
import pandas as pd
from first_paper_utils import filter_to_good_range_case, filter_to_optimal_case
from first_paper_utils import gait_state_noise_list

#T-test calculation
from scipy.stats import ttest_rel

#Allow plotting large datasets
alt.data_transformers.disable_max_rows()

#Read the data in
data_location = '../ekf_sim/first_paper_NLS_vs_ISA.csv'

df, title = pd.read_csv(data_location), 'All Data'

#Configuration for the first part of the paper NLS vs ISA
baseline_test = 'ISA'
comparison_test = 'NSL'

#Configuration for the second part of the paper PCA_GF vs ISA
# baseline_test = 'ISA'
# comparison_test = 'PCA_GF'

#Filter for the test that we will compare on
df = df[(df['Test']==baseline_test) | (df['Test']==comparison_test)]

#Filter data to optimal case
# df = filter_to_good_range_case(df) #Comment line out for all the "good" range
test_type = baseline_test
df_optimal = filter_to_optimal_case(df,test_type)

#Greatest difference
df_optimal_diff = df.iloc[[214]]  #Opitmal index found manually
df_optimal = df_optimal_diff

# Filter for each method
baseline_results_df = df_optimal[(df_optimal['Test']==baseline_test)]
my_method_results_df = df_optimal[(df_optimal['Test']==comparison_test)]

states = ['phase','phase_dot','stride_length','ramp']

print(f"Mean results for Subject-Indepent \n\r{baseline_results_df[states].mean()}")
print(f"Mean results for Personalized \n\r{my_method_results_df[states].mean()}")

# print(f"std dev results for Subject-Indepent \n\r{baseline_results_df[states].std()}")
# print(f"std dev results for Personalized \n\r{my_method_results_df[states].std()}")


import os
import sys
from pathlib import Path

import numpy as np
import torch
import torch.utils.data
from PIL import Image
from scipy.stats import entropy
from torch import nn
from torch.autograd import Variable
from torch.nn import functional as F
from torch.utils.data import Dataset
from torchvision import transforms as T
from torchvision.models.inception import inception_v3

class Dataset(Dataset):
    def __init__(
        self,
        folder,
        exts = ['jpg', 'jpeg', 'png', 'tiff'],
    ):
        super().__init__()
        self.folder = folder
        self.paths = [p for ext in exts for p in Path(f'{folder}').glob(f'**/*.{ext}')]

        self.transform = T.Compose([
            T.ToTensor()
        ])

    def __len__(self):
        return len(self.paths)

    def __getitem__(self, index):
        path = self.paths[index]
        img = Image.open(path).convert("RGB")
        return self.transform(img)

def inception_score(imgs, cuda=True, batch_size=32, resize=False, splits=1):
    """Computes the inception score of the generated images imgs
    imgs -- Torch dataset of (3xHxW) numpy images normalized in the range [-1, 1]
    cuda -- whether or not to run on GPU
    batch_size -- batch size for feeding into Inception v3
    splits -- number of splits
    """

    N = len(imgs)
    assert batch_size > 0
    assert N > batch_size

    # Set up dtype
    if cuda:
        dtype = torch.cuda.FloatTensor
    else:
        if torch.cuda.is_available():
            print("WARNING: You have a CUDA device, so you should probably set cuda=True")
        dtype = torch.FloatTensor

    # Set up dataloader
    dataloader = torch.utils.data.DataLoader(imgs, batch_size=batch_size)

    # Load inception model
    inception_model = inception_v3(
        pretrained=True, transform_input=False).type(dtype)
    inception_model.eval()
    up = nn.Upsample(size=(299, 299), mode='bilinear').type(dtype)

    def get_pred(x):
        if resize:
            x = up(x)
        x = inception_model(x)
        return F.softmax(x).data.cpu().numpy()

    # Get predictions
    preds = np.zeros((N, 1000))

    for i, batch in enumerate(dataloader, 0):
        batch = batch.type(dtype)
        batchv = Variable(batch)
        batch_size_i = batch.size()[0]

        preds[i*batch_size:i*batch_size + batch_size_i] = get_pred(batchv)

    # Now compute the mean kl-div
    split_scores = []

    for k in range(splits):
        part = preds[k * (N // splits): (k+1) * (N // splits), :]
        py = np.mean(part, axis=0)
        scores = []
        for i in range(part.shape[0]):
            pyx = part[i, :]
            scores.append(entropy(pyx, py))
        split_scores.append(np.exp(np.mean(scores)))

    return np.mean(split_scores), np.std(split_scores)

if __name__ == '__main__':
    gpu_id = 0
    if len(sys.argv)>1:
        gen_img = sys.argv[1]
    else:
        gen_img = ""
    print("eval:"+gen_img)
    sys.stdout.flush()
    gt_img = "xxx/celeba/img_align_celeba_test_crop_64x64"

    os.system("python -m pytorch_fid "+gen_img+" "+gt_img+" --device cuda:"+str(gpu_id))
    os.environ['CUDA_VISIBLE_DEVICES'] = ','.join(str(e) for e in [gpu_id])

    print("Calculating Inception Score...")
    print(inception_score(Dataset(gen_img),
          cuda=True, batch_size=32, resize=True, splits=10))


import cv2
import numpy as np

kernel3 = np.ones((3,3),np.uint8)
kernel5 = np.ones((5,5),np.uint8)
kernel12 = np.ones((12,12),np.uint8)
kernel24 = np.ones((24,24),np.uint8)
kernel48 = np.ones((48,48),np.uint8)
kernel100 = np.ones((100,100),np.uint8)

face = cv2.imread('faceBald.jpg')

b,g,r = cv2.split(face)

def subrgbgray(rgb,treshold):
    row, col , raw = rgb.shape
    #print row*col
    output = np.zeros((row,col,3), np.uint8)
    for i in range(0,row):
        for j in range(0,col):
            if treshold[i,j] != 255:
                output.itemset((i,j,0),0)
                output.itemset((i,j,1),0)
                output.itemset((i,j,2),0)
            else:
                output[i,j]=rgb[i,j]
    return output

face_segmented = cv2.subtract(r,g)

ret, face_segmented = cv2.threshold(face_segmented, 25,255,cv2.THRESH_BINARY)

face_segmented = cv2.morphologyEx(face_segmented, cv2.MORPH_CLOSE, kernel12)

face_segmented = subrgbgray(face, face_segmented)

cv2.imshow('face only', face_segmented)
cv2.imshow('Ori', face)

cv2.waitKey(0)


import sys
import os
import pandas as pd
import numpy as np

if __name__ == "__main__":
    if len(sys.argv) >= 3:
        f = open(sys.argv[1],"r")
        stats = {
            "Dataset Class":[],
            "Dataset":[],
            "Vertices":[],
            "Edges":[],
            "Density":[],
            "Maximum degree":[],
            "Minimum degree":[],
            "Average degree":[],
            "Average degree variance":[],
            "Global clustering coefficient":[],
            "Average clustering coefficient":[],
            "Dijkstra Avg Time":[],
            "SLF-LLL Avg Time":[],
            "Gunrock Avg Time":[],
            "Speedup SLF-LLL over Dijkstra":[],
            "Speedup Gunrock over Dijkstra":[],
            "Speedup Gunrock over SLF-LLL":[],
            "Average visited Dijkstra":[],
            "Average visited SLF-LLL":[],
            "Average visited Gunrock":[]
        }

        types = {
            "Vertices":np.uintc,
            "Edges":np.uintc,
            "Maximum degree":np.uintc,
            "Minimum degree":np.uintc
        }
        for line in f.readlines():
            # Building path to files
            dataset_full_path = line.rstrip('\n')
            dataset_path, dataset_file = os.path.split(dataset_full_path)
            dataset_name, dataset_ext = os.path.splitext(dataset_file)
            dataset_folder = os.path.split(dataset_path)[1]
            times_path = os.path.join(dataset_path,"csv")
            times_csv = os.path.join(times_path,dataset_name+"_times.csv")
            visited_csv = os.path.join(times_path,dataset_name+"_visited.csv")
            frontier_csv = os.path.join(times_path,dataset_name+"_frontier.csv")
            info_path = os.path.join(dataset_path,"info")
            info_csv = os.path.join(info_path,dataset_name+"_info.csv")
            # Reading the csv file
            if os.path.exists(times_csv) and os.path.exists(info_csv):
                # Read Banner
                graph_info = pd.read_csv(info_csv).loc[0]
                # Append Name
                stats["Dataset Class"].append(dataset_folder)
                stats["Dataset"].append(dataset_name)
                # Vertices and Edges
                stats["Vertices"].append(graph_info["Vertices"])
                stats["Edges"].append(graph_info["Edges"])
                # Density
                stats["Density"].append(graph_info["Density"])
                # Degrees Metrocs
                stats["Maximum degree"].append(graph_info["Maximum degree"])
                stats["Minimum degree"].append(graph_info["Minimum degree"])
                stats["Average degree"].append(graph_info["Average degree"])
                stats["Average degree variance"].append(graph_info["Average degreee variance"])
                # Clustering Coefficients
                stats["Global clustering coefficient"].append(graph_info["Global clustering coefficient"])
                stats["Average clustering coefficient"].append(graph_info["Average clustering coefficient"])
                # Append Times and Speedup
                graph_times = pd.read_csv(times_csv)
                dij = np.average(graph_times["Dijkstra"])
                slf = np.average(graph_times["SLF-LLL"])
                gun = np.average(graph_times["Gunrock"])
                stats["Dijkstra Avg Time"].append(dij)
                stats["SLF-LLL Avg Time"].append(slf)
                stats["Gunrock Avg Time"].append(gun)
                stats["Speedup SLF-LLL over Dijkstra"].append(dij/slf)
                stats["Speedup Gunrock over Dijkstra"].append(dij/gun)
                stats["Speedup Gunrock over SLF-LLL"].append(slf/gun)
                if os.path.exists(visited_csv):
                    graph_visited = pd.read_csv(visited_csv)
                    stats["Average visited Dijkstra"].append(np.average(graph_visited["Dijkstra"]))
                    stats["Average visited SLF-LLL"].append(np.average(graph_visited["SLF-LLL"]))
                if os.path.exists(frontier_csv):
                    graph_frontier = pd.read_csv(frontier_csv)
                    frontier_size = graph_frontier.groupby("Execution")["Frontier Size"].sum().mean()
                    stats["Average visited Gunrock"].append(frontier_size)
        stats = pd.DataFrame(stats).astype(types)
        stats.to_csv(sys.argv[2],index=False)
        f.close()
    else:
        print("Correct usage: python stats_datasets.py dataset_list output_file")