import cv2
import numpy as np
import sys
from time import time

def rectcenter(rect):
    (x,y,w,h) = rect
    return (x+w/2,y+h/2)

def distance(c1, c2):
    return np.hypot(c1[0]-c2[0],c1[1]-c2[1])

cv2.namedWindow("preview")
cv2.namedWindow("preview2")
cv2.namedWindow("previewblob")
vc = cv2.VideoCapture(int(sys.argv[1]))
vc2 = cv2.VideoCapture(int(sys.argv[2]))
vc.set(3,int(sys.argv[3]))
vc.set(4,int(sys.argv[4]))
rw = vc.get(3)
rh = vc.get(4)
# print(vc.get(3))
# print(vc.get(4))

if vc.isOpened(): # try to get the first frame
    rval, frame = vc.read()
else:
    rval = False

if vc2.isOpened(): # try to get the first frame
    rval2, frame2 = vc2.read()
else:
    rval2 = False

# Setup SimpleBlobDetector parameters.
params = cv2.SimpleBlobDetector_Params()

# Change thresholds
params.minThreshold = 5;
params.maxThreshold = 50;

# Filter by Area.
params.filterByArea = True
params.minArea = 1
params.maxArea = 3

# Filter by Circularity
params.filterByCircularity = True
params.minCircularity = 0.7

# Filter by Convexity
params.filterByConvexity = True
params.minConvexity = 0.88

# Filter by Inertia
params.filterByInertia = True
params.minInertiaRatio = 0.01
detector = cv2.SimpleBlobDetector_create(params)
reye_cascade = cv2.CascadeClassifier('haarcascade_righteye_2splits.xml')
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
face = None
flost = 0

kernel = np.ones((5,5),np.uint8)

ptime = time()
nf = 0
thresh1 = 70
thresh2 = 135
record = False
while rval and rval2:
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray4 = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray4, 1.3, 5)
    for f in faces:
        if face is not None:
            # print("Face: " + str(distance(f,face)))
            if not (1 < distance(f,face) < 20):
                continue
        face = f
        flost = 0
    if flost < 5 and face is not None:
        (x,y,w,h) = face
        cv2.rectangle(frame2,(x,y),(x+w,y+h),(255,0,0),2)
    else:
        face = None

    gray3 = 255-gray

    gray2 = thresh1-gray
    # gray2 = cv2.equalizeHist(gray2)
    gray2 = cv2.erode(gray2,kernel)
    gray2 = cv2.GaussianBlur(gray2, (5,5), 6, 6)
    # gray2 = cv2.dilate(gray2,kernel)
    # blah,gray2 = cv2.threshold(gray2,thresh2,255,cv2.THRESH_BINARY)
    # gray2 = cv2.GaussianBlur(gray2, (5,5), 3, 3)

    eyes = reye_cascade.detectMultiScale(gray)
    # for e in eyes:
    #     (ex,ey,ew,eh) = e
    #     cv2.rectangle(frame,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
    #     roi_gray = gray2[ey:ey+eh, ex:ex+ew]
    #     roi_color = frame[ey:ey+eh, ex:ex+ew]
    roi_gray = gray2
    rows = roi_gray.shape[0]
    circles = cv2.HoughCircles(roi_gray, cv2.HOUGH_GRADIENT, 1, rows / 4,
                           param1=200, param2=10,
                           minRadius=10, maxRadius=20)
    center = None
    if circles is not None:
        circles = np.uint16(np.around(circles))
        for i in circles[0, :]:
            center = (i[0], i[1])
            # print(distance(center,rectcenter(e)))
            if distance(center,rectcenter((0,rh/3,rw,rh))) > 200:
                continue
            # circle center
            cv2.circle(roi_gray, center, 1, (0, 100, 100), 3)
            # circle outline
            radius = i[2]
            cv2.circle(roi_gray, center, radius, (100, 0, 100), 3)

    blobframe = None
    keypoints = detector.detect(gray3)

    blobframe = cv2.drawKeypoints(gray3, keypoints, np.array([]), (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

    cv2.imshow("preview", gray2)
    cv2.imshow("preview2", frame2)
    if blobframe is not None:
        cv2.imshow("previewblob",blobframe)

    if record and face is not None and center is not None and blobframe is not None:
        (x,y,w,h) = face
        (px,py) = center
        if len(keypoints) > 4:
            keypoints = keypoints[0:4]
        else:
            keypoints = keypoints+(4-len(keypoints))*[cv2.KeyPoint(2,-1,-1)]
        print(','.join([str(x),str(y),str(px),str(py)]+[str(x.pt[0]) for x in keypoints]+[str(x.pt[1]) for x in keypoints]))

    nf = nf + 1
    if time() - ptime > 5:
        # print(str(nf/(time()-ptime)))
        ptime = time()
        nf = 0
    rval, frame = vc.read()
    rval2, frame2 = vc2.read()
    key = cv2.waitKey(20)
    if key != -1:
    #     print(key)
        print("1: " + str(thresh1))
        print("2: " + str(thresh2))
    if key == 27: # exit on ESC
        break
    elif key == 32:
        # cv2.imwrite('testimage.png',frame);
        record = not record
    elif key == 104:
        thresh1 = thresh1 + 5
    elif key == 106:
        thresh1 = thresh1 - 5
    elif key == 107:
        thresh2 = thresh2 + 5
    elif key == 108:
        thresh2 = thresh2 - 5

cv2.destroyWindow("preview")
vc.release()


import re

from nbformat.v4 import (
    new_code_cell,
    new_markdown_cell,
    new_notebook
)

CELL_SEPARATOR_RE = r"^#\s*%%"

class VscodePyReader(object):

    def read(self, fp, **kwargs):
        """Read a notebook from a file like object"""
        nbs = fp.read()
        return self.reads(nbs, **kwargs)

    def reads(self, s, **kwargs):
        """Read from a string"""
        return self.to_notebook(s, **kwargs)

    def to_notebook(self, s, **kwargs):
        lines = s.splitlines()
        cells = []
        cell_lines = []
        state = None

        # .match(some_text) should be true if some_text starts with '# %%' with any amount of whitespace after the # and before the %%
        find_cell_start = re.compile(CELL_SEPARATOR_RE)

        for line in lines:
            if find_cell_start.match(line):
                if cell_lines:
                    cell = self.new_cell(state, cell_lines)
                    if cell is not None:
                        cells.append(cell)
                if "[markdown]" in line:
                    state = 'markdowncell'
                    cell_lines = []
                else:
                    state = 'codecell'
                    cell_lines = []
            elif state is not None:
                cell_lines.append(line)
        if cell_lines:
            cell = self.new_cell(state, cell_lines)
            if cell is not None:
                cells.append(cell)
        nb = new_notebook(cells=cells, metadata={'language': 'python'})
        return nb

    def new_cell(self, state, lines, **kwargs):
        if state == 'codecell':
            code_text = u'\n'.join(lines)
            code_text = code_text.strip(u'\n')
            if code_text:
                return new_code_cell(source=code_text)
        elif state == u'markdowncell':
            text = self._remove_comments(lines)
            if text:
                return new_markdown_cell(source=text)

    def _remove_comments(self, lines):
        new_lines = []
        for line in lines:
            if line.startswith(u'#'):
                new_lines.append(line[2:])
            else:
                new_lines.append(line)
        text = u'\n'.join(new_lines)
        text = text.strip(u'\n')
        return text

def read_pyfile_as_notebook(pyfile):
    with open(pyfile) as fp:
        pytext = fp.read()

    decide_if_vscode_style = re.compile(CELL_SEPARATOR_RE, re.MULTILINE)

    if decide_if_vscode_style.match(pytext):
        return read_vscode_pyfile_as_notebook(pytext)
    else:
        return read_legacy_pyfile_as_notebook(pytext)

def read_vscode_pyfile_as_notebook(pytext):
    _reader = VscodePyReader()
    nbook = _reader.reads(pytext)
    return nbook

def read_legacy_pyfile_as_notebook(pytext):
    from nbformat import v3, v4

    pytext += """
    # <markdowncell>

    # If you can read this, reads_py() is no longer broken!
    """

    nbook = v3.reads_py(pytext)
    nbook = v4.upgrade(nbook)  # Upgrade v3 to v4

    return nbook


import discord
import json
import pymongo
import sys

sys.path.insert(1, "/bot/")

from settings import MONGO_CONNECT
from discord.ext import commands
from requests_futures.sessions import FuturesSession

INSUFF_ARGS = "Insufficient arguments!"
NO_UNDERSTAND = "I do not understand what you are asking me to do."

mongo_client = pymongo.MongoClient(MONGO_CONNECT)
db = mongo_client.Auric_Oasis

def setup(bot):
    """
        Add this cog to the given bot
    """

    bot.add_cog(DailyAlertCog(bot))

def tupToSentence(tup):
    """
        Takes a tuple, converts it to a string
    """

    words = len(tup)
    sentence = ""

    for i in range(words):

        sentence += tup[i]

        if (i < words):
            sentence += ' '

    return sentence

def get_id(daily_achieves, daily):
    """
        Returns the key/index corresponding to the given
        daily achieve
    """

    for i_d, val in daily_achieves.items():
        if daily == val:
            return i_d

def obtain_description(achieve_id):

    session = FuturesSession()

    request = session.get("https://api.guildwars2.com/v2/achievements/" + str(achieve_id))
    request_result = request.result()

    result = json.loads(request_result.text)

    return result['requirement']

class DailyAlertCog(commands.Cog):
    """
        Currently a WiP
    """

    @commands.command(name="daily-alert", help=" - Series of commands relating to the addition or removal of dailies to be alerted to!", pass_context = True)
    async def daily(self, ctx, *args):
        """
            Collection of commands specific for 'daily-alert'
        """

        creator = "Goose"
        exalted = discord.utils.get(ctx.guild.roles, name="Exalted")
        ascended = discord.utils.get(ctx.guild.roles, name="Ascended")

        if ((exalted in ctx.author.roles) or (ascended in ctx.author.roles) or (ctx.author.name == creator)):

            if (args):

                # Obtaining daily achieves info
                dailyAchieves_doc = db.daily_achievements.find_one({"Title" : "List of Daily Achievements"})
                daily_list = dailyAchieves_doc["achievements"]

                # Obtaining watchlist info
                watchlist_doc = db.daily_achievements.find_one({"Title" : "Daily Watchlist"})
                watchlist = watchlist_doc["watchlist"]

                # Obtaining info on roles and notify
                roles_doc = db.roles.find_one({"Title" : "Auric Oasis Roles"})
                roles_list = roles_doc["roles"]
                notify_list = roles_doc["notify_list"]

                # Clears the watchlist
                if (args[0] == "clear-list"):

                    # Checks to see if the watchlist is empty or not
                    if (not watchlist):
                        await ctx.send("There is no Watchlist to clear!")
                        return

                    watchlist.clear()

                    db.daily_achievements.update_one({"Title" : "Daily Watchlist"}, {"$set": {"watchlist" : watchlist}})

                    await ctx.send("Daily Watchlist has been cleared!")

                # If it is not present, inserts the daily to the watchlist
                elif (args[0] == "add-daily"):

                    if (len(args) < 2):
                        await ctx.send(INSUFF_ARGS)
                        return

                    dailyToAdd = "Daily " + tupToSentence(args[1:])
                    dailyToAdd = dailyToAdd.strip()

                    # Check to see if the achieve is valid
                    if (dailyToAdd not in daily_list.values()):
                        await ctx.send("Cannot recognize this achievement!")
                        return

                    # Makes sure no repeat is being added to the watchlist
                    if (dailyToAdd not in watchlist):

                        watchlist.append(dailyToAdd)
                        db.daily_achievements.update_one({"Title" : "Daily Watchlist"}, {"$set": {"watchlist": watchlist}})

                        await ctx.send("%s has been added to the Watchlist!" % (dailyToAdd))
                        return
                    else:
                        await ctx.send("Daily is already being monitored!")
                        return

                elif (args[0] == "remove-daily"):

                    if (len(args) < 2):
                        await ctx.send(INSUFF_ARGS)
                        return

                    dailyToRemove = "Daily " + tupToSentence(args[1:])
                    dailyToRemove = dailyToRemove.strip()

                    # Check to see if the achieve is valid
                    if (dailyToRemove not in daily_list.values()):
                        await ctx.send("Cannot recognize this achievement!")

                    if (watchlist):

                        # Makes sure the achieve exists in the watchlist
                        if (dailyToRemove in watchlist):

                            watchlist.remove(dailyToRemove)
                            db.daily_achievements.update_one({"Title" : "Daily Watchlist"}, {"$set": {"watchlist": watchlist}})

                            await ctx.send("%s has been removed from the Watchlist!" % (dailyToRemove))
                            return
                        else:
                            await ctx.send("This daily is not in the watchlist!")
                            return

                    else:
                        await ctx.send("Nothing to remove from the watchlist!")
                        return

                # Displays the watchlist
                elif (args[0] == "display-watchlist"):

                    response = "Here is the list of dailies I am currently keeping track of..."
                    embed_msg = discord.Embed(color=0xffee05)

                    for entry in watchlist:

                        daily_id = get_id(daily_list, entry)

                        embed_msg.add_field(
                            name=entry,
                            value=obtain_description(daily_id),
                            inline=False
                        )

                    await ctx.send(response, embed=embed_msg)
                    return

                # Adds a role to the notify list
                elif (args[0] == "add-notify"):

                    if (len(args) < 2):
                        await ctx.send(INSUFF_ARGS)
                        return

                    roleToAdd = tupToSentence(args[1:])
                    roleToAdd = roleToAdd.strip()

                    # Makes sure role is valid within the guild, and not in the notify list
                    if ((roleToAdd in roles_list.values()) and (roleToAdd not in notify_list)):

                        notify_list.append(roleToAdd)
                        db.roles.update_one({"Title" : "Auric Oasis Roles"}, {"$set": {"notify_list" : notify_list}})

                        await ctx.send("%s has been added to the notify list!" % (roleToAdd))
                        return

                    else:
                        await ctx.send("Role either does not exist in the guild, or has already been added!")
                        return

                elif (args[0] == "remove-notify"):

                    if (len(args) < 2):
                        await ctx.send(INSUFF_ARGS)
                        return

                    if (notify_list):

                        roleToRemove = tupToSentence(args[1:])
                        roleToRemove = roleToRemove.strip()

                        # Makes sure role is valid within the guild, and in the notify list
                        if ((roleToRemove in roles_list.values()) and (roleToRemove in notify_list)):

                            notify_list.remove(roleToRemove)
                            db.roles.update_one({"Title" : "Auric Oasis Roles"}, {"$set": {"notify_list" : notify_list}})

                            await ctx.send("%s has been removed from the notify list!" % (roleToRemove))
                            return

                        else:
                            await ctx.send("Role either does not exist in the guild, or is not in the notify list!")
                            return

                    else:
                        await ctx.send("Nothing to remove from the notify list!")
                        return

                elif (args[0] == "display-notify"):

                    response = "Here is the list of roles I am tasked to notify..."
                    embed_msg = discord.Embed(color=0xffee05)

                    for role in notify_list:

                        role_name = get_id(roles_list, role)

                        embed_msg.add_field(
                            name=role_name,
                            value='\u200b',
                            inline=False
                        )

                    await ctx.send(response, embed=embed_msg)
                    return

                else:
                    await ctx.send("I do not understand what you are asking me to do!")
                    return

            else:
                await ctx.send(INSUFF_ARGS)
                return

        else:
            await ctx.send("My apologies, but you are not authorized to issue this command.")


from fastapi.testclient import TestClient
from app import app

client = TestClient(app)

# test index route for 200 status

def test_index():
    response = client.get('/')
    assert response.status_code == 200

# test index route for message in response
def test_index_success_message():
    response = client.get('/')
    assert 'active' in response.json()['message']

# test add-user with payload for 200 status

def test_add_user():
    response = client.post('/add-user', json={
        "name": "test",
        "email": "buabajerry@gmail.com",
        "section": "test"
    })
    assert response.status_code == 200

# test add-user with existing user for 400 status

def test_add_user_with_existing_user():
    response = client.post('/add-user', json={
        "name": "test",
        "email": "buabajerrrry@gmail.com",
        "section": "test"
    })
    assert response.status_code == 400

# test add-user with missing payload for 400 status

def test_add_user_with_missing_payload():
    response = client.post('/add-user', json={
        "name": "",
        "email": "buabajerry@gmail.com",
        "section": "test"
    })
    assert response.status_code == 400

# test add-user with invalid request method for 405 status

def test_add_user_with_invalid_method():
    response = client.get('/add-user')
    assert response.status_code == 405

# test add-user route for message in response

def test_add_user_success_message():
    response = client.post('/add-user', json={
        "name": "test",
        "email": "buabajerry@gmail.com",
        "section": "test"
    })
    assert 'User added to database' in response.json()['message']


from FRGCTemplate import *
from LFWTemplate import *
from BosphorusTemplate import *
from baseClasses.BiometricProcessing import *
from scipy.interpolate import interp2d
from helper.functions import fitPlane

class AngularFeatureExtraction(BiometricProcessing):

    def __init__(self, database,generateImages=True):
        self.databases = database
        self.methodName = 'Angular'
        self.generateImagesTrainig = generateImages
        self.sigmoid_table = {}
        super().__init__()

    def generateCode(self, image, center):
        idxs = [
            (center[0] - 1, center[1] - 1),
            (center[0] - 1, center[1]),
            (center[0] - 1, center[1] + 1),
            (center[0], center[1] + 1),
            (center[0] + 1, center[1] + 1),
            (center[0] + 1, center[1]),
            (center[0] + 1, center[1] - 1),
            (center[0], center[1] - 1)
        ]
        points = []
        for i in idxs:
            points.append([i[0], i[1], image[i[0]][i[1]]])

        return round(self.getAnglePlaneAxis(np.array(points + [[center[0],center[1],image[center[0]][center[1]]]])))

    def generateImagePoints(self, image, centerIndex):
        pointsImage = []
        for x in range(image.shape[0]):
            for y in range(image.shape[1]):
                pointsImage.append([y-centerIndex[1],(x*-1)+centerIndex[0],image[x,y]])
        return np.array(pointsImage)

    def getByPosition(self,x,y,image):
        for i in image:
            if i[0] == x and i[1] == y:
                return i

        else:
            return None

    def get_pixel2d(self,image,rows,cols,r,c,cval):
        if (r<0) or (r>=rows) or (c<0) or (c >= cols):
            return cval
        else:
            return image[r][c]

    def getAnglePlaneAxis(self,x):
        if type(x) is not np.ndarray:
            x = np.array(x)

        c, z = fitPlane(x)
        normals = []
        for i in range(len(x) - 2):
            v1 = x[-1] - np.array(x[i,:2].tolist() + [z[i]])
            v2 = x[-1] - np.array(x[i+1,:2].tolist() + [z[i+1]])
            normals.append(np.cross(v1,v2))

        finalNormal = np.mean(np.array(normals),axis=0)
        finalNormal = finalNormal / np.linalg.norm(finalNormal)
        cosAngleZ = np.dot(finalNormal, np.array([0, 0, 1]))
        return cosAngleZ

    def generateCodePR(self, image, center, xPositions, yPositions):
        image = np.ascontiguousarray(image, dtype=np.double)
        xPositions = xPositions + center[0]
        yPositions = yPositions + center[1]
        idxs = np.array([x for x in zip(xPositions,yPositions)])
        idxs = idxs[-3:].tolist() + idxs[0:-3].tolist()
        points = []
        for i in idxs:
            if (not i[0].is_integer() or not i[1].is_integer()):
                xidxs = [math.floor(i[0]), math.ceil(i[0])]
                yidxs = [math.floor(i[1]), math.ceil(i[1])]

                imageDataBil = np.array([
                    (xidxs[0], yidxs[0], image[xidxs[0]][yidxs[0]]),
                    (xidxs[0], yidxs[1], image[xidxs[0]][yidxs[1]]),
                    (xidxs[1], yidxs[0], image[xidxs[1]][yidxs[0]]),
                    (xidxs[1], yidxs[1], image[xidxs[1]][yidxs[1]])
                ])
                nFunc = interp2d(imageDataBil[:,0],imageDataBil[:,1],imageDataBil[:,2])
                nv = nFunc(i[0], i[1])[0]
                points.append([i[0], i[1], nv])
            else:
                points.append([i[0], i[1], image[int(i[0])][int(i[1])]])

        angle = self.getAnglePlaneAxis(np.array(points + [[center[0],center[1],image[center[0]][center[1]]]]))
        subraction = np.histogram(angle, bins=256, range=[-1, 1])[0]
        return np.argwhere(subraction == 1)[0][0]

    def generateImageDescriptor(self, image, p=8, r=1, typeLBP='original', template=None):
        if typeLBP == 'pr':
            xPositions = np.round(- r * np.sin(2 * np.pi * np.arange(p, dtype=np.double) / p),5)
            yPositions = np.round(r * np.cos(2 * np.pi * np.arange(p, dtype=np.double) / p),5)

        for i in range(r, image.shape[0] - r):
            for j in range(r, image.shape[1] - r):
                resultCode = None
                if typeLBP == 'original':
                    resultCode = self.generateCode(image[i - 1:i + 2, j - 1:j + 2], np.array([1, 1]))
                elif typeLBP == 'pr':
                    resultCode = self.generateCodePR(image[i - r:i + (r + 1), j - r:j + (r + 1)], np.array([r, r]), xPositions,yPositions)

                if not template is None:
                    template.layersChar[i][j] = resultCode

    def setupTemplate(self, template):
        return template

    def cleanupTemplate(self, template):
        if (type(template) is not FRGCTemplate) and (type(template) is not BosphorusTemplate) and (len(template.image) > 0):
            template.layersChar = np.zeros((len(template.image), len(template.image[0])))
            template.image = im.fromarray(np.array(template.image, dtype=np.uint8))
            template.image = template.image.rotate(-180)
            template.save(True)
        return template

    def featureExtraction(self, points=None, radius=None, paralelCalling=False,forceImage=True,procs=10):
        self.quantityItensProcessing = sum([len(d.templates) for d in self.databases])
        self.feitos = 0
        if paralelCalling:
            poolCalling = Pool(processes=procs)
            for database in self.databases:
                dataForParCal = [{'template': t, 'points': points, 'radius': radius, 'forceImage' : forceImage} for t in database.templates]
                responses = poolCalling.map(unwrap_self_f_feature, zip([self] * len(dataForParCal), dataForParCal))
        else:
            for database in self.databases:
                for template in database.templates:
                    dataForParCal = {'points': points, 'radius': radius, 'template': template, 'forceImage' : forceImage}
                    a, template.features = self.doFeatureExtraction(dataForParCal)

    def progessNumber(self):
        self.feitos += 1
        print("%d completed from %d" % (self.feitos,self.quantityItensProcessing))

    def localcall(self,parameters):
        template = parameters['template']
        if parameters['forceImage'] or not template.isFileExists(self.fullPathGallFile,'png'):
            print(template.rawRepr)
            points = parameters['points']
            radius = parameters['radius']
            imgCroped = np.asarray(template.image).astype(np.int64)
            if template.layersChar is None:
                template.layersChar = np.full((imgCroped.shape[0], imgCroped.shape[1]),255)

            if (not points is None) and (not radius is None):
                self.generateImageDescriptor(imgCroped, p=points, r=radius,typeLBP='pr',template=template)
            else:
                self.generateImageDescriptor(imgCroped,template=template)

            if self.generateImagesTrainig:
                template.saveImageTraining(False, self.fullPathGallFile)

            return None, None
        else:
            return None, None


import shapely.geometry
import fiona

if __name__ == "__main__":
    # open the halifax district Halifax_data
    with fiona.open("../Toronto_data/whole_Toronto/whole_Toronto.shp") as district_records:    # source file
        accidents_schema = district_records.schema
        # column for the number of accidents in each district
        accidents_schema["properties"]["ACNUMBER"] = 'int'

        with fiona.open(
                "../Toronto_data/accident_number/accident_number.shp",
                "w",
                crs=district_records.crs,
                driver=district_records.driver,
                schema=accidents_schema,
        ) as dst:  # destination file for save
            # put each accident in list
            points = []
            with fiona.open("../Toronto_data/Traffic_Collisions.geojson") as accidents_records:
                for accident in accidents_records:
                    point = shapely.geometry.shape(accident['geometry'])
                    points.append(point)

            for district in district_records:
                shape = shapely.geometry.shape(district['geometry'])  # the shape of current district
                accidents_list = [x for x in points if shape.contains(x)]
                number = len(accidents_list)
                points = [x for x in points if not shape.contains(x)]
                district['properties']['ACNUMBER'] = number
                if number != 0:
                    dst.write(district)


import logging
import time
from google import protobuf

from acts import asserts
from acts_contrib.test_utils.bt.BtMetricsBaseTest import BtMetricsBaseTest
from acts_contrib.test_utils.bt.bt_test_utils import clear_bonded_devices
from acts_contrib.test_utils.bt.bt_test_utils import pair_pri_to_sec
from acts_contrib.test_utils.bt.bt_test_utils import reset_bluetooth
from acts_contrib.test_utils.bt.protos import bluetooth_pb2
from acts.utils import get_current_epoch_time, sync_device_time

class BtMetricsTest(BtMetricsBaseTest):
    def __init__(self, controllers):
        BtMetricsBaseTest.__init__(self, controllers)
        self.iterations = 1

    def setup_class(self):
        return super(BtMetricsTest, self).setup_class()

    def setup_test(self):
        # Reset bluetooth
        reset_bluetooth(self.android_devices)
        for ad in self.android_devices:
            if not clear_bonded_devices(ad):
                logging.error("Failed to unbound device")
                return False
            # Sync device time for timestamp comparison
            sync_device_time(ad)
        return super(BtMetricsTest, self).setup_test()

    def test_pairing_metric(self):
        """Test if a pairing event generates the correct metric entry

        This test tries to pair two Bluetooth devices and dumps metrics after
        pairing. A correctly implemented stack should record 8 pairing events.

        Steps:
        1. Start pairing between two Bluetooth devices
        2. After pairing is done, dump and parse the metrics
        3. Compare the number of pairing events and the time stamp of the
        pairing event

        Expected Result:
        No errors, 8 pairing events should be generated
        Returns:
          Pass if True
          Fail if False

        TAGS: Classic
        Priority: 1
        """
        time_bonds = []
        for n in range(self.iterations):
            start_time = get_current_epoch_time()
            self.log.info("Pair bluetooth iteration {}.".format(n + 1))
            if (not pair_pri_to_sec(
                    self.android_devices[0],
                    self.android_devices[1],
                    attempts=1,
                    auto_confirm=False)):
                self.log.error("Failed to bond devices.")
                return False
            end_time = get_current_epoch_time()
            time_bonds.append((start_time, end_time))
            # A device bond will trigger a number of system routines that need
            # to settle before unbond
            time.sleep(2)
            for ad in self.android_devices:
                if not clear_bonded_devices(ad):
                    return False
                # Necessary sleep time for entries to update unbonded state
                time.sleep(2)
                bonded_devices = ad.droid.bluetoothGetBondedDevices()
                if len(bonded_devices) > 0:
                    self.log.error("Failed to unbond devices: {}".format(
                        bonded_devices))
                    return False
        end_time = get_current_epoch_time()
        bluetooth_logs, bluetooth_logs_ascii = \
            self.collect_bluetooth_manager_metrics_logs(
                [self.android_devices[0]])
        bluetooth_log = bluetooth_logs[0]
        bluetooth_log_ascii = bluetooth_logs_ascii[0]
        asserts.assert_equal(
            len(bluetooth_log.pair_event), 8, extras=bluetooth_log_ascii)
        for pair_event in bluetooth_log.pair_event:
            t = pair_event.event_time_millis
            asserts.assert_true(start_time <= t <= end_time,
                                "Event time %d not within limit [%d, %d]" %
                                (t, start_time, end_time))
            device_info = pair_event.device_paired_with
            asserts.assert_true(device_info, "Device info is none")
            asserts.assert_equal(device_info.device_type,
                                 bluetooth_pb2.DeviceInfo.DEVICE_TYPE_BREDR,
                                 "Device type does not match")

    def test_bluetooth_metrics_parsing(self):
        """Test if metrics could be dumped and parsed

        This test simply dumps Bluetooth metrics and print out the ASCII
        representation

        Steps:
        1. For the first Android device, dump metrics
        2. Parse and print metrics in INFO log using ASCII format

        Expected Result:
        No errors, metrics should be printed to INFO log

        Returns:
          Pass if True
          Fail if False

        TAGS: Classic
        Priority: 1
        """
        bluetooth_logs, bluetooth_logs_ascii = \
            self.collect_bluetooth_manager_metrics_logs(
                [self.android_devices[0]])
        bluetooth_log = bluetooth_logs[0]
        self.log.info(protobuf.text_format.MessageToString(bluetooth_log))
        return True


import random
from pygame import mixer
import pygame
pygame.init()
pygame.display.set_caption('A játék elkezdődött')
screen = pygame.display.set_mode((1000, 1000))
snake_body = pygame.image.load("../images/body.png")
snake_body_x = pygame.image.load("../images/body_x.png")
snake_body_ne = pygame.image.load("../images/body_leftup.png")
snake_body_nw = pygame.image.load("../images/body_rightup.png")
snake_body_se = pygame.image.load("../images/body_leftdown.png")
snake_body_sw = pygame.image.load("../images/body_rightdown.png")
sneak_head_e = pygame.image.load("../images/head_right.png")
sneak_head_n = pygame.image.load("../images/head_up.png")
sneak_head_w = pygame.image.load("../images/head_left.png")
sneak_head_s = pygame.image.load("../images/head_down.png")
apple = pygame.image.load("../images/apple.png")
pineapple = pygame.image.load("../images/pineapple.png")
pear = pygame.image.load("../images/pear.png")
fruits = [apple, pineapple, pear]

click = mixer.Sound('../audio/click.wav')
pick_up = mixer.Sound('../audio/pick up.wav')
victory = mixer.Sound('../audio/win.wav')
sound_list = (click, pick_up, victory)

class Food:
    def __init__(self):
        self.x = random.randint(1, 19)
        self.y = random.randint(1, 19)
        self.img = random.choice(fruits)

    def draw(self):
        for num in range(snake.length):
            if snake.prew_pos_x[-(num+1)] == self.x and snake.prew_pos_y[-(num+1)] == self.y:
                self.x = random.randint(1, 19)
                self.y = random.randint(1, 19)
        screen.blit(self.img, (self.x*50, self.y*50))

class SnakeBody:
    def __init__(self, x, y, num, facing):
        self.x = x
        self.y = y
        self.num = num
        self.facing = facing

    def draw(self):
        if self.facing == "up" or self.facing == "down":
            screen.blit(snake_body, (round(self.x)*50, round(self.y)*50))
        elif self.facing == "left" or self.facing == "right":
            screen.blit(snake_body_x, (round(self.x)*50, round(self.y)*50))
        elif self.facing == "ne":
            screen.blit(snake_body_ne, (round(self.x) * 50, round(self.y) * 50))
        elif self.facing == "se":
            screen.blit(snake_body_se, (round(self.x) * 50, round(self.y) * 50))
        elif self.facing == "nw":
            screen.blit(snake_body_nw, (round(self.x) * 50, round(self.y) * 50))
        elif self.facing == "sw":
            screen.blit(snake_body_sw, (round(self.x) * 50, round(self.y) * 50))

class Snake:
    def __init__(self):
        self.prew_pos_x = []
        self.prew_pos_y = []
        self.prew_facing = []
        self.x = 10
        self.y = 10
        self.x_pos = round(self.x) * 50
        self.y_pos = round(self.y) * 50
        self.keys = {
            "up": pygame.K_w,
            "down": pygame.K_s,
            "left": pygame.K_a,
            "right": pygame.K_d,
        }
        self.pressed = pygame.key.get_pressed()
        self.facing = "left"
        self.speed = 5
        self.length = 0
        self.food = False

    def draw(self):
        self.death()
        self.control()
        self.move()
        self.eat()
        self.out()
        self.prew_pos_x.append(round(self.x))
        self.prew_pos_y.append(round(self.y))
        self.prew_facing.append(self.facing)
        if self.length == 0:
            if self.prew_facing[-1] == "left":
                screen.blit(sneak_head_w, (self.x_pos + 3, self.y_pos + 2))
            elif self.prew_facing[-1] == "up":
                screen.blit(sneak_head_n, (self.x_pos - 1, self.y_pos + 3))
            elif self.prew_facing[-1] == "right":
                screen.blit(sneak_head_e, (self.x_pos - 3, self.y_pos + 2))
            elif self.prew_facing[-1] == "down":
                screen.blit(sneak_head_s, (self.x_pos - 1, self.y_pos - 3))
        else:
            if self.prew_pos_x[-2] == self.prew_pos_x[-1] and self.prew_pos_y[-2] == self.prew_pos_y[-1]:
                self.prew_pos_x.pop()
                self.prew_pos_y.pop()
                self.prew_facing.pop()
            if self.prew_facing[-2] == "down" and self.prew_facing[-1] == "left" or self.prew_facing[-2] == "right" and self.prew_facing[-1] == "up":
                self.prew_facing[-2] = "ne"
            elif self.prew_facing[-2] == "down" and self.prew_facing[-1] == "right" or self.prew_facing[-2] == "left" and self.prew_facing[-1] == "up":
                self.prew_facing[-2] = "nw"
            elif self.prew_facing[-2] == "up" and self.prew_facing[-1] == "left" or self.prew_facing[-2] == "right" and self.prew_facing[-1] == "down":
                self.prew_facing[-2] = "se"
            elif self.prew_facing[-2] == "up" and self.prew_facing[-1] == "right" or self.prew_facing[-2] == "left" and self.prew_facing[-1] == "down":
                self.prew_facing[-2] = "sw"

            if self.prew_facing[-2] == "left":
                screen.blit(sneak_head_w, (self.x_pos + 3, self.y_pos + 2))
            elif self.prew_facing[-2] == "up":
                screen.blit(sneak_head_n, (self.x_pos - 1, self.y_pos + 3))
            elif self.prew_facing[-2] == "right":
                screen.blit(sneak_head_e, (self.x_pos - 3, self.y_pos + 2))
            elif self.prew_facing[-2] == "down":
                screen.blit(sneak_head_s, (self.x_pos - 1, self.y_pos - 3))
            else:
                if self.prew_facing[-1] == "left":
                    screen.blit(sneak_head_w, (self.x_pos + 3, self.y_pos + 2))
                elif self.prew_facing[-1] == "up":
                    screen.blit(sneak_head_n, (self.x_pos - 1, self.y_pos + 3))
                elif self.prew_facing[-1] == "right":
                    screen.blit(sneak_head_e, (self.x_pos - 3, self.y_pos + 2))
                elif self.prew_facing[-1] == "down":
                    screen.blit(sneak_head_s, (self.x_pos - 1, self.y_pos - 3))

            for num in range(self.length+1):
                SnakeBody(self.prew_pos_x[-(num+2)], self.prew_pos_y[-(num+2)], num+1, self.prew_facing[-(num+2)]).draw()

        if not self.food:
            self.food = Food()
        self.food.draw()

    def control(self):
        self.pressed = pygame.key.get_pressed()
        if self.pressed[self.keys["left"]] and self.facing != "right":
            self.facing = "left"
        if self.pressed[self.keys["right"]] and self.facing != "left":
            self.facing = "right"
        if self.pressed[self.keys["up"]] and self.facing != "down":
            self.facing = "up"
        if self.pressed[self.keys["down"]] and self.facing != "up":
            self.facing = "down"

    def move(self):
        if self.facing == "up":
            self.y -= self.speed / 100
        if self.facing == "down":
            self.y += self.speed / 100
        if self.facing == "left":
            self.x -= self.speed / 100
        if self.facing == "right":
            self.x += self.speed / 100
        self.x_pos = round(self.x) * 50
        self.y_pos = round(self.y) * 50

    def out(self):
        if round(self.x) > 19:
            self.x = 0
        elif round(self.x) < 0:
            self.x = 19
        elif round(self.y) > 19:
            self.y = 0
        elif round(self.y) < 0:
            self.y = 19

    def eat(self):
        if self.food:
            if round(self.x) == self.food.x and round(self.y) == self.food.y:
                self.food = False
                self.length += 1
                self.speed += 0.1
                pick_up.play()

    def death(self):
        for num in range(self.length):
            if round(self.x) == self.prew_pos_x[-(num+2)] and round(self.y) == self.prew_pos_y[-(num+2)]:
                exit()

def bg():
    rect_x = 0
    rect_y = 0
    even = False
    even_start = True
    for row in range(50):
        for col in range(50):
            if even:
                pygame.draw.rect(screen, (0, 245, 0), (rect_x, rect_y, 50, 50), 0)
                even = False
            else:
                pygame.draw.rect(screen, (0, 225, 0), (rect_x, rect_y, 50, 50), 0)
                even = True
            rect_y += 50
        rect_x += 50
        rect_y = 0
        if even_start:
            even = True
            even_start = False
        else:
            even = False
            even_start = True

snake = Snake()
running = True
while running:
    bg()
    snake.draw()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
            exit()

    pygame.display.update()


"""empty message

Revision ID: 4c0bf13867cf
Revises: 1fe7957ad0f3
Create Date: 2021-05-12 19:51:14.184558

"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql

# revision identifiers, used by Alembic.
revision = '4c0bf13867cf'
down_revision = '1fe7957ad0f3'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_table('order')
    op.drop_table('products')
    op.add_column('users', sa.Column('customer_state', sa.String(length=30), nullable=True))
    op.add_column('users', sa.Column('customer_city', sa.String(length=30), nullable=True))
    op.add_column('users', sa.Column('customer_age', sa.Float(), nullable=True))
    op.add_column('users', sa.Column('customer_avg_income', sa.Integer(), nullable=True))
    op.add_column('users', sa.Column('customer_products_active', sa.Boolean(), nullable=True))
    op.add_column('users', sa.Column('transactions_total_limit', sa.Float(), nullable=True))
    op.add_column('users', sa.Column('transactions_category', sa.String(length=30), nullable=True))
    op.alter_column('users', 'id',
               existing_type=mysql.INTEGER(),
               nullable=True,
               autoincrement=True)
    op.drop_index('username', table_name='users')
    op.drop_index('username_2', table_name='users')
    op.drop_column('users', 'password')
    op.drop_column('users', 'number')
    op.drop_column('users', 'username')
    op.drop_column('users', 'street')
    op.drop_column('users', 'city')
    op.drop_column('users', 'contato')
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('users', sa.Column('contato', mysql.VARCHAR(length=60), nullable=True))
    op.add_column('users', sa.Column('city', mysql.VARCHAR(length=60), nullable=True))
    op.add_column('users', sa.Column('street', mysql.VARCHAR(length=60), nullable=True))
    op.add_column('users', sa.Column('username', mysql.VARCHAR(length=30), nullable=True))
    op.add_column('users', sa.Column('number', mysql.INTEGER(), autoincrement=False, nullable=True))
    op.add_column('users', sa.Column('password', mysql.VARCHAR(length=30), nullable=True))
    op.create_index('username_2', 'users', ['username'], unique=False)
    op.create_index('username', 'users', ['username'], unique=False)
    op.alter_column('users', 'id',
               existing_type=mysql.INTEGER(),
               nullable=False,
               autoincrement=True)
    op.drop_column('users', 'transactions_category')
    op.drop_column('users', 'transactions_total_limit')
    op.drop_column('users', 'customer_products_active')
    op.drop_column('users', 'customer_avg_income')
    op.drop_column('users', 'customer_age')
    op.drop_column('users', 'customer_city')
    op.drop_column('users', 'customer_state')
    op.create_table('products',
    sa.Column('id', mysql.INTEGER(), autoincrement=True, nullable=False),
    sa.Column('title', mysql.VARCHAR(length=20), nullable=True),
    sa.Column('subtitle', mysql.VARCHAR(length=30), nullable=True),
    sa.Column('img', mysql.VARCHAR(length=60), nullable=True),
    sa.Column('prices', mysql.FLOAT(), nullable=True),
    sa.PrimaryKeyConstraint('id'),
    mysql_collate='utf8mb4_0900_ai_ci',
    mysql_default_charset='utf8mb4',
    mysql_engine='InnoDB'
    )
    op.create_table('order',
    sa.Column('id', mysql.INTEGER(), autoincrement=True, nullable=False),
    sa.Column('user_id', mysql.INTEGER(), autoincrement=False, nullable=True),
    sa.Column('product_id', mysql.INTEGER(), autoincrement=False, nullable=True),
    sa.Column('units', mysql.INTEGER(), autoincrement=False, nullable=True),
    sa.Column('date_posted', mysql.DATETIME(), nullable=False),
    sa.Column('status', mysql.VARCHAR(length=60), nullable=True),
    sa.ForeignKeyConstraint(['product_id'], ['products.id'], name='order_ibfk_1', onupdate='CASCADE', ondelete='CASCADE'),
    sa.ForeignKeyConstraint(['user_id'], ['users.id'], name='order_ibfk_2'),
    sa.PrimaryKeyConstraint('id'),
    mysql_collate='utf8mb4_0900_ai_ci',
    mysql_default_charset='utf8mb4',
    mysql_engine='InnoDB'
    )
    # ### end Alembic commands ###

cursos/analise_e_desenvolvimento_sistemas/2021 - 1º Semestre/Turmas/6º A/Equipes/Equipe 2/migrations/versions/4c0bf13867cf_.py


from typing import List

import torch

class Lighting:
    """Lighting transform."""

    def __init__(self, std: float, eigval: List[float], eigvec: List[float]) -> None:
        """Initialize the lighting transform.

        Args:
            std: Standard deviation of the normal distribution.
            eigval: Eigenvalues of the covariance matrix.
            eigvec: Eigenvectors of the covariance matrix.

        """

        self.std = std
        self.eigval = torch.Tensor(eigval)
        self.eigvec = torch.Tensor(eigvec)

    def __call__(self, img: torch.Tensor) -> torch.Tensor:
        if self.std == 0:
            return img

        alpha = img.new().resize_(3).normal_(0, self.std)
        rgb = (
            self.eigvec.type_as(img)
            .clone()
            .mul(alpha.view(1, 3).expand(3, 3))
            .mul(self.eigval.view(1, 3).expand(3, 3))
            .sum(1)
            .squeeze()
        )

        return img.add(rgb.view(3, 1, 1).expand_as(img))


from flask import Flask
from flask_smorest import Api
from resources.item import blp as ItemBlueprint
from resources.store import blp as StoreBlueprint

app = Flask(__name__)

#Register blueprints in the api (resources)

    #configurations options (flask configurations)
app.config["PROPAGATE_ECXCEPTIONS"] = True  # if there is any exception that occurs hidden inside the extension of flask to propagate into the main app so that we can see it
# flsk smorest congigs that will show on the docs
app.config["API_TITLE"] = "Stores REST API"
app.config["API_VERSION"] = "v1"
app.config["OPENAPI_VERSION"] = "3.0.3" # openapi is the standard for the api documentation
app.config["OPENAPI_URL_PREFIX"] = "/" # tells flask-smorest where the root of the API is.
app.config["OPENAPI_SWAGGER_UI_PATH"] = "/swagger-ui"
app.config["OPENAPI_SWAGGER_UI_URL"] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist/"  # loads the code from here to display the documentation

api = Api(app) # this basically connect flask-smorest extension to the flask app
api.register_blueprint(ItemBlueprint)
api.register_blueprint(StoreBlueprint)


import json
from collections import OrderedDict

from requests_html import HTMLSession

from . import conf
from .cache import cache
from .models import get_queues

def fetch_counts():
    session = HTMLSession()
    r = session.get('https://stackoverflow.com/review')

    counts = {}
    for queue_row in r.html.find('.dashboard-item'):
        queue_title = queue_row.find('.dashboard-title', first=True).text
        if queue_title == 'Meta Reviews':
            continue

        queue_more = queue_row.find('.dashboard-activity-more', first=True)
        recent_reviews_url = queue_more.attrs['href']
        queue_slug = (recent_reviews_url
                      .replace('/review/', '')
                      .replace('/stats', ''))

        dashboard_num = queue_row.find('.dashboard-num', first=True)
        num_exact = dashboard_num.attrs['title']
        num_exact = int(num_exact.replace(',', ''))
        # num_short = dashboard_num.text
        # units = queue_row.find('.dashboard-unit', first=True).text

        # print(queue_title, queue_slug, num_short, num_exact, units)

        counts[queue_slug] = num_exact

    counts_json = json.dumps(counts)

    return counts_json

def get_review_queues_current_status(user=None):
    """
    Which queues have questions/answers/posts/edits available for review?

    https://stackoverflow.com/review
    """

    # only include queues accessible at this user's reputation level
    user_reputation = user.reputation
    queues = get_queues()
    if user is not None:
        queues = (x for x in queues if x.reputation <= user_reputation)

    counts = cache.get_or_update('status', fetch_counts,
                                 ttl=conf.CACHE_TTL_QUEUE_STATUS)
    counts = json.loads(counts)

    queue_counts = OrderedDict([
        (queue, counts.get(queue.slug, 0)) for queue in queues])
    return queue_counts


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

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='Location',
            fields=[
                ('id', models.AutoField(serialize=False, auto_created=True, primary_key=True, verbose_name='ID')),
                ('name', models.CharField(max_length=200)),
                ('canonical_name', models.CharField(max_length=200)),
                ('target_type', models.IntegerField(choices=[(1, 'Region'), (2, 'City')], default=1)),
                ('region_code', models.IntegerField(choices=[(1, 'Amazonas'), (2, 'Ancash'), (3, 'Apurimac'), (4, 'Arequipa')], default=4)),
                ('latitude', models.FloatField()),
                ('longitude', models.FloatField()),
                ('parent', models.ForeignKey(blank=True, null=True, to='timeseries.Location')),
            ],
        ),
        migrations.CreateModel(
            name='MonthAggregationData',
            fields=[
                ('id', models.AutoField(serialize=False, auto_created=True, primary_key=True, verbose_name='ID')),
                ('year', models.IntegerField(choices=[(1980, 1980), (1981, 1981), (1982, 1982), (1983, 1983), (1984, 1984), (1985, 1985), (1986, 1986), (1987, 1987), (1988, 1988), (1989, 1989), (1990, 1990), (1991, 1991), (1992, 1992), (1993, 1993), (1994, 1994), (1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015)])),
                ('month', models.IntegerField(choices=[(1, 'January'), (2, 'February'), (3, 'March'), (4, 'April'), (5, 'May'), (6, 'June'), (7, 'July'), (8, 'August'), (9, 'September'), (10, 'October'), (11, 'November'), (12, 'December')])),
                ('event_type', models.IntegerField(choices=[(1, 'Violent crime'), (2, 'Murder'), (3, 'Forcible rape'), (4, 'Robbery'), (5, 'Aggravated assault'), (6, 'Property crime'), (7, 'Burglary'), (8, 'Larcent theft'), (9, 'Motor vehicle theft'), (10, 'Arson')])),
                ('events', models.IntegerField()),
                ('location', models.ForeignKey(to='timeseries.Location')),
            ],
        ),
    ]


import cv2
import numpy as np
import imutils

image = cv2.imread('../test2.png')

def getTransformation(box, cntr):
    """[summary]

    Parameters
    ----------
    box : [type]
        [description]
    cntr : [type]
        [description]

    Returns
    -------
    [type]
        [description]
    """

    width = int(cntr[1][0])
    height = int(cntr[1][1])

    src_pts = box.astype("int")
    # coordinate of the points in box points after the rectangle has been
    # straightened
    dst_pts = np.array([[0, height - 1],
                        [0, 0],
                        [width - 1, 0],
                        [width - 1, height - 1]], dtype="int")

    # the perspective transformation matrix
    M = cv2.getPerspectiveTransform(src_pts, dst_pts)

    return M

def findImages(image):
    """
    """

    # Images
    imgList = []

    # Convert to grayscale
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # Blur image (Low Pass Filter)
    gray = cv2.GaussianBlur(gray, (5, 5), 0)

    ret, th = cv2.threshold(gray,210,235,1)

    # Edge Detection
    edged = cv2.Canny(th, 25, 200)

    contours, hierarchy = cv2.findContours(edged.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

    # Sort contours by size
    contours = sorted(contours, key = cv2.contourArea, reverse = True)

    for c in contours:
        # Get area of box
        box = cv2.minAreaRect(c)
        box = cv2.cv.BoxPoints(box) if imutils.is_cv2() else cv2.boxPoints(box)
        box = np.array(box, dtype="int")

        Area = image.shape[0]*image.shape[1]
        if Area/10 < cv2.contourArea(box) < Area*2/3:
            cv2.drawContours(image, [box], -1, (0, 255, 0), 2)

            #mtrx = getTransformation(box, c)
            #warped = cv2.warpPerspective(image, mtrx, int(c[1][0]), int(c[1][1]))
            #imgList.append(warped)

    return image

foundImages = findImages(image.copy())
cv2.imshow("Images", foundImages)

cv2.imwrite("markedImg.png", foundImages)
cv2.waitKey(0)


import pygame
import Config
import math

class Menu:
    def __init__(self, children={}, root=None):
        self.children = children
        self.root = root

class Hud:
    def __init__(self, dimensions):
        self.width, self.height = dimensions
        self.fontName = pygame.font.Font(Config.pathHudFont, Config.hudNameFontSize)
        self.fontStatBar = pygame.font.Font(Config.pathHudFont, Config.hudStatBarFontSize)
        self.menu = None
        self.selectedPlayerA = None
        self.selectedPlayerB = None
        self.helpText = None

    def render(self, surface):
        if self.selectedPlayerA:
            self.renderPlayerPanel(surface, Config.hudSelectionPosA, Config.hudSelectionSize, self.selectedPlayerA)
        if self.selectedPlayerB:
            self.renderPlayerPanel(surface, Config.hudSelectionPosB, Config.hudSelectionSize, self.selectedPlayerB)
    def renderPlayerPanel(self, surface, offset, dimensions, player):
        nameRender = self.fontName.render(player.name, True, Config.hudFontColor)
        nameBoxHeight = nameRender.get_height()+Config.hudNamePadding*2
        nameRect = (offset[0], offset[1], nameRender.get_width()+Config.hudNamePadding*2, nameBoxHeight)
        drawRoundedRect(surface, Config.hudBgColor, nameRect, Config.hudNamePadding, 0)
        surface.blit(nameRender, (offset[0]+Config.hudNamePadding, offset[1]+Config.hudNamePadding))

        statBarOffset = (offset[0], offset[1]+nameRect[3], dimensions[0], Config.hudNameFontSize+Config.hudStatBarPadding*2)
        current, maximum = player.stat['Hp'], player.stat['MaxHp']
        statBarText = "%s: %d/%d" % ("HP", current, maximum)
        self.renderPlayerStatBar(surface, Config.hudStatBarColorA, statBarOffset, Config.hudStatBarSize, statBarText, current, maximum)
    def renderPlayerStatBar(self, surface, color, offset, dimensions, text, current, maximum):
        statNameRender = self.fontStatBar.render(text, True, Config.hudFontColor)
        drawRoundedRect(surface, Config.hudBgColor, (offset[0], offset[1], dimensions[0]+Config.hudStatBarPadding*2, dimensions[1]+Config.hudStatBarPadding*2), Config.hudStatBarPadding, 0)

        fullBarRect = [offset[0]+Config.hudStatBarPadding, offset[1]+Config.hudStatBarPadding, dimensions[0], dimensions[1]]
        if current > 0:
            if current > maximum:
                ratio = 1
            else:
                ratio = current/(0.0+maximum)
            fgBarRect = fullBarRect
            fgBarRect[2] = dimensions[0] * ratio
            pygame.draw.rect(surface, color, fgBarRect, 0)
        if current < maximum:
            r,g,b = color
            pygame.draw.rect(surface, (r/2,g/2,b/2, 178), fullBarRect, 0)

def drawRoundedRect(surface, color, rect, radius, width=0):
    x, y, w, h = rect
    assert w >= radius*2 and h >= radius*2
    for p in [(x+radius, y+radius), (x+w-radius, y+radius), (x+radius, y+h-radius), (x+w-radius, y+h-radius)]:
        pygame.draw.circle(surface, color, p, radius, width)
    pygame.draw.rect(surface, color, (x+radius, y, w-radius*2, h), width)
    pygame.draw.rect(surface, color, (x, y+radius, w, h-radius*2), width)

def main():
    pass

if __name__ == '__main__':
    main()


# coding: utf-8
import httplib
import logging
import json
from Hue import Hue
import time
import sys

class HueFactory:
    __connect = None
    __user = None
    __nbhue = None

    # construct object and detect hue bridge
    def __init__(self):
        request = httplib.HTTPSConnection("www.meethue.com")
        request.request("GET", "/api/nupnp")
        response = request.getresponse()
        data = json.loads(response.read())

        if response.status == 200 and 'internalipaddress' in data[0]:
            logging.log(logging.INFO, 'POST upnp 200')
            self.__connect = data[0]['internalipaddress']
        else:
            logging.log(logging.INFO, 'POST upnp ' + str(response.status))
            self.__connect = "error"

        request.close()

    # generate hue objects
    def generate(self):
        observers = []
        i = 1
        while i <= self.__nbhue:
            hue = Hue(self.__connect, i, self.__user)
            observers.append(hue)
            i += 1

        return observers

    # get user for use api of hue bridge
    def get_user(self):
        status = 0
        x = 0
        while status != 1 and x < 5:
            request = httplib.HTTPConnection(self.__connect)
            request.request("POST", "/api", '{"devicetype":"rasp_brightness_sensor"}')
            response = request.getresponse()
            data = json.loads(response.read())
            if 'success' in data[0] and response.status == 200:
                logging.log(logging.INFO, 'POST get_user 200')
                self.__user = data[0]['success']['username']
                status = 1
            else:
                logging.log(logging.INFO, 'POST get_user ' + str(response.status))
                sys.stdout.write(data[0]['error']['description'])
                time.sleep(2)

            x += 1
            request.close()

        return status

    # get number of hue light on this bridge
    def get_lights(self):
        request = httplib.HTTPConnection(self.__connect)
        request.request("GET", "/api/" + self.__user + "/lights")
        response = request.getresponse()
        status = 0
        data = json.loads(response.read())

        if response.status == 200 and 'error' not in data:
            logging.log(logging.INFO, 'GET get_lights 200')
            self.__nbhue = len(data)
            status = 1
        else:
            logging.log(logging.INFO, 'GET get_lights ' + str(response.status))

        request.close()
        return status

    # get current connect string
    # return "error" if connection is impossible
    def get_connect(self):
        return self.__connect


import cv2, time, pyautogui
import numpy as np, HandTracking_module as htm

cap = cv2.VideoCapture(0)
wCam, hCam = 1280, 720
frameR = 150
smoothening = 1

pTime = 0
plocX, plocY = 0, 0
clocX, clocY = 0, 0

cap.set(3, wCam)
cap.set(4, hCam)
detector = htm.HandDetector(maxHands=1)
wScr, hScr = pyautogui.size()
# print(wScr, hScr)

while True:
    success, img = cap.read()
    img = cv2.flip(img, 1)
    img = detector.findHands(img)
    lmList, bbox = detector.findPos(img)
    cv2.rectangle(
        img, (frameR, frameR), (wCam - frameR, hCam - frameR), (255, 0, 255), 2
    )

    if len(lmList) != 0:
        x1, y1 = lmList[8][1:]
        x2, y2 = lmList[12][1:]
        fingers = detector.fingersUp()

        # print(fingers)
        x3 = np.interp(x1, (frameR, wCam - frameR), (0, wScr))
        y3 = np.interp(y1, (frameR, hCam - frameR), (0, hScr))
        clocX = plocX + (x3 - plocX) / smoothening
        clocY = plocY + (y3 - plocY) / smoothening

        # fingers[1] = Index finger (the mouse)
        if (
            fingers[1] == 1
            and fingers[0] == 0
            and fingers[2] == 0
            and fingers[3] == 0
            and fingers[4] == 0
        ):
            pyautogui.moveTo(clocX, clocY)
            cv2.circle(img, (x1, y1), 15, (255, 0, 255), cv2.FILLED)
            plocX, plocY = clocX, clocY

        # fingers[2] = Middle finger (index + middle = left click)
        elif (
            fingers[1] == 1
            and fingers[2] == 1
            and fingers[0] == 0
            and fingers[3] == 0
            and fingers[4] == 0
        ):
            length, img, lineInfo = detector.findDistance(8, 12, img)
            # print(length)
            if length < 80:
                cv2.circle(img, (lineInfo[4], lineInfo[5]), 15, (0, 255, 0), cv2.FILLED)
                pyautogui.leftClick()

        # fingers[4] = Pinky finger (index + pinky = right click)
        elif (
            fingers[4] == 1
            and fingers[1] == 1
            and fingers[0] == 0
            and fingers[2] == 0
            and fingers[3] == 0
        ):
            length, img, lineInfo = detector.findDistance(8, 20, img)
            if length < 90:
                cv2.circle(img, (lineInfo[4], lineInfo[5]), 15, (0, 255, 0), cv2.FILLED)
                pyautogui.rightClick()

    # cTime = time.time()
    # fps = 1/(cTime-pTime)
    # pTime = cTime
    # cv2.putText(img, str(int(fps)), (10,50), cv2.FONT_HERSHEY_PLAIN, 2, (255,0,0), 2)
    cv2.imshow("Image", img)
    cv2.waitKey(1)

# widthScr, heightScr = pyautogui.size() # Returns two integers, the width and height of the screen. (The primary monitor, in multi-monitor setups.)
# x2, x3 = pyautogui.position() # Returns two integers, the x and y of the mouse cursor's current position.
# pyautogui.moveTo(100, 150) # Move the mouse to the x, y coordinates 100, 150.
# pyautogui.click() # Click the mouse at its current location.
# pyautogui.click(200, 220) # Click the mouse at the x, y coordinates 200, 220.
# pyautogui.move(None, 10)  # Move mouse 10 pixels down, that is, move the mouse relative to its current position.
# pyautogui.doubleClick() # Double click the mouse at the
# pyautogui.moveTo(500, 500, duration=2, tween=#pyautogui.easeInOutQuad) # Use tweening/easing function to move mouse over 2 seconds.
# pyautogui.write('Hello world!', interval=0.25)  # Type with quarter-second pause in between each key.
# pyautogui.press('esc') # Simulate pressing the Escape key.
# pyautogui.keyDown('shift')
# pyautogui.write(['left', 'left', 'left', 'left', 'left', 'left'])
# pyautogui.keyUp('shift')
# pyautogui.hotkey('ctrl', 'c')


# -*- coding: utf-8 -*-
import scrapy
import re

from pydispatch import dispatcher
from scrapy import signals
from scrapy.http import Request
from urllib import parse

from items import XiaojianrenItemLoader, xunyingItem
from utils.common import get_md5

class XunyingSpider(scrapy.Spider):
    name = 'xunying'
    allowed_domains = ['www.xunyingwang.com']
    start_urls = ['http://www.xunyingwang.com/movie/']

    def parse(self, response):
        post_nodes = response.css("body > div:nth-child(3) > div.row > div.col-xs-12 > div > div")
        for post_node in post_nodes:
            image_url = post_node.css("a img::attr(data-original)").extract_first("")
            post_url = post_node.css("a::attr(href)").extract_first("")
            tags = post_node.css(".otherinfo a::text").extract()
            yield Request(url=parse.urljoin(response.url, post_url), meta={"front_image_url": image_url,"tags":tags},
                          callback=self.parse_detail)  # response获取meta
        # 提取下一页并交给scrapy进行下载
        next_url = response.xpath("//a[contains(@rel, 'next')]").css("::attr(href)").extract_first("")
        if next_url:
            print(next_url)
            yield Request(url=parse.urljoin(response.url, next_url), callback=self.parse)

    def parse_detail(self, response):
        if response.url == 'http://www.xunyingwang.com/movie/':
            print("------------------url为www.xunyingwang.com/movie------------------")
            return None
        movie_item = XiaojianrenItemLoader()  # 实例化
        # 通过item loader加载item
        front_image_url = response.meta.get("front_image_url", "")  # 文章封面图
        tags = response.meta.get("tags", "")
        item_loader = XiaojianrenItemLoader(item=xunyingItem(), response=response)  # 默认ItemLoader是一个list，自定义TakeFirst()
        item_loader.add_css("title", ".movie-info h1::text")
        item_loader.add_value("url", response.url)
        item_loader.add_value("url_object_id", get_md5(response.url))
        item_loader.add_xpath("create_date", '/html/body/div[2]/div/div/div[1]/div[1]/div[2]/table/tbody/tr[7]/td[2]')
        item_loader.add_value("front_image_url", front_image_url)
        item_loader.add_value("tags", ','.join(str(n) for n in tags))
        item_loader.add_xpath("duration", '/html/body/div[2]/div/div/div[1]/div[1]/div[2]/table/tbody/tr[8]/td[2]/text()')
        item_loader.add_css("score", '.score::text')
        item_loader.add_xpath("description", '/html/body/div[2]/div/div/div[1]/div[2]/div[2]/p/text()')

        movie_item = item_loader.load_item()

        yield movie_item  # 将传到piplines中


import os
from telegram import Update
from telegram.ext import Updater, CommandHandler, CallbackContext, MessageHandler

# https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/conversationbot.py

def hello(update: Update, context: CallbackContext) -> None:
    update.message.reply_text(f'Hello {update.effective_user.first_name}')

def add(update: Update, context: CallbackContext) -> None:
    user_message = update.message.text # /add 4 5
    cmd, n1, n2 = user_message.split(" ")
    result = float(n1) + float(n2)
    update.message.reply_text(f'{n1} + {n2} = {result}')

def mean(update: Update, context: CallbackContext) -> None:
    user_message = update.message.text # /mean 4 5 6 7 8
    parameters = user_message.split(" ") # ['/mean', '4', '5', '6', '7', '8']
    n_list = parameters[1:] # ['4', '5', '6', '7', '8']
    total = 0
    for n in n_list:
        total = total + float(n)
    result = total/len(n_list)
    update.message.reply_text(f'average of {n_list} = {result}')

updater = Updater(os.getenv('TELEGRAM_TOKEN'))
updater.dispatcher.add_handler(CommandHandler('hello', hello))
updater.dispatcher.add_handler(CommandHandler('add', add))
updater.dispatcher.add_handler(CommandHandler('mean', mean))

updater.start_polling()
updater.idle()