import numpy as np
import cv2
from skimage import measure, morphology

from matplotlib.patches import Rectangle

class ImageFilters():

    def smooth(mat_image, filter_size):

        # Get image type and check is an accepted type by the gaussian blur function
        img_type = mat_image.dtype
        types_allowed = ['int8', 'int16', 'float32']

        if img_type not in types_allowed:
            if img_type in ['int8', 'int16']:
                mat_image = np.int16(mat_image)
            # Force 32bit and 64 bit types to be float 32
            else:
                mat_image = np.float32(mat_image)

        # Check if current image has all channels, and smooth all of them
        if mat_image.ndim > 2: n_cycles = mat_image.shape[2]
        else: n_cycles = 1

        # Initialise img_blur with the same shape as mat_image
        img_blur = np.zeros(mat_image.shape)

        # Loop over all the image channels
        for i_channel in range(n_cycles):
            try:
                ch_image = mat_image[:,:,i_channel]
                # Use sigma blurring to smooth the image
                img_blur[:,:,i_channel] = cv2.GaussianBlur(ch_image, (filter_size, filter_size), 0)
            except IndexError:
                img_blur = cv2.GaussianBlur(mat_image, (filter_size, filter_size), 0)

        return img_blur

    def enhance(mat_image, filter_size):

        # Use large sigma blurring to smooth the image to substract
        img_substract = ImageFilters.smooth(mat_image, filter_size)

        # Create denoised image by substraction
        img_enhanced = mat_image - img_substract
        # Set negative values to zero
        img_enhanced[img_enhanced < 0 ] = 0

        return img_enhanced

    def check_filtersize(filter_size):

        # If filter size is not odd, update to first higher odd number
        if (filter_size % 2 == 0) & (filter_size != 0):
            filter_size +=1
            print('Filter size has to be an odd number. Filter size has been changed to next odd number.')

        return filter_size

    def wavelet2d_firstdet(mat_image, a_scale):

        """
        Funtion to compute the 2D Wavelet Transform using the first derivative
        of a gaussian as a mother wavelet

        INPUT:
            a_scale: float, scale or dilation for the gaussian envelop,
                        it works better when it's a multiple of 2
            mat_image: numpy array, image to be transformed
        OUTPUT:
            WT_mod: numpy array, modulus of the WT, same size as the input image
            WT_arg: numpy array, argument of the WT in degrees

        """
        # Construct x and y vectors, with zero at the middle
        x = np.arange(-mat_image.shape[1]/2, mat_image.shape[1]/2)
        y = np.arange(-mat_image.shape[0]/2, mat_image.shape[0]/2)
        # Construct the matrix as a stack of vectors
        xg = np.tile(x, (len(y), 1))
        yg = np.tile(y, (len(x), 1)).transpose()

        # Compute the 2D FFT of the image, shifted
        fft_img = np.fft.fftshift(np.fft.fft2(mat_image))

        # Define the gaussian function in real space.
        # Note that x*x is better than x**2
        phi = np.exp(-((xg/a_scale)*(xg/a_scale)+(yg/a_scale)*(yg/a_scale))/2)
        # Define the first derivative in x and in y
        phi_x = -(xg/a_scale)*phi
        phi_y = -(yg/a_scale)*phi
        # Normalise according to the scale
        phi_xg = 1/(a_scale**2)*phi_x
        phi_yg = 1/(a_scale**2)*phi_y
        # Compute the 2D FFT, shifted
        fft_phi_x = np.fft.fftshift(np.fft.fft2(phi_xg))
        fft_phi_y = np.fft.fftshift(np.fft.fft2(phi_yg))
        # Compute the gradient in x and in y, and inverse the FFT
        WT_x = np.fft.ifftshift(np.fft.ifft2(fft_phi_x*fft_img))
        WT_y = np.fft.ifftshift(np.fft.ifft2(fft_phi_y*fft_img))
        # Compute the modulus (not normalised) and the argument in degrees
        WT_mod = np.sqrt(np.abs(WT_x)**2 + np.abs(WT_y)**2)
        WT_arg = np.angle(WT_x + 1j*WT_y, deg = True)

        return WT_mod, WT_arg

class ImageMask():

    def threshold(mat_image, threshold):

        # Take the median of all pixels higher than zero
        median_positive = np.median(mat_image[mat_image>0].flatten())

        # Calculate threshold intensity.
        # threshold is based on the median of all positive pixel values
        intensity_th = np.float(threshold)*median_positive

        # Threshold the image as uint8
        img_th = (mat_image > intensity_th).astype('uint8')

        return img_th

    def floodfill(image_th, min_size, method = 'outside'):

        # Minimum area to discard objects, input is size
        min_area = min_size**2

        # Get seedpoint for floodfilling. The seed should be localted in outer aqueous phase, and not
        # within vesicle. Take 10 seedpoints along the x-direction to find which one gives the most flooded pixels
        h, w = image_th.shape[:2]

        if method == 'outside':
            seed_xs = np.linspace(2, w, 10).astype(int)
            seed_y = 0
            value_infill = 0
        else:
            seed_xs = np.linspace(h/2-5, h/2 + 5, 10).astype(int)
            seed_y = int(w/2)
            value_infill = 255

        # Initialise iteration
        pixels_flooded_current = 0
        seed_point_current = (0,0)

        # For each seed point, track number of pixels that is flooded
        for seed_x in seed_xs:
            seed_point = (seed_x-1,seed_y)
            # Flood the image with the current seedpoint
            flooded_img = ImageMask.flood(image_th, seed_point)
            # Count number of flooded pixels
            pixels_flooded_next = np.sum((flooded_img>0).astype(int))

            # If number of flooded pixels has increased, keep the seedpoint
            if pixels_flooded_next > pixels_flooded_current:
                seed_point_current = seed_point
                pixels_flooded_current = pixels_flooded_next

        # First floodfilling to find the vesicle contour
        flooded_outer = ImageMask.flood(image_th, seed_point_current)
        # For flooding the exerior: Interior: 0, membranes: 1, exterior: 255
        # For flooding the interior: Interior: 255, membranes: 1, exterior: 0
        # Only keep the inner area: remove membrane and exterior
        inner_holes = (flooded_outer == value_infill).astype(int)
        # Second floodfilling to fill the holes
        flooded_outer_rep = inner_holes.copy().astype('uint8')
        flooded_outer_rep = ImageMask.flood(flooded_outer_rep, seed_point_current)
        # Non-flooded pixels are vesicle lumen
        if method == 'outside':
            inner = (flooded_outer_rep < 255).astype(int)
        else:
            inner = (flooded_outer_rep == 255).astype(int)
        inner = inner.astype('uint8')

        # Connect points and label them
        img_label = measure.label(inner, background = 0)
        img_label = morphology.remove_small_objects(img_label, min_size = min_area, connectivity = 1)

        # Relabel the vesicles
        mask_labels = 0*img_label
        new_id = 0
        # Relabel the vesicles
        for ves_label in np.unique(img_label.flatten())[1:]:
            new_id += 1
            mask_labels[img_label == ves_label] = new_id

        return mask_labels

    def flood(image_th, seed_point):

        # Copy the image to prevent cv2 of destroying it
        image_fill = image_th.copy()
        # Get shape of image
        h, w = image_fill.shape

        # Create empty mask that is one pixel wider on each side
        mask = np.zeros((h+2, w+2), np.uint8)

        # Create flooded image
        _, flooded_img, _, _ = cv2.floodFill(image_fill, mask, seed_point, 255)

        return flooded_img

    def wt_edges(WT_mod, WT_arg):

        """
        Function to implement the edge detection based on a modified
        canny detector with the WT
        Note that no threshold is used with this version
        INPUT:
            WT_mod: numpy array, WT modulus, same size as image
            WT_arg: numpy array, WT argument in degrees
        OUTPUT
            mask_edge: numpy array, binary mask with the detected edged
                        same size as image
        """

        # Discretise the argument to follow the directions
        # where we can look for the gradient
        rWT_arg = 45.*np.round(WT_arg/45.)
        # Define matrices with each direction to look for the
        # maxima with matrix operations instead of loops
        dir_sa=[0.,45.,90.,135.,-180.,-135.,-90.,-45.]
        # Initialise direction matrix
        WT_mod_0=np.zeros(WT_mod.shape)
        WT_mod_45=np.zeros(WT_mod.shape)
        WT_mod_90=np.zeros(WT_mod.shape)
        WT_mod_135=np.zeros(WT_mod.shape)
        WT_mod_m180=np.zeros(WT_mod.shape)
        WT_mod_m135=np.zeros(WT_mod.shape)
        WT_mod_m90=np.zeros(WT_mod.shape)
        WT_mod_m45=np.zeros(WT_mod.shape)
        # Get the values from the WT modulus
        WT_mod_0[:,:-1]=WT_mod[:,1:]
        WT_mod_m180[:,1:]=WT_mod[:,: -1]
        WT_mod_90[:-1,:]=WT_mod[1:,:]
        WT_mod_m90[1:,:]=WT_mod[:-1,:]
        WT_mod_45[:-1,:-1]=WT_mod[1:,1:]
        WT_mod_m135[1:,1:]=WT_mod[:-1,:-1]
        WT_mod_135[:-1,1:]=WT_mod[1:,:-1]
        WT_mod_m45[1:,:-1]=WT_mod[:-1,1:]

        # Construct the matrices to compare with the pixel i+1
        # and with the pixel i-1
        WT_mod_ap=[WT_mod_0,WT_mod_45,
                    WT_mod_90,WT_mod_135,
                    WT_mod_m180,WT_mod_m135,
                    WT_mod_m90,WT_mod_m45]
        WT_mod_am=[WT_mod_m180,WT_mod_m135,
                    WT_mod_m90,WT_mod_m45,
                    WT_mod_0,WT_mod_45,
                    WT_mod_90,WT_mod_135]

        # Initialize matrix for the edge mask
        mask_edge=np.zeros(WT_mod.shape)
        # Loop through each direction and compare the corresponding matrices
        # keeping the maxima
        for idir in range(len(dir_sa)):
            mask_angle=rWT_arg==dir_sa[idir]
            mask_edge[mask_angle*np.greater(WT_mod,WT_mod_ap[idir])*np.greater(WT_mod,WT_mod_am[idir])]=1

        return mask_edge

    def chain_search(mask_WTarg, search_mat):

        # Get search parameters
        search_length, search_width = search_mat

        # Get the points where the mask is not zero
        ye, xe = np.where(mask_WTarg)

        # Create a new matrix to store the labeled points
        mask_label = np.zeros_like(mask_WTarg)

        # Get the search limits
        search_limit = int(np.floor(search_length/2))
        xmax = mask_WTarg.shape[0] - search_limit
        ymax = mask_WTarg.shape[1] - search_limit

        # Create array of points that fall within the search limits
        pointsp = [[x,y] for x,y in zip(xe, ye) if (x > search_limit) and (y > search_limit)]
        pointsp = [[x,y] for x,y in pointsp if (x < xmax) and (y < ymax)]
        # Assign label to points in matrix
        for idc, point in enumerate(pointsp, start = 1):
            mask_label[point[1], point[0]] = idc

        # Search algorithm, it runs only two times
        for _ in range(2):
            for point in pointsp:
                xc, yc = point[0], point[1]
                if mask_WTarg[yc, xc] <= 90:
                    search_angle = mask_WTarg[yc, xc] + 90
                else:
                    search_angle = mask_WTarg[yc, xc] - 90

                r1 = Rectangle((xc, yc), search_limit, search_width, angle=search_angle)
                r2 = Rectangle((xc, yc), search_limit, -search_width, angle=search_angle)
                r3 = Rectangle((xc, yc), -search_limit, search_width, angle=search_angle)
                r4 = Rectangle((xc, yc), -search_limit, -search_width, angle=search_angle)

                xs1 = xc - search_limit
                xs2 = xc + search_limit
                ys1 = yc - search_limit
                ys2 = yc + search_limit

                pointsp_search = [[x,y] for x,y in pointsp if (xs1 <= x <= xs2) and (ys1 <= y <= ys2)]

                # Check if points are contained within the rectangle
                found_pix = []
                for rect in [r1,r2,r3,r4]:
                    match_points = rect.contains_points(pointsp_search)
                    found_pix.extend(np.array(pointsp_search)[match_points])

                xp = [x for x,y in found_pix]
                yp = [y for x,y in found_pix]

                try:
                    id_1 = np.min(mask_label[yp, xp].flatten())
                except ValueError:
                    pass
                else:
                    mask_label[yp, xp] = id_1

        for idc, id_label in enumerate(np.unique(mask_label.flatten())):
            mask_label[mask_label == id_label] = idc

        length_chain = []
        id_chain_all = np.unique(mask_label.flatten())
        id_chain_all = id_chain_all[id_chain_all != 0]
        for id_chain in id_chain_all:
            length_chain.append(len(np.where(mask_label==id_chain)[0]))

        ind_sort = np.argsort(length_chain)
        try: yo, xo = np.where(mask_label == id_chain_all[ind_sort][-1])
        except IndexError: yo = [0]; xo = [0]
        try: yi, xi = np.where(mask_label == id_chain_all[ind_sort][-2])
        except IndexError: xi = [0]; yi = [0]

        ri = np.stack((xi, yi), axis = 1)
        ro = np.stack((xo, yo), axis = 1)

        return ri, ro

class ImageCorrection():

    def substract_background(input_image, corr_type, inplace = True):

        # Correct input image according to the method in 'corr_type'
        if 'mean' in corr_type:
            bg_int = np.mean(input_image)
        elif corr_type == 'ROI corner':
            bg_ul = np.mean(input_image[:3,:3])
            bg_ur = np.mean(input_image[:3, -3:])
            bg_ll = np.mean(input_image[-3:, :3])
            bg_lr = np.mean(input_image[-3:, -3:])
            bg_int = np.mean([bg_ul, bg_ur, bg_ll, bg_lr])
        elif corr_type == 'ROI center':
            sy = input_image.shape[0]
            sx = input_image.shape[1]
            bg_int = np.mean(input_image[int(sy/2) - 1: int(sy/2) + 2, int(sx/2) - 1: int(sx/2) + 2])

        if inplace is True:
            input_image -= bg_int.astype(input_image.dtype)
            return input_image
        elif inplace is False:
            return bg_int

class ImageCheck():

    def single_channel(current_image, current_channel):

        # Check the current channel selected, if it's multiple, force it to be the first channel
        if current_channel == 0:
            mat_image = 1*current_image[:,:,0]
            print('A single channel needs to be selected. Setting channel 1 as working channel')
        else:
            try:
                mat_image = 1*current_image[:,:,current_channel - 1]
            except IndexError:
                mat_image = 1*current_image

        return mat_image


import cv2
import numpy as np

points1 = np.empty((0,2), dtype=float)
points2 = np.empty((0,2), dtype=float)

def mouse_callback(event, x, y, flags, param):
    global points1
    global points2

    if event == cv2.EVENT_LBUTTONDBLCLK:
        print(x,y)
        (im, image_index) = param
        if image_index == 1:
            points1 = np.append(points1, [[x, y]], axis=0)
            cv2.circle(im, (x, y), 2, (0, 0, 255), -1)
        else:
            points2 = np.append(points2, [[x, y]], axis=0)
            cv2.circle(im2, (x, y), 2, (0, 0, 255), -1)

    print(points1)
    print(points2)

def homo(pts_src, pts_dst, im):
    h, status = cv2.findHomography(pts_src, pts_dst)
    print(h)
    print(status)
    return cv2.warpPerspective(im, h, (im.shape[1], im.shape[0]))

im1 = np.zeros((400, 400, 3), np.uint8)
im2 = np.zeros((400, 400, 3), np.uint8)
im3 = np.zeros((400, 400, 3), np.uint8)

cv2.circle(im1, (200, 200), 100, (255, 0, 0), -1)

im1 = cv2.imread("im.png")
im2 = cv2.imread("im2.png")

cv2.namedWindow("Display1", cv2.CV_WINDOW_AUTOSIZE)
cv2.namedWindow("Display2", cv2.CV_WINDOW_AUTOSIZE)
cv2.namedWindow("Display3", cv2.CV_WINDOW_AUTOSIZE)

cv2.setMouseCallback("Display1", mouse_callback, (im1, 1))
cv2.setMouseCallback("Display2", mouse_callback, (im2, 2))

while(True):
    cv2.imshow("Display1", im1)
    cv2.imshow("Display2", im2)
    cv2.imshow("Display3", im3)

    if cv2.waitKey(15)%0x100 == ord('a'):
        im3 = homo(points1, points2, im)

    #ord(scape) = 27
    if cv2.waitKey(15)%0x100==27:
        break

cv2.destroyWindow("Display1")
cv2.destroyWindow("Display2")
cv2.destroyWindow("Display3")


from python_http_client.exceptions import HTTPError

import sendgrid

from accounts.models import User, Reset
from server.settings import get_secret

sg = sendgrid.SendGridAPIClient(get_secret('SEND_GRID_KEY'))

class Emailer():
    def __init__(self):
        pass

    def email_reset_link(self, user: User, reset: Reset):
        link = 'https://chatengine.io/reset/{}'.format(str(reset.uuid)) \
            if get_secret('PIPELINE') == 'production' else \
            'http://localhost:3000/reset/{}'.format(str(reset.uuid))

        data = {
            "personalizations": [
                {
                    "to": [{"email": user.email}],
                    "subject": "Reset Password | Chat Engine",
                    "substitutions": {
                        "-link-": link
                    }
                }
            ],
            "from": {"email": 'no_reply@chatengine.io'},
            "template_id": "02e2e343-03b3-4bee-a6b1-3e7527a3b207"
        }

        try:
            sg.client.mail.send.post(request_body=data)
            return True

        except HTTPError:
            return False

    def email_demo_requested(self, email: str, company: str, userbase: str, goals: str):
        data = {
            "personalizations": [
                {
                    "to": [{"email": email}, {"email": 'adam@lamorre.co'}],
                    "subject": "Demo Requested | Chat Engine",
                    "substitutions": {
                        "-email-": email,
                        "-company-": company,
                        "-userbase-": userbase,
                        "-goals-": goals,
                    }
                }
            ],
            "from": {"email": 'no_reply@chatengine.io'},
            "template_id": "67689bef-d9eb-4a7e-a53d-548bb4fb61e5"
        }

        try:
            sg.client.mail.send.post(request_body=data)
            return True

        except HTTPError:
            return False


import unittest
import random

from mock import Mock

import game
import game_views
import game_data
import game_common

class GameObjectTest(unittest.TestCase) :

    def setUp(self) :
        self.data = Mock(spec=game_data.GameData)
        self.state = Mock()
        self.dice_check = Mock(spec=game.check_bids)
        self.win_check = Mock(spec=game.get_winner)
        self.win_hand = Mock(spec=game.on_win)
        self.bid_reset = Mock(spec=game.bid_reset)
        self.reshuffle_dice = Mock(spec=game.reshuffle_dice)
        self.subject = game.Game(self.data, self.win_hand, self.dice_check,
        self.win_check, self.bid_reset, self.reshuffle_dice)

    def testDeactivatePlayer(self) :
        player1 = "player"
        self.subject.deactivate_player(player1)
        self.data.mark_inactive.assert_called_with(player1)

    def testSettingAPlayer(self) :
        player1 = "player"
        self.subject.set_current_player(player1)
        self.data.set_current_player.assert_called_with(player1)

    def testCheckingForFinished(self) :
        player1 = "player"
        dice_map = dict()
        self.win_check.return_value = player1
        self.data.get_dice_map.return_value = dice_map
        ret = self.subject.finished()
        self.assertTrue(ret is not None)
        self.assertTrue(ret)
        self.data.get_dice_map.assert_called_with()
        self.win_check.assert_called_with(dice_map)

    def testCheckingForActive(self) :
        player1 = "player"
        self.data.is_active.return_value = True

        self.assertTrue(self.subject.is_player_active(player1))

        self.data.is_active.assert_Called_with(player1)
        self.data.is_active.return_value = False

        self.assertTrue(not self.subject.is_player_active(player1))

    def testCheckingForFinishedNegative(self) :
        self.win_check.return_value = None
        dice_map = dict()
        self.data.get_dice_map.return_value = dice_map
        ret = self.subject.finished()
        self.assertTrue(ret is not None)
        self.assertTrue(not ret)
        self.data.get_dice_map.assert_called_with()
        self.win_check.assert_called_with(dice_map)

    def testStartupStateOfGameObject(self) :
        self.data.get_current_player.return_value = None
        self.assertTrue(self.subject.get_current_player() is None)
        self.data.get_current_state.return_value = self.state
        self.assertTrue(self.subject.get_state() == self.state)
        self.data.get_current_state.assert_called_with()
        self.assertTrue(not self.state.on_game_start.called)
        self.assertTrue(not self.data.add_player.called)

    def testStartingAGame(self) :
        self.data.get_current_state.return_value = self.state
        self.subject.start_game()
        self.data.get_current_player.return_value = None
        self.assertTrue(self.subject.get_current_player() is None)
        self.state.on_game_start.assert_called_with()
        self.assertEquals(self.state, self.subject.get_state())

    def testSettingAState(self) :
        state1 = Mock()
        self.subject.set_state(state1)
        self.data.set_current_state.assert_called_with(state1)

    def testMakingABid(self) :
        player = "player"
        self.data.get_current_player.return_value = player
        self.data.get_current_state.return_value = self.state
        bid = (1, 2)
        self.subject.make_bid(bid)

        self.data.get_current_state.assert_called_with()
        self.data.get_current_player.assert_called_with()
        self.state.on_bid.assert_called_with(player, bid)
        self.assertTrue(not self.data.set_bid.called)
        self.assertEquals(self.state, self.subject.get_state())

    def testResettingBid(self) :
        players = ["player" for x in xrange(0, 3)]
        self.data.get_players.return_value = players

        self.subject.reset_bid()

        self.bid_reset.assert_called_with(players)

    def testGettingNumberOfDiceAPlayerHas(self) :
        player1 = "player"
        expected = 4
        self.data.get_number_of_dice.return_value = expected

        ret = self.subject.num_of_dice(player1)

        self.data.get_number_of_dice.assert_called_with(player1)
        self.assertEquals(expected, ret)

    def testMakingAChallengeWithNoneAndNoneGrabsFromGame(self) :
        player1 = "player"
        player2 = "player"
        self.data.get_players.return_value = [player1, player2]
        self.data.get_current_player.return_value = player2
        self.data.get_current_state.return_value = self.state

        self.subject.make_challenge()
        self.data.get_current_state.assert_called_with()
        self.data.get_players.assert_called_with()
        self.state.on_challenge.assert_called_with(player2, player1)
        self.assertEquals(self.state, self.subject.get_state())

    def testMakingAChallengeWithChallengedParametersDoesNotCall(self) :
        player1 = "player"
        player2 = "player"
        self.data.get_current_player.return_value = player2
        self.data.get_current_state.return_value = self.state

        self.subject.make_challenge(challenged=player1)
        self.data.get_current_state.assert_called_with()
        self.data.get_current_player.assert_called_with()
        self.assertTrue(not self.data.get_players.called)
        self.state.on_challenge.assert_called_with(player2, player1)
        self.assertEquals(self.state, self.subject.get_state())

    def testGettingNextPlayer(self) :
        players = ["player" for x in xrange(0, 5)]
        self.data.get_players.return_value = players
        self.data.get_current_player.return_value = players[0]

        ret = self.subject.get_next_player()

        self.assertTrue(ret is not None)
        self.assertEquals(players[1], ret)
        self.data.get_players.assert_called_with()
        self.data.get_current_player.assert_called_with()

    def testGettingNextPlayerOnLastPlayer(self) :
        players = ["player" for x in xrange(0, 5)]
        self.data.get_players.return_value = players
        self.data.get_current_player.return_value = players[4]

        ret = self.subject.get_next_player()

        self.assertTrue(ret is not None)
        self.assertEquals(players[0], ret)
        self.assertTrue(self.data.get_players.called)

    def testGettingPreviousPlayer(self) :
        players = ["player" for x in xrange(0, 5)]
        self.data.get_players.return_value = players
        self.data.get_current_player.return_value = players[4]

        ret = self.subject.get_previous_player()

        self.assertTrue(ret is not None)
        self.assertEquals(players[3], ret)
        self.assertTrue(self.data.get_players.called)

    def testGettingPreviousPlayerOnFirstPlayer(self) :
        players = ["player" for x in xrange(0, 5)]
        self.data.get_players.return_value = players
        self.data.get_current_player.return_value = players[0]

        ret = self.subject.get_previous_player()

        self.assertTrue(ret is not None)
        self.assertEquals(players[4], ret)
        self.assertTrue(self.data.get_players.called)

    def testGettingNextPlayerWithOnePlayer(self) :
        players = ["player"]
        self.data.get_players.return_value = players
        self.data.get_current_player.return_value = players[0]

        ret = self.subject.get_next_player()
        self.assertTrue(ret is not None)
        self.assertEquals(players[0], ret)
        self.assertTrue(self.data.get_players.called)

    def testGettingPreviousPlayerWithOnePlayer(self) :
        players = ["player"]
        self.data.get_players.return_value = players
        self.data.get_current_player.return_value = players[0]

        ret = self.subject.get_previous_player()

        self.assertTrue(ret is not None)
        self.assertEquals(players[0], ret)
        self.assertTrue(self.data.get_players.called)

    def testGettingPreviousBid(self) :
        players = ["player" for x in xrange(0, 2)]
        bid = (1, 2)
        self.data.get_players.return_value = players
        self.data.get_bid.return_value = bid
        self.data.get_current_player.return_value = players[1]

        ret = self.subject.get_previous_bid()
        self.assertTrue(ret is not None)
        self.assertEquals(bid, ret)
        self.data.get_bid.assert_called_with(players[0])

    def testBidChecking(self) :
        dice_dict = dict()
        exp = True
        self.data.get_dice_map.return_value = dice_dict
        self.dice_check.return_value = exp
        bid = (1, 2)
        ret = self.subject.true_bid(bid)
        self.assertTrue(ret is not None)
        self.assertTrue(exp == ret)
        self.assertTrue(self.data.get_dice_map.called)
        self.dice_check.assert_called_with(bid, dice_dict)

    def testRemovingDice(self) :
        length = 4
        ret_list = [1 for x in xrange(0, length)]
        player = "player"
        self.data.get_dice.return_value = ret_list
        self.subject.remove_dice(player)
        self.data.get_dice.assert_called_with(player)
        self.assertTrue(self.data.set_dice.called)
        self.assertEquals(length - 1, len(self.data.set_dice.call_args[0][1]))

    def testWinHandling(self) :
        player1 = "player"
        player2 = "player"
        cur_bid = (1, 2)
        self.subject.on_win(player1, player2, cur_bid)
        self.win_hand.assert_called_with(player1, player2, cur_bid)

    def testGettingWinningPlayer(self) :
        player1 = "player"
        ret_map = {player1:[1]}
        self.data.get_dice_map.return_value = ret_map
        self.win_check.return_value = player1
        ret = self.subject.get_winning_player()
        self.assertTrue(ret is not None)
        self.assertTrue(ret == player1)
        self.win_check.assert_called_with(ret_map)
        self.data.get_dice_map.assert_called_with()

    def testActivatingAllPlayers(self) :
        self.subject.activate_players()
        self.data.make_all_active.assert_called_with()

    def testGettingDiceMap(self) :
        player1 = "player"
        ret_map = {player1:[1]}
        self.data.get_dice_map.return_value = ret_map
        ret = self.subject.get_dice_map()
        self.assertEquals(ret_map, ret)

    def testGettingFaceValues(self) :
        lowest = 1
        highest = 6
        self.data.get_lowest_dice.return_value = lowest
        self.data.get_highest_dice.return_value = highest

        result = self.subject.get_face_values()

        self.assertEquals(2, len(result))
        self.assertEquals(lowest, result[0])
        self.assertEquals(highest, result[1])

    def testShufflingDice(self) :
        players = ["player" for x in xrange(0, 3)]
        self.data.get_players.return_value = players
        lowest = 1
        highest = 6
        self.data.get_lowest_dice.return_value = lowest
        self.data.get_highest_dice.return_value = highest
        face_vals = (lowest, highest)

        self.subject.shuffle_dice()

        self.reshuffle_dice.assert_called_with(players, face_vals)

class BidCheckerTest(unittest.TestCase) :

    def testCheckingBidSimple(self) :
        player = "player"
        bid = (2, 4)
        dice_map = {player:[2, 4, 4]}
        ret = game.check_bids(bid, dice_map)
        self.assertTrue(ret is not None)
        self.assertTrue(ret)

    def testCheckingBidNegative(self) :
        player = "player"
        bid = (2, 4)
        dice_map = {player:[2, 4]}
        ret = game.check_bids(bid, dice_map)
        self.assertTrue(ret is not None)
        self.assertTrue(not ret)

class WinCheckerTest(unittest.TestCase) :

    def testCheckingBidAllNone(self) :
        dice_map = {"a":[1, 2, 3], "b":[1], "c":[1, 4, 2]}
        self.assertTrue(game.get_winner(dice_map) is None)

    def testCheckingBidOneWin(self) :
        winner = "a"
        dice_map = {winner:[1, 2, 3], "b":[], "c":[]}
        ret = game.get_winner(dice_map)
        self.assertTrue(ret is not None)
        self.assertTrue(winner == ret)

class WinHandlerTest(unittest.TestCase) :

    def setUp(self) :
        self.game_obj = Mock(spec=game.Game)
        self.subject = game.on_win

    def testHandlingWinWithoutMakingPlayerInactive(self) :
        player1 = "player"
        player2 = "player"
        bid = (1, 2)
        self.game_obj.get_dice.return_value = [1, 2]
        self.subject(player1, player2, bid, self.game_obj)
        self.game_obj.reset_bid.assert_called_with()
        self.game_obj.remove_dice.assert_called_with(player2)
        self.game_obj.shuffle_dice.assert_called_with()
        self.game_obj.get_dice.assert_called_with(player2)
        self.game_obj.set_current_player.assert_called_with(player2)

    def testHandlingWinWithMakingPlayerInactive(self) :
        player1 = "player"
        player2 = "player"
        bid = (1, 2)
        self.game_obj.get_dice.return_value = []
        self.subject(player1, player2, bid, self.game_obj)
        self.game_obj.remove_dice.assert_called_with(player2)
        self.game_obj.reset_bid.assert_called_with()
        self.game_obj.shuffle_dice.assert_called_with()
        self.game_obj.get_dice.assert_called_with(player2)
        self.game_obj.deactivate_player.assert_called_with(player2)
        self.game_obj.set_current_player.assert_called_with(player1)

class BidResetTest(unittest.TestCase) :

    def setUp(self) :
        self.game_obj = Mock(spec=game.Game)
        self.subject = game.bid_reset

    def testResettingABid(self) :
        player1 = "player1"
        players = [player1]

        self.subject(players, self.game_obj)

        self.game_obj.set_bid(player1, None)

class ReshuffleDiceTest(unittest.TestCase) :

    def setUp(self) :
        self.game_obj = Mock(spec=game.Game)
        self.dice_roller = Mock(spec=game_common.roll_set_of_dice)
        self.subject = game.reshuffle_dice

    def testShufflingDice(self) :
        player1 = "player1"
        players = [player1]
        face_vals = (1, 6)
        num = 3
        return_dice = [3] * num
        total_players = len(players)
        self.game_obj.num_of_dice.return_value = num
        self.dice_roller.return_value = return_dice

        self.subject(players, face_vals, self.game_obj,
             self.dice_roller)

        self.dice_roller.assert_called_with(num, face_vals)
        self.game_obj.set_dice.assert_called_with(player1,
             return_dice)

def suite() :
    """Return a test suite of all tests defined in this module"""
    test_suite = unittest.TestSuite()
    loader = unittest.TestLoader()
    test_suite.addTests(loader.loadTestsFromTestCase(GameObjectTest))
    test_suite.addTests(loader.loadTestsFromTestCase(BidCheckerTest))
    test_suite.addTests(loader.loadTestsFromTestCase(WinCheckerTest))
    test_suite.addTests(loader.loadTestsFromTestCase(WinHandlerTest))
    test_suite.addTests(loader.loadTestsFromTestCase(BidResetTest))
    test_suite.addTests(loader.loadTestsFromTestCase(ReshuffleDiceTest))
    return test_suite

if __name__ == "__main__" :
    unittest.TextTestRunner().run(suite())


from django.db.models import Q

import math
from pytz.exceptions import NonExistentTimeError

from archive.models.log_models import WorldBossLogArchive, WorldBossLogItemDropArchive, WorldBossLogMonsterDropArchive, WorldBossLogRuneDropArchive, \
    WishLogArchive, WishLogItemDropArchive, WishLogMonsterDropArchive, WishLogRuneDropArchive, \
    DungeonArtifactDropArchive, DungeonItemDropArchive, DungeonLogArchive, DungeonMonsterDropArchive, DungeonMonsterPieceDropArchive, \
    DungeonRuneCraftDropArchive, DungeonRuneDropArchive, DungeonSecretDungeonDropArchive, \
    RiftDungeonItemDropArchive, RiftDungeonLogArchive, RiftDungeonMonsterDropArchive, RiftDungeonRuneCraftDropArchive, RiftDungeonRuneDropArchive, \
    RiftRaidLogArchive, RiftRaidItemDropArchive, RiftRaidMonsterDropArchive, RiftRaidRuneCraftDropArchive, \
    MagicBoxCraftArchive, MagicBoxCraftItemDropArchive, MagicBoxCraftRuneCraftDropArchive, MagicBoxCraftRuneDropArchive, \
    ShopRefreshLogArchive, ShopRefreshItemDropArchive, ShopRefreshMonsterDropArchive, ShopRefreshRuneDropArchive, \
    SummonLogArchive, CraftRuneLogArchive, FullLogArchive
from archive.models.report_models import WishReportArchive, LevelReportArchive, SummonReportArchive, \
    RuneCraftingReportArchive, MagicShopRefreshReportArchive, MagicBoxCraftingReportArchive
from data_log.models.log_models import WorldBossLog, WishLog, DungeonLog, RiftDungeonLog, RiftRaidLog, MagicBoxCraft, ShopRefreshLog, SummonLog, CraftRuneLog, FullLog
from data_log.models.report_models import WishReport, LevelReport, SummonReport, MagicShopRefreshReport, \
    RuneCraftingReport, MagicBoxCraftingReport

BATCH_SIZE = 5000

def _archive_log(date_to, options):
    log_model = options['log_model']
    archive_model = options['archive_model']
    filter_field = options['filter_field']
    is_dungeon = options.get('is_dungeon', False)

    # sub-tables
    item_submodel = options.get('item_submodel', None)
    monster_submodel = options.get('monster_submodel', None)
    monster_pieces_submodel = options.get('monster_pieces_submodel', None)
    rune_submodel = options.get('rune_submodel', None)
    rune_crafts_submodel = options.get('rune_crafts_submodel', None)
    artifact_submodel = options.get('artifact_submodel', None)
    secret_dungeon_submodel = options.get('secret_dungeon_submodel', None)

    select_related = ['summoner']
    if is_dungeon:
        select_related.append('level')

    prefetch_related = []
    if item_submodel:
        prefetch_related.append('items')
    if monster_submodel:
        prefetch_related.append('monsters')
    if monster_pieces_submodel:
        prefetch_related.append('monster_pieces')
    if rune_submodel:
        prefetch_related.append('runes')
    if rune_crafts_submodel:
        prefetch_related.append('rune_crafts')
    if artifact_submodel:
        prefetch_related.append('artifacts')
    if secret_dungeon_submodel:
        prefetch_related.append('secret_dungeons')

    q_log = Q(**{filter_field + '__lte': date_to})
    qs_log = log_model.objects.filter(q_log).select_related(*select_related)
    if prefetch_related:
        qs_log = qs_log.prefetch_related(*prefetch_related)

    qs_log_c = qs_log.count()
    batches = math.ceil(qs_log_c / BATCH_SIZE)
    print(f"[{log_model.__name__}] To archive: {str(batches)} batches, which equals {str(qs_log_c)}")
    for idb in range(batches):
        to_create_item_drop_archive = []
        to_create_monster_drop_archive = []
        to_create_monster_pieces_drop_archive = []
        to_create_rune_drop_archive = []
        to_create_rune_crafts_drop_archive = []
        to_create_artifact_drop_archive = []
        to_create_secret_dungeon_drop_archive = []
        ids_to_delete = []
        for log in qs_log[:BATCH_SIZE]:
            try:
                archive_log = archive_model.objects.create(**archive_model.archive_data(log))

                if item_submodel:
                    to_create_item_drop_archive += [item_submodel(
                        **item_submodel.archive_data(archive_log, item)
                    ) for item in log.items.all()]

                if monster_submodel:
                    to_create_monster_drop_archive += [monster_submodel(
                        **monster_submodel.archive_data(archive_log, monster)
                    ) for monster in log.monsters.all()]

                if monster_pieces_submodel:
                    to_create_monster_pieces_drop_archive += [monster_pieces_submodel(
                        **monster_pieces_submodel.archive_data(archive_log, item)
                    ) for item in log.monster_pieces.all()]

                if rune_submodel:
                    to_create_rune_drop_archive += [rune_submodel(
                        **rune_submodel.archive_data(archive_log, rune)
                    ) for rune in log.runes.all()]

                if rune_crafts_submodel:
                    to_create_rune_crafts_drop_archive += [rune_crafts_submodel(
                        **rune_crafts_submodel.archive_data(archive_log, item)
                    ) for item in log.rune_crafts.all()]

                if artifact_submodel:
                    to_create_artifact_drop_archive += [artifact_submodel(
                        **artifact_submodel.archive_data(archive_log, item)
                    ) for item in log.artifacts.all()]

                if secret_dungeon_submodel:
                    to_create_secret_dungeon_drop_archive += [secret_dungeon_submodel(
                        **secret_dungeon_submodel.archive_data(archive_log, item)
                    ) for item in log.secret_dungeons.all()]
            except NonExistentTimeError:
                pass

            ids_to_delete.append(log.id)

        log_model.objects.filter(pk__in=ids_to_delete).delete()
        _iter = min((idb + 1) * BATCH_SIZE, qs_log_c)
        print(f"[{archive_model.__name__}] {str(_iter)}/{str(qs_log_c)} ({str(round(_iter / qs_log_c * 100, 2))}%)")

        if item_submodel:
            item_submodel.objects.bulk_create(to_create_item_drop_archive, batch_size=BATCH_SIZE)
        if monster_submodel:
            monster_submodel.objects.bulk_create(to_create_monster_drop_archive, batch_size=BATCH_SIZE)
        if monster_pieces_submodel:
            monster_pieces_submodel.objects.bulk_create(to_create_monster_pieces_drop_archive, batch_size=BATCH_SIZE)
        if rune_submodel:
            rune_submodel.objects.bulk_create(to_create_rune_drop_archive, batch_size=BATCH_SIZE)
        if rune_crafts_submodel:
            rune_crafts_submodel.objects.bulk_create(to_create_rune_crafts_drop_archive, batch_size=BATCH_SIZE)
        if artifact_submodel:
            artifact_submodel.objects.bulk_create(to_create_artifact_drop_archive, batch_size=BATCH_SIZE)
        if secret_dungeon_submodel:
            secret_dungeon_submodel.objects.bulk_create(to_create_secret_dungeon_drop_archive, batch_size=BATCH_SIZE)

def archive_world_boss_logs(date_to):
    options = {
        'log_model': WorldBossLog,
        'archive_model': WorldBossLogArchive,
        'filter_field': 'timestamp',
        'is_dungeon': True,

        'item_submodel': WorldBossLogItemDropArchive,
        'monster_submodel': WorldBossLogMonsterDropArchive,
        'rune_submodel': WorldBossLogRuneDropArchive,
    }
    _archive_log(date_to, options)

def archive_wish_logs(date_to):
    options = {
        'log_model': WishLog,
        'archive_model': WishLogArchive,
        'filter_field': 'timestamp',

        'item_submodel': WishLogItemDropArchive,
        'monster_submodel': WishLogMonsterDropArchive,
        'rune_submodel': WishLogRuneDropArchive,
    }
    _archive_log(date_to, options)

def archive_dungeon_logs(date_to):
    options = {
        'log_model': DungeonLog,
        'archive_model': DungeonLogArchive,
        'filter_field': 'timestamp',
        'is_dungeon': True,

        'item_submodel': DungeonItemDropArchive,
        'monster_submodel': DungeonMonsterDropArchive,
        'monster_pieces_submodel': DungeonMonsterPieceDropArchive,
        'rune_submodel': DungeonRuneDropArchive,
        'rune_crafts_submodel': DungeonRuneCraftDropArchive,
        'artifact_submodel': DungeonArtifactDropArchive,
        'secret_dungeon_submodel': DungeonSecretDungeonDropArchive,
    }
    _archive_log(date_to, options)

def archive_rift_dungeon_logs(date_to):
    options = {
        'log_model': RiftDungeonLog,
        'archive_model': RiftDungeonLogArchive,
        'filter_field': 'timestamp',
        'is_dungeon': True,

        'item_submodel': RiftDungeonItemDropArchive,
        'monster_submodel': RiftDungeonMonsterDropArchive,
        'rune_submodel': RiftDungeonRuneDropArchive,
        'rune_crafts_submodel': RiftDungeonRuneCraftDropArchive,
    }
    _archive_log(date_to, options)

def archive_raid_dungeon_logs(date_to):
    options = {
        'log_model': RiftRaidLog,
        'archive_model': RiftRaidLogArchive,
        'filter_field': 'timestamp',
        'is_dungeon': True,

        'item_submodel': RiftRaidItemDropArchive,
        'monster_submodel': RiftRaidMonsterDropArchive,
        'rune_crafts_submodel': RiftRaidRuneCraftDropArchive,
    }
    _archive_log(date_to, options)

def archive_magic_box_craft_logs(date_to):
    options = {
        'log_model': MagicBoxCraft,
        'archive_model': MagicBoxCraftArchive,
        'filter_field': 'timestamp',

        'item_submodel': MagicBoxCraftItemDropArchive,
        'rune_submodel': MagicBoxCraftRuneDropArchive,
        'rune_crafts_submodel': MagicBoxCraftRuneCraftDropArchive,
    }
    _archive_log(date_to, options)

def archive_shop_refresh_logs(date_to):
    options = {
        'log_model': ShopRefreshLog,
        'archive_model': ShopRefreshLogArchive,
        'filter_field': 'timestamp',

        'item_submodel': ShopRefreshItemDropArchive,
        'rune_submodel': ShopRefreshRuneDropArchive,
        'monster_submodel': ShopRefreshMonsterDropArchive,
    }
    _archive_log(date_to, options)

def archive_summon_logs(date_to):
    options = {
        'log_model': SummonLog,
        'archive_model': SummonLogArchive,
        'filter_field': 'timestamp',
    }
    _archive_log(date_to, options)

def archive_craft_rune_logs(date_to):
    options = {
        'log_model': CraftRuneLog,
        'archive_model': CraftRuneLogArchive,
        'filter_field': 'timestamp',
    }
    _archive_log(date_to, options)

def archive_full_logs(date_to):
    options = {
        'log_model': FullLog,
        'archive_model': FullLogArchive,
        'filter_field': 'timestamp',
    }
    _archive_log(date_to, options)

def archive_reports(date_to):
    q_report = Q(generated_on__lte=date_to)

    report_archive_map = {
        WishReport: WishReportArchive,
        LevelReport: LevelReportArchive,
        SummonReport: SummonReportArchive,
        MagicShopRefreshReport: MagicShopRefreshReportArchive,
        MagicBoxCraftingReport: MagicBoxCraftingReportArchive,
        RuneCraftingReport: RuneCraftingReportArchive,
    }

    for report_model, archive_model in report_archive_map.items():
        qs_report = report_model.objects.filter(q_report).select_related('report_ptr')
        qs_report_c = qs_report.count()
        batches = math.ceil(qs_report_c / BATCH_SIZE)
        print(f"[{report_model.__name__}] To archive: {str(batches)} batches, which equals {str(qs_report_c)}")
        for idb in range(batches):
            ids_to_delete = []
            archive_to_create = []
            for report in qs_report[:BATCH_SIZE]:
                data = {
                    'content_type': report.content_type,
                    'generated_on': report.generated_on,
                    'start_timestamp': report.start_timestamp,
                    'end_timestamp': report.end_timestamp,
                    'log_count': report.log_count,
                    'unique_contributors': report.unique_contributors,
                    'report': report.report,
                    'generated_by_user': report.generated_by_user,
                }
                if report_model == LevelReport:
                    data['level_id'] = report.level_id
                elif report_model == SummonReport:
                    data['item_id'] = report.item_id
                elif report_model == MagicBoxCraftingReport:
                    data['box_type'] = report.box_type
                elif report_model == RuneCraftingReport:
                    data['craft_level'] = report.craft_level

                archive_to_create.append(archive_model(**data))
                ids_to_delete.append(report.id)

            archive_model.objects.bulk_create(archive_to_create, batch_size=BATCH_SIZE)
            report_model.objects.filter(pk__in=ids_to_delete).delete()
            _iter = min((idb + 1) * BATCH_SIZE, qs_report_c)
            print(f"[{archive_model.__name__}] {str(_iter)}/{str(qs_report_c)} ({str(round(_iter / qs_report_c * 100, 2))}%)")


"""
comms module handles communications with Halti Master.

Currently a keep-alive HTTP connection and JSON is used but we should be able to
change this to anything with minimal effort.
"""
import json
import logging
import requests

from halti_agent import settings

logger = logging.getLogger('halti-agent-comms')

s = requests.Session()
s.headers.update({'Content-Type': 'application/json',
                  'Accept': 'application/json'})

# store instance ID here so comms always has access to it
INSTANCE_ID = None

HEARTBEAT_URL = '/api/v1/instances/{}/heartbeat'
REGISTER_URL = '/api/v1/instances/register'
NOTIFY_URL = '/api/v1/instances/{}/notify'

def post_json(url, payload):
    """HTTP Post payload to given url with correct headers."""
    full_url = settings.HALTI_SERVER_URL + url
    data = json.dumps(payload)
    res_json = s.post(full_url, data=data).json()
    logger.debug('received data: {}'.format(res_json))
    return res_json

def heartbeat(payload):
    """Perform Halti Heartbeat with Halti Master."""
    return post_json(HEARTBEAT_URL.format(INSTANCE_ID), payload)

def register(payload):
    """Register this node with Halti master."""
    return post_json(REGISTER_URL, payload)

def notify_master(event, meta):
    """Notify master with an Halti Event."""
    try:
        return post_json(NOTIFY_URL.format(INSTANCE_ID), halti_event(event, meta))
    except requests.RequestException as ex:
        logger.error('could not notify master: {}'.format(ex), exc_info=True)

class Events(object):
    """Halti Event constants."""
    PULL_FAILED = 'PULL_FAILED'
    PULL_START = 'PULL_START'
    START_CONTAINER = 'START_CONTAINER'
    START_CONTAINER_FAILED = 'START_CONTAINER_FAILED'
    STOP_CONTAINER = 'STOP_CONTAINER'

def halti_event(event, meta=''):
    """event, meta => Halti Event.

    Automatically determines event_type (default is "INFO").
    """
    types = {
        'INFO': {Events.PULL_START},
        'ERROR': {Events.PULL_FAILED}
    }

    def _get_event_type(event):
        return next((t for t, evnts in types.items() if event in evnts), 'INFO')

    return {
        'event': event,
        'event_type': _get_event_type(event),
        'event_meta': meta
    }


#
# @lc app=leetcode.cn id=709 lang=python
#
# [709] 转换成小写字母
#

# @lc code=start
class Solution(object):
    def toLowerCase(self, str):
        """
        :type str: str
        :rtype: str
        """
        base = ord('a')
        delta = base - ord('A')
        res = []
        for ch in str:
            if ch.isalpha() and ord(ch) < base:
                res.append(chr(ord(ch) + delta))
            else:
                res.append(ch)
        return ''.join(res)

# @lc code=end

709.转换成小写字母.py

709.转换成小写字母.py


import cv2
import dlib
import os
import sys
import random

output_dir = './my_faces'
size = 64

if not os.path.exists(output_dir):
    os.makedirs(output_dir)

# Change the brightness and contrast of the picture
def relight(img, light=1, bias=0):
    w = img.shape[1]
    h = img.shape[0]
    #image = []
    for i in range(0,w):
        for j in range(0,h):
            for c in range(3):
                tmp = int(img[j,i,c]*light + bias)
                if tmp > 255:
                    tmp = 255
                elif tmp < 0:
                    tmp = 0
                img[j,i,c] = tmp
    return img

# Use the frontal_face_detector that comes with dlib as our feature extractor
detector = dlib.get_frontal_face_detector()
# Turn on the camera parameter for the input stream, which can be a camera or video file
camera = cv2.VideoCapture(0)

index = 1
while True:
    if (index <= 10000):
        print('Being processed picture %s' % index)
        # Read photos from the camera
        success, img = camera.read()
        # Convert to grayscale image
        gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        # Face detection using the detector
        dets = detector(gray_img, 1)

        for i, d in enumerate(dets):
            x1 = d.top() if d.top() > 0 else 0
            y1 = d.bottom() if d.bottom() > 0 else 0
            x2 = d.left() if d.left() > 0 else 0
            y2 = d.right() if d.right() > 0 else 0

            face = img[x1:y1,x2:y2]
            # Adjust the contrast and brightness of the image, and the contrast and brightness values are random numbers
            # which can increase the diversity of the sample.
            face = relight(face, random.uniform(0.5, 1.5), random.randint(-50, 50))

            face = cv2.resize(face, (size,size))

            cv2.imshow('image', face)

            cv2.imwrite(output_dir+'/'+str(index)+'.jpg', face)

            index += 1
        key = cv2.waitKey(30) & 0xff
        if key == 27:
            break
    else:
        print('Finished!')
        break


import numpy as np
import random

class VektParuosimas:
# Skirtumų paieškos funkcija, kuriai paduodami originalus ir modifikuotas vektoriai,
# grąžinamas neatitikusių elementų vietų masyvas.
    def findDifferences(self, original, modified):
        differences = []
        for i in range(len(original[0])):
            if modified[0][i] != original[0][i]:
                differences.append(i)
        return differences

# Paduodamas tekstas paverčiamas binariniu kodu. Grąžinamos rašybos ženklų
# binarinės vertės atskirtos tarpais.
    def stringToBinary(self, text):
        res = ' '.join(format(ord(x), 'b') for x in text)
        return res

# Kiekvieno rašybos ženklo(binarine forma) vektoriaus gale pridedama
# tiek nulių, kad vektorius būtų tinkamo ilgio(12).
# Funkcijai paduodamos rašybos ženklų binarinės vertės atskirtos tarpais,
# grąžinami sutvarkyti vektoriai ilgio 12 (pvz [110000100000, 110001000000]), bei pridėtų 0-ių kiekiai (pvz [5,5])
    def skaidytiBinary(self, text):
        skaidList = []
        addedZeros = []

        for binary_value in text:
                integer = binary_value
                for _ in range(12-len(binary_value)):
                    integer = integer + "0"
                addedZeros.append(12-len(binary_value))
                skaidList.append(int(integer))
        return skaidList, addedZeros

# Funkcijai paduodami sutvarkyti(ilgio 12) ir gauti išsiuntus kanalu binariniai vektoriai, bei pridėtų 0 kiekiai
# Funkcija binarius vektorius paverčia ascii simboliais ir grąžina tekstą.
    def binaryToString(self, binaryVektoriai, addedZeros):
        ascii_string = ""
        gautiVektoriai = []

        if len(binaryVektoriai[0]) == 23:
            for j in range(len(binaryVektoriai)):
                gautiVektoriai.append(binaryVektoriai[j][0:12])
        elif len(binaryVektoriai[0]) == 12:
            gautiVektoriai = binaryVektoriai

        for i in range(len(gautiVektoriai)):
            cutZeros = gautiVektoriai[i][0:len(gautiVektoriai[i])-addedZeros[i]]

            s = [str(i) for i in cutZeros]
            joinedInt = int("".join(s), 2)

            ascii_character = chr(joinedInt)
            ascii_string += ascii_character
        return ascii_string

# Funkcija paverčianti vektorius tinkamo formato, kad galimas būtų atvaizduoti paveikslėlis
# Suskirstoma eilutėmis ir stulpeliais pagal pradinio paveikslėlio parametrus
# Funkcijai paduodami gauti binariniai vektoriai, pridėtų 0 kiekiai, bei
# pradinio paveikslėlio stulpelių ir eilučių kiekiai
# Grąžinamas galutinis sutvarkytas sąrašas koordinačių.
    def formatBinaryForPicture(self, binaryVektoriai, addedZeros, len1, len2):
        gautiVektoriai = []
        intVekt = []

        if len(binaryVektoriai[0]) == 23:
            for j in range(len(binaryVektoriai)):
                gautiVektoriai.append(binaryVektoriai[j][0:12])
        elif len(binaryVektoriai[0]) == 12:
            gautiVektoriai = binaryVektoriai

        for i in range(len(gautiVektoriai)):
            cutZeros = gautiVektoriai[i][0:len(gautiVektoriai[i])-addedZeros[i]]

            s = [str(i) for i in cutZeros]

            if s == 0 or s == []:
                joinedInt = 0
            else: joinedInt = int("".join(s), 2)
            intVekt.append(joinedInt)

        k = 0
        row = []
        galutinisList = []

        for i in range(int(len(intVekt)/len2)):
            a = k * len2
            row = intVekt[a:a+len2]
            galutinisList.append(row)
            k += 1

        return galutinisList


from turtle import Turtle
FONT = 50
ALIGNMENT = "center"

class Scoreboard(Turtle):
    def __init__(self, side):
        self.score = 0
        super().__init__()
        self.penup()
        self.side = side
        if side == "left":
            self.goto(-40, 220)
        else:
            self.goto(40, 220)
        self.color("white")
        self.hideturtle()
        self.write(f"{0}", True, align=ALIGNMENT, font=("Ariel", FONT, "normal"))

    def increase_score(self, in_double_round):
        if in_double_round:
            self.score += 2
        else:
            self.score += 1
        self.clear()
        if self.side == "left":
            self.goto(-40, 220)
        else:
            self.goto(40, 220)

        self.write(f"{self.score}", True, align=ALIGNMENT, font=("Ariel", FONT, "normal"))


#!/usr/bin/python3
def square_matrix_simple(matrix=[]):
    # Create a new matrix to store the squared values
    squared_matrix = []

    # Iterate through each row in the input matrix
    for row in matrix:
        squared_row = []

        # Iterate through each element in the row and square it
        for num in row:
            squared_row.append(num ** 2)

        # Append the squared row to the squared matrix
        squared_matrix.append(squared_row)

    return squared_matrix


"""empty message

Revision ID: 1d8e1742395c
Revises: 2faeca62add6
Create Date: 2017-05-16 15:06:28.660819

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '1d8e1742395c'
down_revision = '2faeca62add6'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('questions',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('user_id', sa.Integer(), nullable=True),
    sa.Column('title', sa.String(length=64), nullable=True),
    sa.Column('description', sa.String(length=256), nullable=True),
    sa.Column('create_date', sa.DateTime(), nullable=True),
    sa.Column('update_date', sa.DateTime(), nullable=True),
    sa.Column('favorites', sa.Integer(), nullable=True),
    sa.Column('has_accepted_answer', sa.Boolean(), nullable=True),
    sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_questions_create_date'), 'questions', ['create_date'], unique=False)
    op.create_index(op.f('ix_questions_update_date'), 'questions', ['update_date'], unique=False)
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_index(op.f('ix_questions_update_date'), table_name='questions')
    op.drop_index(op.f('ix_questions_create_date'), table_name='questions')
    op.drop_table('questions')
    # ### end Alembic commands ###


import tkinter as tk
from tkinter.messagebox import *

class APP:
    def __init__(self, master):
        frame = tk.Frame(master)
        frame.pack(side = tk.LEFT, padx = 10, pady = 10)

        self.hi_here = tk.Button(frame, text = "你好啊", fg = "black", bg = "white", command = self.say_hi)
        self.hi_here.pack()

    def say_hi(self):
        showinfo(message='hello')

        # 显示标签
        # var = tk.StringVar()
        # label = tk.Message( root, textvariable=var, relief=tk.RAISED )
        # var.set("Hey!? How are you doing?")
        # label.pack()

root = tk.Tk()
app = APP(root)

root.mainloop()


# -*- coding: utf-8 -*-
"""
Created on Wed Sep 12 17:50:24 2018

code split into multiple parts for ease of running

@author: Shane
"""
import random
import numpy as np
from sklearn import linear_model

'''
Question 5-7

Running it experimentally to get the output

N = 100
c
c

change N = 10
a
'''
N = 10
d = 2
runs = 1000

#function that implements the PLA learning algorithm
def PLA(data, labels, weights = [0] * (d + 1)):

    intercept = np.ones((N,1))
    data = np.hstack((intercept, data))

    nloops = 0

    while True:

        #increment loop counter
        nloops += 1

        if nloops > 10000:
            #return number of loops used
            return nloops

        #use current weights to generate hypothesis
        hypothesis = np.sign(np.matmul(weights, np.transpose(data)))

        wrong = labels != hypothesis
        test = np.where(wrong)

        #if there are misclassified points
        if len(test[0]) >= 1:
            #select one at random
            select = random.choice(test[0])
            #update weights
            weights = weights + labels[select] * data[select]

        else:
            #return number of loops used
            return nloops, weights

#setup for PLA hw problem

def setup_problem(N):
    points = []
    for i in range(N):
        coord = [random.uniform(-1,1), random.uniform(-1,1)]
        points.append(coord)

    points = np.array(points)

    # get bisecting line
    point1 = (random.uniform(-1,1), random.uniform(-1,1))
    point2 = (random.uniform(-1,1), random.uniform(-1,1))
    a = (point1[1] - point2[1])/(point1[0] - point2[0])
    b = point1[1] - a*point1[0]

    labels = []
    for point in points:
        if point[1] < a * point[0] + b:
            labels.append(1)
        else:
            labels.append(-1)

    labels = np.array(labels)

    equation = (a,b)

    return points, labels, equation

#function to measure accuracy for out of sample (newly generated) data
def measure_accuracy(f, model):
    num = 1000
    points = []
    for i in range(num):
        coord = [random.uniform(-1,1), random.uniform(-1,1)]
        points.append(coord)

    points = np.array(points)

    #get true labels
    f_labels = []

    for point in points:
        if point[1] < f[0] * point[0] + f[1]:
            f_labels.append(1)
        else:
            f_labels.append(-1)

    g_labels = np.sign(model.predict(points))

    f_labels = np.array(f_labels)
    g_labels = np.array(g_labels)

    #return percent accurate
    return np.sum(f_labels == g_labels)/num

#try running PLA
acc_in = []
acc_out = []
nruns = []

for i in range(runs):
    points, labels, equation = setup_problem(N)

    #train linear regression
    regr = linear_model.LinearRegression()
    regr.fit(points, labels)

    y_pred_in = np.sign(regr.predict(points))

    acc_in.append(np.sum(labels == y_pred_in)/len(labels))

    acc_out.append(measure_accuracy(equation, regr))

    #PLA loops
    nloops, weights = PLA(points, labels, np.insert(regr.coef_, 0, [regr.intercept_]))
    nruns.append(nloops)

#average number of runs
print(np.mean(acc_in))
print(np.mean(acc_out))
print(np.mean(nruns))


from BaseHTTPServer import (HTTPServer,
                            BaseHTTPRequestHandler)
import SocketServer
import os
import subprocess
import tempfile
from shutil import rmtree
from hook import HookHandler
from util import withTempDirDo

class TagHookHandler(HookHandler):
    """Request handler to handle the tag web hook

    You need to specify a pypi repository for the hook handler to
    work.  You do that by setting the pypirepo field of the class:
    HookHandler.pypirepo = "yourrepo".

    Notice that the repo name you specify has to appear in the .pypirc
    of the user running server.
    """
    def do_POST(self):

        # send ok
        if not self.checkIP():
            self.send_response(403)
            return

        # parse json
        print("Parse JSON...")
        data = self.getJSON()
        if data is None:
            print("... JSON not valid!")
            return
        print("... JSON okay")
        ref = data['ref']
        repo = data['repository']['url']

        # check repository url
        print("Check repository URL...")
        if not self.checkRepoURL(repo):
            print("... URL not allowed")
            self.send_response(403)
            return
        print("... URL okay")

        # everything seems okay
        self.send_response(200)

        # handle tag
        withTempDirDo(handle_tag,
                      repository=repo,
                      reference=ref,
                      pypi=self.pypirepo,
                      python_path=self.python_path)

    pypirepo = None

def handle_tag(repository, reference, pypi, python_path="python"):
    """checkout revs from a git repo and upload a python sdist to pypi

    This function assumes that your cwd is already pointing to the git
    repository in question.
    """

    # pull repository and checkout the reference
    subprocess.call(['git','clone',repository,'-n','.'])
    subprocess.call(['git','checkout',reference])

    if os.path.exists('setup.py'):
        if not pypi is None:
            subprocess.call([python_path,'setup.py','sdist','upload','-r',pypi])
        else:
            subprocess.call([python_path,'setup.py','sdist','upload'])

def run_server(port, klass=TagHookHandler):
    """Start a webserver from the specified class"""
    server_address = ('', port)
    httpd = HTTPServer(server_address, klass)
    print("Start Webserver on port %i" % port)
    print("Hit CTL-C to shut down the server")
    print("Upload new releases to pypi repository \"%s\""\
          % TagHookHandler.pypirepo)
    # start web server
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        httpd.socket.close()


from calc_tasks import arm_stiffness_calc
from utils.ns_plot import SL_ns, ns_plot
from utils.tools import dims_adjust

def data_process_func(as_results, data):
    as_dic, arms_idx = as_results
    from collections import OrderedDict
    stf_dic = OrderedDict() # {arm_id:{t:armstf}}
    for ia in arms_idx:
        stf_dic[ia] = OrderedDict()
    for t_stamp, as_ls in as_dic.items():
        for armstf, ia in as_ls:
            stf_dic[ia][t_stamp] = armstf
    stf_ls = [stf for s_a_dic in list(stf_dic.values()) for stf in list(s_a_dic.values())] # s_a_dic: {t:armstf} of a single arm; stf_ls:[stf]
    return stf_ls

def ns_as_plot(single=True, arms=4, temp=30, conc=0.5, sp_suffix='', conf_suffix='', flag_suffix='', dims_ls= [20,2,7]):
    varname = 'as'
    dims_adjust(dims_ls, conf_suffix, single, sp_suffix)
    data = (arms, temp, conc, sp_suffix, conf_suffix, flag_suffix, dims_ls)
    results = SL_ns(arm_stiffness_calc, data, varname) # results: var_ls_results, label, plotpath
    #### plot confs ####
    x_var = 'Arm Stiffness'
    x_lim = (0,1)
    y_lim = (0,0.3)
    bin_num = 50
    text_pos = (0.7, 0.215)
    #### conf ends ####
    plot_confs = varname, x_var, x_lim, y_lim, text_pos, bin_num
    summary = ns_plot(data_process_func, results, plot_confs, data, varname) # summary: m1,std,m3_s
    # ns_plot does save figures.
    return summary


"""
民政部网站 最新行政区划代码
1.假链接:向主页发请求
2.提取真链接:向假链接发请求，提取真实返回数据的url地址
3.向真链接发请求 提取最终数据
"""
import sys,re

import requests
from lxml import etree
import redis
from hashlib import md5

class MzbSpider:
    def __init__(self):
        self.url = 'http://www.mca.gov.cn/article/sj/xzqh/2020/'
        self.headers = {"User-Agent":'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'}
        #redis实现增量
        self.r = redis.Redis(host='localhost',port=6379,db=4)

    def get_html(self,url):
        html = requests.get(url=url,headers=self.headers,verify=False).text

        return html

    def xpath_func(self,html,xpath_bds):
        p = etree.HTML(html)
        r_list = p.xpath(xpath_bds)

        return r_list

    def md5_func(self,url):
        s = md5()
        s.update(url.encode())

        return s.hexdigest()

    def get_false_url(self):
        false_html = self.get_html(url=self.url)
        false_xpath_bds = '//table/tr[2]/td[2]/a/@href'
        href_list = self.xpath_func(false_html,false_xpath_bds)
        if href_list:
            false_url = 'http://www.mca.gov.cn'+href_list[0]
            finger = self.md5_func(false_url)
            if self.r.sadd('mzb:spider',finger)==1:
                # 开始进行数据抓取
                self.get_real_url(false_url)
            else:
                sys.exit('抓取完成')
        else:
            print('最新月份提取失败')
    def re_func(self,html,regex):
        pattern = re.compile(regex,re.S)
        r_list = pattern.findall(html)

        return r_list

    def get_real_url(self,false_url):
        html = self.get_html(false_url)
        regex = '<span style="float:left;width:0;height:0;">.*?<script>.*?window.location.href="(.*?)".*?</script><script type="text/javascript">'
        real_url_list = self.re_func(html,regex)
        if real_url_list:
           real_url = real_url_list[0]
           self.get_real_html(real_url)
        else:
            sys.exit('无数据')

    def get_real_html(self,real_url):
        html = self.get_html(real_url)
        xpath_bds = '//tr[@height="19"]'
        tr_list = self.xpath_func(html,xpath_bds)
        item={}
        for tr in tr_list:
            code_list = tr.xpath('./td[2]/text()|./td[2]/span/text()')
            name_list = tr.xpath('./td[3]/text()')
            item['code'] = code_list[0].strip() if code_list else None
            item['name'] = name_list[0].strip() if name_list else None
            print(item)

    def run(self):
        self.get_false_url()

if __name__ == '__main__':
    spider = MzbSpider()
    spider.run()


#poker homework
import random
suits = ["♠", "♥", "♦", "♣"]
ranks = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"]

class Card(object):
    def __init__(self, suit, rank):
        self.suit = suit
        self.rank = rank

    def get_suit(self):
        return self.suit

    def get_rank(self):
        return self.rank

    def __str__(self):
        return "%s%s" % (self.rank, self.suit)

class Deck(object):
    def __init__(self):
        self.cards = []
        for s in suits:
            for r in ranks:
                self.cards.append(Card(s, r))

    def shuffle(self):
        random.shuffle(self.cards)

    def __str__(self):
        deck = ""
        for i in range(0, 52):
            deck += str(self.cards[i]) + " "
        return deck

    def take_one(self):
        return self.cards.pop(0)

class Hand(object):
    def __init__(self, deck):
        self.cards = []
        for i in range(5):
            self.cards.append(deck.take_one())

    def __str__(self):
        hand = ""
        for i in range(5):
            hand += str(self.cards[i]) + " "
        return hand

    def is_pair(self):
        pair_rank = ''
        for i in range(5):
            for j in range(i+1, 5):
                if self.cards[i].get_rank() == self.cards[j].get_rank():
                    pair_rank = self.cards[i].get_rank()
                    return True, pair_rank
        return False, pair_rank

    def is_two_pair(self):
        pairs_rank = []
        counter = 0
        for i in range(5):
            for j in range(i + 1, 5):
                if self.cards[i].get_rank() == self.cards[j].get_rank():
                    if self.cards[i].get_rank() in pairs_rank:
                        break
                    else:
                        counter += 1
                        pairs_rank.append(self.cards[i].get_rank())
        if counter == 2:
            return True, pairs_rank

        else:
            return False, pairs_rank

    def is_flush(self):
        suit = self.cards[0].get_suit()
        for i in range(5):
            if self.cards[i].get_suit()!=suit:
                return False
        return True

    def is_straight(self):
        rank_numbers = []
        for i in range(5):
            number = ranks.index(self.cards[i].get_rank())
            rank_numbers.append(number)

        rank_numbers.sort()
        for i in range(5):
            j = i + 1
            if j < 5:
                if rank_numbers[j] - rank_numbers[i] != 1:
                    return False
        return True

    def is_straight_flush(self):
        if hand.is_flush() == False:
            return False

        else:
            rank_numbers = []
            for i in range(5):
                number = ranks.index(self.cards[i].get_rank())
                rank_numbers.append(number)

            rank_numbers.sort()
            if rank_numbers[0] == 0 and \
                    rank_numbers[1] == 1 and \
                    rank_numbers[2] == 2 and \
                    rank_numbers[3] == 3 and \
                    rank_numbers[4] == 12:
                return True

            for i in range(5):
                j = i + 1
                if j < 5:
                    if rank_numbers[j] - rank_numbers[i] != 1:
                        return False
                    else:
                        return True

    def is_royal_flush(self):  # A, K, Q, J, 10, all the same suit.
        if hand.is_flush() == False:
            return False

        else:
            rank_numbers = []
            for i in range(5):
                number = ranks.index(self.cards[i].get_rank())
                rank_numbers.append(number)

            rank_numbers.sort()
            if rank_numbers[0] == 8 and \
                    rank_numbers[1] == 9 and \
                    rank_numbers[2] == 10 and \
                    rank_numbers[3] == 11 and \
                    rank_numbers[4] == 12:
                return True
        return False

    def is_x_of_a_kind(self):
        counter = 0
        condition, pair_rank = hand.is_pair()

        if condition == False:
            return 0

        for i in range(5):
            if self.cards[i].get_rank() == pair_rank:
                counter+=1
        if counter==4:
            return 4
        elif counter==3:
            return 3
        else:
            return 0

    def is_three_of_a_kind(self):
        if hand.is_x_of_a_kind() == 3:
            return True

    def is_four_of_a_kind(self):
        if hand.is_x_of_a_kind() == 4:
            return True

    def is_full_house(self):
        condition, pairs_rank = hand.is_two_pair()
        if condition == False:
            return False

        else:
            remaining_card = []
            for i in range(5):
                remaining_card.append(self.cards[i].get_rank())

            for i in range(2):
                while pairs_rank[i] in remaining_card:
                    remaining_card.remove(pairs_rank[i])

            if len(remaining_card) == 0:
                return True

            else:
                return False

royal_flush = 0
straight_flush = 0
four_of_a_kind = 0
full_house = 0
flush = 0
straight = 0
three_of_a_kind = 0
two_pair = 0
pair = 0
nothing = 0

for count in range(100):
    new_deck = Deck()
    new_deck.shuffle()
    print(new_deck)
    hand = Hand(new_deck)
    print(hand)

    if hand.is_royal_flush() == True:
        royal_flush+=1
        print('Royal Flush')
        continue

    elif hand.is_straight_flush() == True:
        straight_flush+=1
        print('Straight Flush')
        continue

    elif hand.is_four_of_a_kind() == True:
        four_of_a_kind+=1
        print('Four of a Kind')
        continue

    elif hand.is_full_house() == True:
        full_house+=1
        print('Full House')
        continue

    elif hand.is_flush() == True:
        flush+=1
        print('Flush')
        continue

    elif hand.is_straight() == True:
        straight+=1
        print('Straight')
        continue

    elif hand.is_three_of_a_kind() == True:
        three_of_a_kind += 1
        print('Three of a Kind')
        continue

    elif True in hand.is_two_pair():
        two_pair+=1
        print('Two Pair')
        continue

    elif True in hand.is_pair():
        pair+=1
        print('Pair')
        continue

    else:
        nothing+=1
        print('Nothing')

print('Summary & statistics out of 10000 hands: ')
print('     Royal Flush: ',royal_flush,' times. Probability:  ', (royal_flush/10000))
print('     Straight Flush: ',straight_flush,' times. Probability:  ',straight_flush/10000)
print('     Four of a Kind: ',four_of_a_kind,' times. Probability:  ',four_of_a_kind/10000)
print('     Full House: ',full_house,' times. Probability:  ',full_house/10000)
print('     Flush: ',flush,' times. Probability:  ',flush/10000)
print('     Straight: ',straight,' times. Probability:  ',straight/10000)
print('     Three of a Kihd: ',three_of_a_kind,' times. Probability:  ',three_of_a_kind/10000)
print('     Two Pair: ',two_pair,' times. Probability:  ',two_pair/10000)
print('     Pair: ',pair,' times. Probability:  ',pair/10000)
print('     Nothing: ',nothing,' times. Probability:  ',nothing/10000)

total = royal_flush+straight_flush+four_of_a_kind+full_house+flush+straight+three_of_a_kind+two_pair+pair+nothing


#!/usr/bin/env python
# -- coding = 'utf-8' --
# Author WangBin
# Python Version 3.6.6
# @Software:PyCharm
# @File : vocab.py
# @Date  : 2020/9/17
# @Email  : 560331

from Public.path import path_vocab

unk_flag = '[UNK]'
pad_flag = '[PAD]'
cls_flag = '[CLS]'
sep_flag = '[SEP]'

# 为词表建立索引
def get_w2i(vocab_path=path_vocab):
    w2i = {}
    with open(vocab_path, 'r', encoding='utf-8') as f:
        while True:
            text = f.readline()
            if not text:
                break
            text = text.strip()
            if text and len(text) > 0:
                w2i[text] = len(w2i) + 1
    return w2i

#  把数据分类建立标签 并返回
def get_gree_tag2index():
    return {
        "O": 0,
        "B-Device": 1,
        'I-Device': 2,
        'B-Func': 3,
        'I-Func': 4

    }


#!/usr/bin/env python3

from pylib import *

#obs = loadz("/home/liuq/Analysis/APS/database_Zhengui/elev/noaa_elev_msl.npz")
obs = loadz("/home/liuq/Analysis/APS/database_Zhengui/elev/noaa_elev_navd.npz")

figure(figsize=[15, 6])
xts,xls=get_xtick(fmt=2,xts=[datenum(2019,8,1),datenum(2019,10,1)],str='%d/%b')
xts,xls=xts[::2],xls[::2]; xls[0]=xls[0]+', 2018'

mod = loadz("/home/liuq/Analysis/APS/RUN02a/mod_at_noaa_stations.npz")
stations= [8658120, 8658163, 8656483, 8654467, 8652587, 8651370];

for st,sta in enumerate(stations):
    subplot(2,3,st+1)
    ind = (obs.station == sta) *( obs.time >= datenum(2019, 9, 3) )* (obs.time < datenum(2019, 9, 12))
    oyi=obs.elev[ind]; oyi=oyi-oyi.mean()
    plot(obs.time[ind], oyi, "r-")
    myi=mod.elev[st,:]; myi=myi-myi.mean()
    plot(mod.time + datenum(2019, 1, 1) + 0 / 24, myi,"b-")
    setp(gca(),xticks=xts, xticklabels=xls, xlim=[datenum(2019, 9, 3), datenum(2019, 9, 12)],ylim=[-1.2, 1.2])
    title("elev. comparison at NOAA "+str(sta))

show(block=False)

savefig('Compare_Elev.png')


import time
import RPi.GPIO as io
import socket
import asyncio
import sys

def LED_Off(angle):
    print("resetting angle: ", angle)
    for p in range(4):
        io.output(4*angle+p,0)

def LED_On(angle):
    print("setting angle: ", angle)
    for p in range(4):
        io.output(4*angle+p,1)

def LED_Duty(angle, stren):
    if(stren is -1 or angle is -1):
        return

    print("LED_Duty begun")
    on_time = 0.2
    off_time = 2 - (0.2*stren)
    print(on_time)
    print(off_time)
    LED_On(angle)
    time.sleep(on_time)
    LED_Off(angle)
    time.sleep(off_time)

def init_port(port):
    io.setmode(io.BCM)
    io.setup(port,io.OUT)
    io.output(port,0)

msg_r =  [
    ["START","0","0","EOM"],
    ["START","0","1","EOM"],
    ["START","0","2","EOM"],
    ["START","0","3","EOM"],
    ["START","0","4","EOM"],
    ["START","0","5","EOM"],
    ["START","0","6","EOM"],
    ["START","0","7","EOM"],
    ["START","0","8","EOM"],
    ["START","0","9","EOM"]
]

def msg_cycle():
    print("cycling message")
    print("index = %d" % msg_cycle.index)
    s_msg = msg_r[msg_cycle.index]
    msg_cycle.index = (msg_cycle.index + 1) % len(msg_r)
    return s_msg
msg_cycle.index = 0

#async def test():
#    print("Testing")
#    while True:
#        msg = await msg_cycle()
#        if len(msg) is not 0:
#            if angle is not int(msg[1]) or stren is not int(msg[2]):
#                angle = int(msg[1])
#                stren = int(msg[2])
#
#                has_changed = True
#
#                await asyncio.sleep(0.1)
#
#        await LED_Duty(angle,stren)

#async def Haptic():
#    print("Haptic On")
#    my_duty = None
#    while True:
#        r_msg = s.recv(13).decode()
#        msg = r_msg.split()
#        await asyncio.sleep(0)
#        if len(msg) is 4:
#            if msg[0] == 'START' and msg[3] == 'EOM':
#                if angle is not int(msg[1]) or stren is not int(msg[2]):
#                    angle = int(msg[1])
#                    stren = int(msg[2])
#
#                    has_changed = True
#
#                    await asyncio.sleep(0.1)
#        if not my_duty and (angle is not -1 or stren is not -1):
#            my_duty = asyncio.ensure_future(LED_Duty(angle,stren))
#        elif has_changed and my_duty:
#            has_changed = False
#            if not my_duty.cancelled():
#                my_duty.cancel()
#            else:
#                my_duty = None

# MAIN FUNCTION
n_ports = 20

print('Haptic Sensors Initialization')

for p in range(n_ports):
    print("init port: ", p)
    init_port(p)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = 'Meenakshis-MacBook-Pro.local'
port = int(input("Enter Port Number"))

print("Connecting")
while True:
    try:
        s.connect((host, port))
        print("Connected to ", host)
        break
    except KeyboardInterrupt:
        quit()
    except:
        print("Not Connected")
print("Past while loop")
count = 0

#loop = asyncio.get_event_loop()
#try:
#    asyncio.ensure_future(Haptic())
#    loop.run_until_complete(Haptic())
#finally:
#    loop.run_until_complete(loop.shutdown_asyncgens())
#    loop.close()
#
#if(not run_test.cancelled()):
#    print("Test is still running")

angle = -1
stren = -1
print("Entering new while loop")
while True:
    r_msg = s.recv(15).decode()
    msg = r_msg.split()

    print(msg)

    #t0 = time.time()
    #while (time.time() - t0 < 1):
    #   a = 5
    #msg = msg_cycle()

    if len(msg) is 4:
        if msg[0] == 'START' and msg[3] == 'EOM':
            print(count,"\n")
            print(msg[0])
            print("Angle: ", msg[1])
            print("Strength: ", msg[2])
            print(msg[3])

            #s_msg = "RECEIVED"
            #s.send(s_msg.encode())

            if angle is not int(msg[1]) or stren is not int(msg[2]):
                angle = int(msg[1])
                stren = int(msg[2])

                has_changed = True

                time.sleep(0.1)

    LED_Duty(angle,stren)


from typing import Tuple, List
from math import prod

def run(my_map: List[str], slope: Tuple = (3, 1), start: Tuple = (0, 0)) -> List:
    """
    The Tobbogan Slide function.
    Why did I do it with a recursion, I have no idea
    Also happy to have done the parameterisation of the slope in part 1.
    No rework needed in part 2
    """
    x, y = start
    right, down = slope
    height, wdth = len(my_map), len(my_map[0])

    new_x = (x + right) % wdth
    new_y = min(height - 1, (y + down))

    mark = [my_map[new_y][new_x]]

    if new_y >= height - 1:
        return mark
    else:
        mark += run(my_map, slope, start=(new_x, new_y))
        return mark

def get_map(fn: str = "toy") -> List[List[str]]:
    """
    Getting the map itself.
    Not sure if using a 2x2 list is actually useful as we can directly
    index the strings...
    """
    with open(f"../inputs/day03/{fn}inputs.txt", "r") as f:
        my_map = [list(x.strip()) for x in f.readlines()]
    return my_map

if __name__ == "__main__":
    my_map = get_map()
    assert my_map[0] == [".", ".", "#", "#", ".", ".", ".", ".", ".", ".", "."]

    toy = sum([1 for x in run(my_map) if x == "#"])
    assert toy == 7

    slopes_part2 = [
        (1, 1),
        (3, 1),
        (5, 1),
        (7, 1),
        (1, 2),
    ]

    vld = []
    for slp in slopes_part2:
        k = sum(1 for x in run(my_map, slope=slp) if x == "#")
        vld.append(k)

    assert vld == [2, 7, 3, 4, 2]

    ## Part 1
    my_map = get_map("puzzle")
    part1 = toy = sum([1 for x in run(my_map) if x == "#"])
    print("This many trees (Part 1): ", part1)

    # Part 2
    vld = {}
    for slp in slopes_part2:
        k = sum(1 for x in run(my_map, slope=slp) if x == "#")
        vld[slp] = k

    print("This many trees (Part 2): ", vld)
    print("Answer part 2: ", prod(vld.values()))


"""
Note data classes, plus submodules that operate on note data.
"""
from enum import Enum
from functools import reduce, total_ordering
from itertools import groupby
from io import StringIO
from math import gcd
from simfile.base import BaseChart
from typing import Iterable, Iterator, List, NamedTuple, Optional, Tuple, Type, Union

from ..timing import Beat
from ..types import Chart

__all__ = ["NoteType", "Note", "NoteData"]

class NoteType(Enum):
    """
    Known note types supported by StepMania.
    """

    TAP = "1"
    HOLD_HEAD = "2"
    TAIL = "3"
    ROLL_HEAD = "4"
    ATTACK = "A"
    FAKE = "F"
    KEYSOUND = "K"
    LIFT = "L"
    MINE = "M"

    def __str__(self):
        """Returns the character value of the note type."""
        return self.value

    def __repr__(self):
        return f"{self.__class__.__name__}.{self.name}"

@total_ordering
class Note(NamedTuple):
    """
    A note, corresponding to a nonzero character in a chart's note data.

    Note objects are intrinsically ordered according to their position in
    the underlying note data: that is, if `note1` would appear earlier in
    the note data string than `note2`, then `note1 < note2` is true.
    """

    beat: Beat
    column: int
    note_type: NoteType

    player: int = 0
    """
    Only used in routine charts. The second player's note data will have
    this value set to 1.
    """

    keysound_index: Optional[int] = None
    """
    Only used in keysounded SSC charts. Notes followed by a number in square
    brackets will have this value set to the bracketed number.
    """

    def _comparable(self) -> Tuple[int, Beat, int]:
        return (self.player, self.beat, self.column)

    def __lt__(self, other) -> bool:
        # bool(...) wrapper to satisfy mypy
        return bool(self._comparable() < other._comparable())

    def __str__(self):
        """
        Returns the note string as it would appear in note data.

        Includes the note type's character, followed by a bracketed keysound
        index if present.
        """
        note_string = str(self.note_type)
        if self.keysound_index is not None:
            note_string += f"[{self.keysound_index}]"
        return note_string

    def __repr__(self):
        return (
            f"{self.__class__.__name__}("
            + ", ".join(
                filter(
                    None,
                    (
                        f"beat={repr(self.beat)}",
                        f"column={self.column}",
                        f"note_type={repr(self.note_type)}",
                        f"player={self.player}" if self.player != 0 else None,
                        f"keysound_index={self.keysound_index}"
                        if self.keysound_index is not None
                        else None,
                    ),
                )
            )
            + ")"
        )

class NoteData:
    """
    Wrapper for note data with iteration & serialization capabilities.

    The constructor accepts a string of note data, any :data:`.Chart`, or
    another :class:`NoteData` instance.
    """

    _notedata: str
    _columns: int

    @property
    def columns(self):
        """How many note columns this chart has."""
        return self._columns

    def __init__(self, source: Union[str, Chart, "NoteData"]):
        if isinstance(source, str):
            self._notedata = source
        elif isinstance(source, BaseChart):
            if source.notes is None:
                raise ValueError("chart has no notes")
            self._notedata = source.notes
        elif isinstance(source, NoteData):
            self._notedata = source._notedata
        else:
            raise TypeError("expected str, Chart, or NoteData")

        self._columns = NoteData._get_columns(self._notedata)

    @staticmethod
    def _get_columns(notes: str):
        first_comma = notes.find(",")
        first_measure = notes[:first_comma] if first_comma > 0 else notes
        first_line = first_measure.strip().splitlines()[0].strip()
        first_line = NoteData._extract_keysound_indices(first_line)
        return len(first_line)

    @classmethod
    def from_notes(
        cls: Type["NoteData"], notes: Iterable[Note], columns: int
    ) -> "NoteData":
        """
        Convert a stream of notes into note data.

        This method assumes the following preconditions:

        * The input notes are naturally sorted.
        * Every note's beat is nonnegative.
        * Every note's column is nonnegative and less than `columns`.

        Note that this method doesn't quantize beats to 192nd ticks,
        and off-grid notes may result in measures with more rows than
        the StepMania editor would produce. StepMania will quantize
        these notes gracefully during gameplay, but you can apply
        :meth:`.Beat.round_to_tick` to each note's beat
        if you'd prefer to keep the note data tidy.
        """
        notedata = StringIO()

        # write a row and trailing newline to the notedata
        def push_row(row: List[Note] = []):
            note_strings = ["0"] * columns
            for note in row:
                note_strings[note.column] = str(note)
            notedata.write("".join(note_strings))
            notedata.write("\n")

        # write a measure to the notedata (no commas or newlines of its own)
        def push_measure(measure: List[Note] = []):
            # get all beat quantizations from this measure
            quantizations = map(lambda note: note.beat.denominator, measure)
            # find the least common multiple of these quantizations
            q = reduce(lambda a, b: a * b // gcd(a, b), quantizations, 1)

            # group notes by row
            # the expression `note.beat % 4 * q` should always resolve to an
            # integer because `q` is a multiple of every beat's denominator
            last_row = -1
            for r, row in groupby(measure, lambda note: int(note.beat % 4 * q)):
                # account for any skipped beats
                for _ in range(last_row + 1, r):
                    push_row()
                push_row(list(row))
                last_row = r
            # account for any trailing empty rows
            for _ in range(last_row + 1, q * 4):
                push_row()

        # group notes by player (for routine charts)
        last_player = -1
        for p, player_notes in groupby(notes, lambda n: n.player):
            if p > last_player:
                if last_player > -1:
                    notedata.write("&\n")
                # account for any skipped players
                for _ in range(last_player + 1, p):
                    push_measure()
                    notedata.write("&\n")
                last_player = p

            # group notes by measure
            last_measure = -1
            for m, measure in groupby(player_notes, lambda n: n.beat // 4):
                # handling the comma at the start of the loop instead of the end
                # avoids needing to know when we've reached the last measure
                if last_measure > -1:
                    notedata.write(",\n")
                # account for any skipped measures
                for _ in range(last_measure + 1, m):
                    push_measure()
                    notedata.write(",\n")
                push_measure(list(measure))
                last_measure = m

            # if there were no notes at all, write a blank measure
            if last_measure == -1:
                push_measure()

        return cls(notedata.getvalue())

    # Returns the line without keysound indices and optionally populates the
    # provided list with the indices
    @staticmethod
    def _extract_keysound_indices(
        line: str,
        keysound_indices: Optional[List[Optional[int]]] = None,
    ) -> str:
        while "[" in line:
            opening_bracket = line.index("[")
            closing_bracket = line.index("]")
            keysound_index = int(line[opening_bracket + 1 : closing_bracket])
            # As long as there are no earlier brackets, the string index of
            # the opening bracket is always 1 greater than its note column
            if keysound_indices is not None:
                keysound_indices[opening_bracket - 1] = keysound_index
            # To maintain the invariant described above (and to construct
            # the un-keysounded line), remove the bracket pair & number
            line = line[:opening_bracket] + line[closing_bracket + 1 :]
        return line

    def _iter_measure(
        self,
        p: int,  # player index
        m: int,  # measure index
        measure: str,  # the measure, stripped of whitespace
    ) -> Iterator[Note]:
        lines = measure.splitlines()
        subdivision = len(lines)

        for l, line in enumerate(lines):
            line = line.strip()
            keysound_indices: List[Optional[int]] = [None] * self._columns
            line = NoteData._extract_keysound_indices(line, keysound_indices)

            for c, column in enumerate(line):
                if column != "0":
                    yield Note(
                        beat=Beat(m * 4 * subdivision + l * 4, subdivision),
                        column=c,
                        note_type=NoteType(column),
                        player=p,
                        keysound_index=keysound_indices[c],
                    )

    def __iter__(self) -> Iterator[Note]:
        """
        Iterate over the notes in the note data.

        Notes are yielded chronologically (ascending beats) first, then
        in ascending column order (same as the serialized order).
        """
        # "Routine" steps types (currently dance-routine and pump-routine) use
        # an & marker to separate the two players' steps. All other steps types
        # do not use an &, so `p` will only be 0 the vast majority of the time
        # TODO: str.split is space-inefficient - consider alternatives
        for p, notedata in enumerate(self._notedata.split("&")):
            for m, measure in enumerate(notedata.split(",")):
                yield from self._iter_measure(p, m, measure.strip())

    def __str__(self) -> str:
        """Returns the note data string."""
        return self._notedata


import sys
input = sys.stdin.readline

T = int(input())
for _ in range(T):
    N = int(input())
    appli = [list(map(int,input().rstrip().split(" "))) for _ in range(N)]
    appli = sorted(appli, key=lambda x: x[1])
    ans = 1
    minor = appli[0][0]
    for i in range(1,N):
        minor = min(minor,appli[i-1][0])
        if minor > appli[i][0]:
            ans += 1
            minor = appli[i][0]
    print(ans)


#!/usr/bin/env python3

import random
import argparse
import requests

def main():
    parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument('-n', type=int, help="Number of words (max: 10000)",
                        metavar='num', default=1000, choices=range(10, 10000))
    parser.add_argument('-r', nargs=2, type=int, help="Range of random numbers",
                        default=[0, 100], metavar=('a', 'b'))
    parser.add_argument('-f', type=str, help="Write generated words to `filename`",
                        metavar='filename', default="input/text.txt")

    args = parser.parse_args()
    a, b = args.r

    word_site = "https://www.mit.edu/~ecprice/wordlist.10000"

    response = requests.get(word_site)
    words = response.content.decode('utf-8').split()
    random.shuffle(words)

    # make words repeat
    words = words[:int(args.n / 10)]

    with open(args.f, 'w') as file:
        for i in range(args.n):
            file.write(f'{random.choice(words)};{random.randint(a, b)}\n')

if __name__ == "__main__":
    main()


# -*- coding:utf-8 -*-
#@Time : 2022/3/30 12:18
#@Author: oliverchen
#@File : TwoSum.py
#@Describe: 给定一个整数数组 nums 和一个整数目标值 target，
#           请你在该数组中找出 和为目标值 target 的那两个整数，并返回它们的数组下标

#导入限定方法参数类型
from typing import List
class TwoSum:
    def twoSum(self,nums: List[int], target: int) -> List[int]:
        hash_table = dict()#哈希表
        for i,value in enumerate(nums):
            a = target - value
            if a in hash_table:
                return [hash_table[a],i]
            hash_table[nums[i]]=i
        return []

if __name__ == '__main__':
    nums = [2,7,11,15]
    target = 9
    L = TwoSum.twoSum(TwoSum,nums,target)
    print(L)


import torch

# normalization, pointwise gaussian
class UnitGaussianNormalizer(object):
    def __init__(self, x, eps=0.00001):
        super(UnitGaussianNormalizer, self).__init__()

        # x could be in shape of ntrain*n or ntrain*T*n or ntrain*n*T
        self.mean = torch.mean(x, 0)
        self.std = torch.std(x, 0)
        self.eps = eps

    def encode(self, x):
        x = (x - self.mean) / (self.std + self.eps)
        return x

    def decode(self, x, sample_idx=None):
        if sample_idx is None:
            std = self.std + self.eps # n
            mean = self.mean
        else:
            if len(self.mean.shape) == len(sample_idx[0].shape):
                std = self.std[sample_idx] + self.eps  # batch*n
                mean = self.mean[sample_idx]
            if len(self.mean.shape) > len(sample_idx[0].shape):
                std = self.std[:,sample_idx]+ self.eps # T*batch*n
                mean = self.mean[:,sample_idx]

        # x is in shape of batch*n or T*batch*n
        x = (x * std) + mean
        return x

    def cuda(self):
        self.mean = self.mean.cuda()
        self.std = self.std.cuda()

    def cpu(self):
        self.mean = self.mean.cpu()
        self.std = self.std.cpu()