# for path related functionalities
from firebase_admin import credentials, storage, initialize_app
import firebase_admin
from bson.objectid import ObjectId
import pickle
from flask import json, jsonify, make_response
from auth_routes import auth_required
from route_config import *
import urllib.request
from skimage import io
import keras
import random
import shutil
import numpy as np
import tensorflow as tf
import colorsys
import skimage
import argparse
import uuid
import cv2
import os
import sys

ROOT_DIR = os.path.abspath('/Users/matthewdev/CodingProjects/ECE188/tailor-made-model-server/Mask_RCNN-master/Mask_RCNN-master')
# Import Mask RCNN
sys.path.append(ROOT_DIR)  # To find local version of the library
from mrcnn.model import MaskRCNN
import mrcnn.model as modellib
from mrcnn.config import Config
from mrcnn import model as modellib
from mrcnn import utils

# firebase imports
cred = credentials.Certificate(
    "/Users/matthewdev/CodingProjects/ECE188/tailor-made-model-server/firebaseCred.json")
default_app = initialize_app(
    cred, {'databaseURL': 'tailor-made-ece188.appspot.com'})
print(default_app.name)

class TestConfig(Config):
    NAME = "Deepfashion2"
    GPU_COUNT = 1
    IMAGES_PER_GPU = 1
    NUM_CLASSES = 1 + 13

model = modellib.MaskRCNN(mode="inference", config=TestConfig(), model_dir="/Users/matthewdev/CodingProjects/ECE188/tailor-made-model-server/")
model.load_weights("./mask_rcnn_deepfashion2.h5", by_name=True)

# helper fns

# def resize_image(image):
#     # scale the image
#     image = tf.cast(image, tf.float32)
#     image = image/255.0
#     # resize image
#     image = tf.image.resize(image, (128, 128))
#     return image

class_names = ['short_sleeved_shirt', 'long_sleeved_shirt', 'short_sleeved_outwear', 'long_sleeved_outwear', 'vest', 'sling',
               'shorts', 'pants', 'skirt_or_pants', 'short_sleeved_dress', 'long_sleeved_dress',
               'vest_dress', 'sling_dress', '']

def random_colors(N):
    np.random.seed(1)
    colors = [tuple(255 * np.random.rand(3)) for _ in range(N)]
    return colors

colors = random_colors(len(class_names))
class_dict = {
    name: color for name, color in zip(class_names, colors)
}

def apply_mask(image, mask, color, alpha=0.5):
    """apply mask to image"""
    for n, c in enumerate(color):
        image[:, :, n] = np.where(
            mask == 1,
            image[:, :, n] * (1 - alpha) + alpha * c,
            image[:, :, n]
        )
    return image

def display_instances(image, boxes, masks, ids, names, scores):
    cropped_images = []
    image_to_crop = image.copy()
    n_instances = boxes.shape[0]
    print("no of detections in frame :", n_instances)
    if not n_instances:
        print('NO INSTANCES TO DISPLAY')
    else:
        assert boxes.shape[0] == masks.shape[-1] == ids.shape[0]
    obj_list = []
    for i in range(n_instances):
        if not np.any(boxes[i]):
            continue
        y1, x1, y2, x2 = boxes[i]
        label = names[ids[i]]
        color = class_dict[label]
        score = scores[i] if scores is not None else None
        caption = '{} {:.2f}'.format(label, score) if score else label
        random_name = str(uuid.uuid4())
        mask = masks[:, :, i]
        obj_list.append({
            'score': int(score * 100),
            'label': label
        })

        cropped_images.append(image_to_crop[y1:y2, x1:x2])

        image = apply_mask(image, mask, color)
        image = cv2.rectangle(image, (x1, y1), (x2, y2), color, 2)
        image = cv2.putText(image, caption, (x1, y1),
                            cv2.FONT_HERSHEY_DUPLEX, 0.7, color, 2)

    return image, cropped_images, obj_list

@app.route("/classifyImage", methods=['POST'])
@auth_required
def predictImage(uid):
    # image_url = ""
    image_name = ""
    if request.is_json:
        try:
            json_data = request.get_json()
            image_name = json_data['image_name']
        except:
            return make_response(jsonify({"message": "Error, must include image name"}), 400)
    objID = ObjectId(uid)
    if not objID:
        return make_response(jsonify({'message': 'missing uid'}), 400)
    image = db.images.find_one_or_404({"uid": objID, "image_name": image_name})
    image_url=""
    try:
        image_url = image["uploaded_image"]
    except:
        return make_response(jsonify({'message': 'image missing url'}), 400)
    urllib.request.urlretrieve(image_url, "transferImage.jpg")
    frame = cv2.imread("./transferImage.jpg")
    # print("FRAME")
    # print(frame)
    results = model.detect([frame], verbose=0)
    r = results[0]
    masked_image, cropped_images, confidences = display_instances(
        frame, r['rois'], r['masks'], r['class_ids'], class_names, r['scores'])
    # masked_image = np.array(masked_image)
    # print(masked_image)
    # cv2.imshow('',masked_image)
    cv2.imwrite("output.jpg", masked_image)
    bucket = storage.bucket("tailor-made-ece188.appspot.com")
    objId = ObjectId(uid)
    user = db.users.find_one_or_404({"_id": objId})
    username = user['username']
    blob = bucket.blob("images/" + username + "/" + image_name + "_classified")
    blob.upload_from_filename("output.jpg")
    # Opt : if you want to make public access from the URL
    blob.make_public()

    print("your file url", blob.public_url)
    public_url = blob.public_url
    prev_image = db.images.find_one_and_update(
        {"uid": objID, "image_name": image_name},
         {'$set': {"segmented_image": public_url, "confidences": confidences } }
    )

    return make_response(jsonify({"image_url": blob.public_url}), 200)

# def classify(uid):
#     url = ""
#     image_name = ""
#     if request.is_json:
#         try:
#             json_data = request.get_json()
#             url = json_data['image_url']
#             image_name = json_data['image_name']

#         except:
#             return make_response(jsonify({"message": "Error, must include image url and name"}), 400)

#     url2 = url

#     url_img = Image.open(requests.get(url2, stream=True).raw)
#     convert_im=transforms.ToTensor()
#     # img = convert_im(url_img)

#     # file_name='/content/test1.jpg'
#     # im = Image.open(file_name, mode='r')
#     # im
#     # file = tf.io.read_file(file_name)
#     #    decode png file into a tensor

#     img=tf.image.decode_jpeg(requests.get(url2).content, channels=3, name="jpeg_reader")
#     # img = tf.image.decode_png(file, channels=3, dtype=tf.uint8)
#     print(img.shape)
#     x,y,z=img.shape
#     x_scale = x/128
#     y_scale = y/128
#     new_img = resize_image(img)
#     # plt.imshow(new_img)
#     # print(new_img.shape)
#     pred = unet(new_img[None])
#     temp=0
#     for i in pred:
#         temp = np.squeeze(pred[0])
#         temp = tf.argmax(pred[0], axis=-1)
#         temp=np.squeeze(temp)
#         # plt.imshow(temp)
#         cv2.imwrite("output.png", temp)

#     # pred = tf.image.convert_image_dtype(i/255.0, dtype=tf.uint8)

#     # im = Image.fromarray(pred)
#     # im.save("your_file.jpeg")
#     bucket = storage.bucket("tailor-made-ece188.appspot.com")
#     objId = ObjectId(uid)
#     user = db.users.find_one_or_404({"_id" : objId })
#     username = user['username']
#     blob = bucket.blob("images/" + username + "/" + image_name +"_classified")
#     blob.upload_from_filename("output.png")
#     # Opt : if you want to make public access from the URL
#     blob.make_public()

#     print("your file url", blob.public_url)
#     public_url = blob.public_url
#     # requests.post('https://tailor-made-ece188.herokuapp.com/addSegmentedImage', headers=)
#     return make_response(jsonify({"image_url": blob.public_url}), 200)

    # k = 0
    # colors=[]
    # min_x=np.ones(60)*128
    # max_x=np.zeros(60)
    # min_y=np.ones(60)*128
    # max_y=np.zeros(60)
    # color_count=np.zeros(60)

    # for i in pred:

    # save image

    # plot the predicted mask
    # plt.subplot(4,3,1+k*3)
    # i = tf.argmax(i, axis=-1)
    # plt.imshow(np.squeeze(i),cmap='jet', norm=NORM)

    # plt.axis('off')
    # plt.title('Prediction')
    # print(i)
    # arr = i.numpy()
    # x,y=arr.shape
    # for i in range(x):
    # for j in range(y):
    #     k = arr[i,j]
    #     if (k != 0):
    #     color_count[k]+=1
    #     if k not in colors:
    #     colors.append(k)
    #     if(i>max_x[k]):
    #     max_x[k]=i
    #     if(j>max_y[k]):
    #     max_y[k]=j
    #     if(i<min_x[k]):
    #     min_x[k]=i
    #     if(j<min_y[k]):
    #     min_y[k]=j
    # print(colors)
    # # plot the actual image
    # plt.subplot(4,3,2+k*3)
    # plt.imshow(np.squeeze(new_img))
    # plt.axis('off')
    # plt.title('Actual Image')
    #     k += 1
    #     if k == 4: break
    # plt.suptitle('Predition After 150 Epochs (By Fine-tuning from 51th Epoch)', color='red', size=20)
    # plt.show()


import os
import uuid
from datetime import datetime

from airflow import DAG
from airflow.providers.yandex.operators.yandexcloud_dataproc import (
    DataprocCreateClusterOperator,
    DataprocCreateHiveJobOperator,
    DataprocCreateMapReduceJobOperator,
    DataprocCreatePysparkJobOperator,
    DataprocCreateSparkJobOperator,
    DataprocDeleteClusterOperator,
)
AVAILABILITY_ZONE_ID = 'ru-central1-b'
S3_BUCKET_NAME_FOR_JOB_LOGS = 'jupiter-app-test-storage'

with DAG(
    'hive_job_test',
    schedule_interval=None,
    start_date=datetime(2021, 1, 1),
    tags=['example'],
) as dag:
    create_hive_query = DataprocCreateHiveJobOperator(
        task_id='create_hive_query',
        cluster_id='c9qc9m3jccl8v7vigq10',
        query='SELECT 1;',
    )

    create_hive_query_from_file = DataprocCreateHiveJobOperator(
        task_id='create_hive_query_from_file',
        cluster_id='c9qc9m3jccl8v7vigq10',
        query='insert into monitoring_output select * from  monitoring_output',
#         script_variables={
#             'CITIES_URI': 's3a://data-proc-public/jobs/sources/hive-001/cities/',
#             'COUNTRY_CODE': 'RU',
#         },
    )


from typing import List
from src.lib.DoublyLinkedList import DoublyLinkedList
from src.lib.PageFaultException import PageFaultException

def lru(in_: List[str]) -> int:
    """
    @param  int in_ lista de paginas referenciadas

    @return int numero de pagefaults
    """

    faults = 0
    l = DoublyLinkedList()

    for page in in_:
        try:
            l.push(page)
        except PageFaultException:
            faults += 1

    return faults


from __future__ import annotations
from abc import ABC, abstractmethod

from model import (
    MakePuzzle,
    StateStorage
)
from model.puzzle import Puzzle
from model.hint import hint
from model.output import Output
from model import highScore

outty = Output.getInstance()

class Command(ABC):

    @abstractmethod
    def __init__(self) -> None:
        self._name = None
        self._description = None

    @abstractmethod
    def execute(self) -> None:
        pass

    def get_name(self) -> str:
        return self._name

    def get_description(self) -> str:
        return self._description

# Concrete Commands:
##############################################################################
# class NewGame(Command):
#
# DESCRIPTION:
#   Executes the required code in model to create a new puzzle object.
# ARGUMENTS:
#
# ATTRIBUTES:
#
# FUNCTIONS:
#
###############################################################################
class NewGame(Command):
    def __init__(self,
                 base: str = '',
                 keyLett: str = '') -> None:
        self._name = '!new'
        self._description = (
            'Generates a new puzzle from a base word with exactly 7 unique'
            'characters or an auto-generated base word.'
        )
        self._base = base
        self._keyLett = keyLett

    # Executes defined function
    def execute(self) -> Puzzle:
        puzzle = MakePuzzle.newPuzzle(
            baseWord=self._base,
            keyLetter=self._keyLett,
            flag=False
        )
        if puzzle is not None:
            puzzle.shuffleChars()
        return puzzle

###############################################################################
# class SaveGame(Command)
#
# DESCRIPTION:
#
# ARGUMENTS:
#
# ATTRIBUTES:
#
# FUNCTIONS:
#
###############################################################################
class SaveGame(Command):
    def __init__(
        self,
        puzzle: Puzzle,
        filePath: str,
        onlyPuzz: bool,
        encrypt: bool
    ) -> None:
        # params
        self._puzzle = puzzle
        self._filePath = filePath
        self._onlyPuzz = onlyPuzz
        self._encrypt = encrypt

    def execute(self) -> None:
        if self._encrypt:
            strat = StateStorage.Saver(StateStorage.encryptedSaveStrategy())
            strat.executeStrategy(
                self._filePath,
                self._puzzle,
                self._onlyPuzz
            )
        else:
            strat = StateStorage.Saver(StateStorage.savePuzzleStrategy())
            strat.executeStrategy(
                self._filePath,
                self._puzzle,
                self._onlyPuzz
            )

###############################################################################
# class LoadGame(Command)
#
# DESCRIPTION:
#
# ARGUMENTS:
#
# ATTRIBUTES:
#
# FUNCTIONS:
#
###############################################################################
class LoadGame(Command):
    def __init__(self, filePath: str) -> None:
        # params
        self._filePath = filePath

    def execute(self) -> object:
        return StateStorage.load(self._filePath)

###############################################################################
# class Shuffle(Command)
#
# DESCRIPTION:
#
# ARGUMENTS:
#
# ATTRIBUTES:
#
# FUNCTIONS:
#
###############################################################################
class Shuffle(Command):
    def __init__(self, receiver: Puzzle) -> None:
        self._name = '!shuffle'
        self._description = (
            'Shuffle the order of the active puzzle for a fresh view'
        )
        self._receiver = receiver

    def execute(self) -> None:
        self._receiver.shuffleChars()

###############################################################################
# class Hint(Command):
#
# DESCRIPTION:
#
# ARGUMENTS:
#
# ATTRIBUTES:
#
# FUNCTIONS:
#
###############################################################################
class Hint(Command):
    def __init__(self, puzzle: object) -> None:
        self._name = '!hint'
        self._description = (
            "Show show data from the current game to help user make a guess"
        )

        # params
        self._puzzle = puzzle

    def execute(self) -> dict:
        hints = hint(self._puzzle)
        hints.makeHintGrid(self._puzzle)
        hints.twoLetterList(self._puzzle)

        shuffleLetts = self._puzzle.getShuffleLetters()
        keyLett = shuffleLetts[0].upper()
        rest = ' '.join(shuffleLetts[1: len(shuffleLetts)]).upper()

        return {
            'letters': f'\u0332{keyLett}\u0332 {rest}',
            'numWords': hints.countWords(self._puzzle),
            'points': self._puzzle.maxScore,
            'numPan': hints.numPangrams(self._puzzle),
            'numPerf': hints.numPerfectPangram(self._puzzle),
            'bingo': self._puzzle.checkBingo(),
            'matrix': hints.getHintGrid(),
            'twoLetLst': hints.getTwoLetterList()
        }

###############################################################################
# class Guess(Command)
#
# DESCRIPTION:
#   Submits a guess to the model
#
# ARGUMENTS:
#   puzzle: Puzzle
#       the object representing the currently running game
#   word: str
#       the word to be submitted as a guess
#   outty: object
#       the output object
#
# FUNCTIONS:
#   execute() -> None:
#       exectutes the attached function call to make a guess
###############################################################################
class Guess(Command):
    def __init__(self, puzzle: Puzzle, word: str) -> None:
        self._name = '!guess'
        self._description = 'description pending'

        # params
        self._puzzle = puzzle
        self._word = word

    def execute(self) -> None:
        MakePuzzle.guess(
            puzzle=self._puzzle,
            input=self._word,
            flag=False
        )

###############################################################################
# class Leaderboard(Command)
#
# DESCRIPTION
#   returns the leaderboard for this game
###############################################################################
class Leaderboard(Command):
    def __init__(self, puzzle: Puzzle) -> None:
        self._puzzle = puzzle

    def execute(self) -> list[tuple]:
        # grab hS
        # format to list of [(name, rank, score)]
        lst = highScore.getHighScore(
            self._puzzle.getUniqueLetters(),
            self._puzzle.getKeyLetter()
        )
        lb = []
        for row in lst:
            lb.append((row[1], row[2], row[3]))

        return lb

###############################################################################
# SaveScore(name: str, puzzle: Puzzle)
#
# DESCRIPTION
#   adds a new high score to the database
###############################################################################
class SaveScore(Command):
    def __init__(self, name: str, puzzle: Puzzle) -> None:
        self._name = name
        self._rank = puzzle.getRank()
        self._score = puzzle.getScore()
        self._uniqueLett = puzzle.getUniqueLetters()
        self._keyLett = puzzle.getKeyLetter()

    def execute(self) -> None:
        highScore.qualify(
            self._name,
            self._rank,
            self._score,
            self._uniqueLett,
            self._keyLett
        )


import numpy as np
import os

#초기 gis data 불러오고 처리하는 작업을 행렬 shape가 (x, y) 형태여서,
#일반적인 형태(y,x)로 변환해주는 함수를 사용함
def convert_axis(mat):
  """
  (x,y), x축이 커지는 방향 : 오른쪽 / y축이 커지는 방향 : 위쪽
  인 행렬을
  (y,x), x축이 커지는 방향 : 오른쪽 / y축이 커지는 방향 : 아래쪽(일반적인 2차원 행렬/이미지 형태)
  로 바꿈
  """
  reverse = np.transpose(mat, [1,0])
  reverse = reverse[::-1, :]
  return reverse

def convert_axis_reverse(mat):
  """
  convert_axis의 반대로 동작
  """
  reverse = np.transpose(mat, [1,0])
  reverse = reverse[:, ::-1]
  return reverse

##### 범위 체크 함수 #####
def range_check(r,c,shape):
  return r >= 0 and r < shape[0] and c >= 0 and c < shape[1]

##### 이웃셀 값 바로 얻어오는 함수 #####
#bitmask : 0bxxxx, 8/4/2/1 순서대로 W/A/S/D(북/서/남/동)
def get_neighboor(mat, r, c, bitmask):
  result = []
  add_r = [-1, 0, 1, 0]
  add_c = [0, -1, 0, 1]
  use_dir = [bitmask & 0b1000, bitmask & 0b0100, bitmask & 0b0010, bitmask & 0b0001]
  for i in range(4):
    if use_dir[i]:
      target_r = r + add_r[i]
      target_c = c + add_c[i]
      if range_check(target_r, target_c, mat.shape):
        result += [mat[target_r, target_c]]
      else:
        result += [None]
  return result

  ##### 이웃셀 값 바로 얻어오는 함수 8방향 #####
#bitmask : 0bxxxxxxxx, 왼쪽부터 순서대로 북/북서/서/서남/남/남동/동/동북(북 부터 반시계 회전)
def get_neighboor8(mat, r, c, bitmask):
  result = []
  add_r = [-1, -1, 0, 1, 1, 1, 0, -1]
  add_c = [0, -1, -1, -1, 0, 1, 1, 1]
  use_dir = [bitmask & (1 << i) for i in range(8)]
  for i in range(8):
    if use_dir[i]:
      target_r = r + add_r[i]
      target_c = c + add_c[i]
      if range_check(target_r, target_c, mat.shape):
        result += [mat[target_r, target_c]]
      else:
        result += [None]
  return result

def get_coastline_cells(mat):
  result = set()
  for r in range(mat.shape[0]):
    for c in range(mat.shape[1]):
      if mat[r,c]["state"] == "ground":
        #지상 셀일 경우, 이웃을 다 가져와 바다 셀이 있는지 확인함.
        neighboors = get_neighboor(mat, r, c, 0b1111)
        flag = False
        for neighboor in neighboors:
          if neighboor is not None:
            if neighboor["state"] == "sea":
              flag = True
        if flag:
          result.add((r,c))

  return result

def save_matrix(filepath, mat):
  try:
    np.save(f"{filepath}", mat)
  except Exception as e:
    return False, f"save matrix : save failed : {e}"
  return True, None

def load_matrix(filepath):
  try:
    mat = np.load(f'{filepath}', allow_pickle=True)
  except Exception as e:
    return False, f"load matrix : load failed : {e}"
  return True, mat

def save_inited_matrix(dir, mat, params, coastlines):
  try:
    #디렉토리 확인 후 생성
    if not os.path.isdir(f'{dir}'):
      os.makedirs(f'{dir}')
    np.save(f"{dir}/mat", mat)
    np.save(f"{dir}/params", [params])
    np.save(f"{dir}/coastlines", [coastlines])
  except Exception as e:
    return False, f"save inited matrix : save failed : {e}"
  return True, None

def load_inited_matrix(dir):
  try:
    mat = np.load(f'{dir}/mat.npy', allow_pickle=True)
    params = np.load(f'{dir}/params.npy', allow_pickle=True)[0]
    coastlines = np.load(f'{dir}/coastlines.npy', allow_pickle=True)[0]
  except Exception as e:
    return False, f"load inited matrix : load failed : {e}"
  return True, (mat, params, coastlines)


import os
from Jumpscale import j

from .RDBClient import RDBClient

#
JSBASE = j.baseclasses.object

class RDBFactory(j.baseclasses.object):
    __jslocation__ = "j.clients.rdb"

    def _init(self):
        self._children = j.baseclasses.dict()

    def client_get(self, bcdbname=None, addr="localhost", port=6379, secret=None):
        """
        :param bcdbname: bcdbname name
        :return:
        """
        assert bcdbname
        key = "%s_%s_%s" % (bcdbname, addr, port)
        if key not in self._children:
            self._children[key] = RDBClient(bcdbname=bcdbname, addr=addr, port=port, secret=secret)
        return self._children[key]

    def reset(self):
        def delete(db):
            itemstodel = ["queue:*", "rdb*", "myjobs*"]
            for item in itemstodel:
                for key in db.keys(item):
                    db.delete(key)

        delete(j.clients.redis.core)
        for item in self._children.values():
            item.flush()

    def test(self):
        """
        kosmos 'j.clients.rdb.test()'

        """
        cl = self.client_get("test")
        cl.flush()
        assert cl.count == 0
        assert len(cl.list()) == 0

        id = cl.set(b"INIT")
        assert id == 0
        assert cl.get(0) == b"INIT"

        nr = cl.count
        assert nr == 1
        # do test to see that we can compare
        id = cl.set(b"r")
        assert id == 1
        assert cl.get(id) == b"r"

        id2 = cl.set(b"b")
        assert id2 == 2

        assert cl.set(b"r", key=id) is None
        assert cl.set(b"rss", key=id) == 1  # changed the data, returns id 1

        nr = cl.count
        assert nr == 3  # nr of real data inside

        # test the list function
        assert cl.list() == [0, 1, 2]
        assert cl.list(2) == [2]
        assert cl.list(0) == [0, 1, 2]

        result = {}
        for id, data in cl.iterate():
            if id == 0:
                continue
            self._log_debug("%s:%s" % (id, data))
            result[id] = data

        assert {1: b"rss", 2: b"b"} == result

        assert cl.list(key_start=id2)[0] == id2

        assert cl.exists(id2)

        self._log_debug("write 10000 entries")

        def dumpdata(self):

            inputs = {}
            for i in range(1000):
                data = os.urandom(4096)
                key = cl.set(data)
                inputs[key] = data

            for k, expected in inputs.items():
                actual = cl.get(k)
                if expected != actual:
                    j.shell()
                assert expected == actual

        dumpdata(self)  # is in default bcdbname

        self._log_debug("count:%s" % cl.count)

        bcdbname = "newbcdbname"
        ns = self.client_get(bcdbname)
        ns.flush()
        assert ns.nsinfo["entries"] == 0

        # both should be same
        id = ns.set(b"a")
        assert ns.get(id) == b"a"
        assert ns.nsinfo["entries"] == 1

        nritems = 1000
        j.tools.timer.start("rdb")

        self._log_debug("perftest for 10.000 records, should get above 5k per sec, +10k expected")
        for i in range(nritems):
            id = cl.set(b"a")

        res = j.tools.timer.stop(nritems)

        assert res > 3000

        self._log_info("PERF TEST SEQ OK")

        cl.flush()
        ns.flush()

        return "OK"


import unittest
import day_22

class testDay22(unittest.TestCase):
    def test_part_1(self):
        # Given
        test_filepath = "test_file.txt"
        # When
        result = day_22.part_1(test_filepath)
        # Then
        self.assertEqual(result, 306)

    def test_parse_inputs(self):
        # Given
        test_filepath = "test_file.txt"
        # When
        player_1_deck, player_2_deck = day_22.parse_inputs(test_filepath)
        # Then
        self.assertEqual(player_1_deck, [9, 2, 6, 3, 1])
        self.assertEqual(player_2_deck, [5, 8, 4, 7, 10])

    def test_play_one_turn(self):
        # Given
        test_filepath = "test_file.txt"
        player_1_deck, player_2_deck = day_22.parse_inputs(test_filepath)
        # When
        player_1_deck_after_1_turn, player_2_deck_after_1_turn = \
            day_22.play_one_turn_part_1(player_1_deck, player_2_deck)
        player_1_deck_after_2_turn, player_2_deck_after_2_turn = \
            day_22.play_one_turn_part_1(player_1_deck_after_1_turn,
                                        player_2_deck_after_1_turn)
        # Then
        self.assertEqual(player_1_deck_after_1_turn, [2, 6, 3, 1, 9, 5])
        self.assertEqual(player_2_deck_after_1_turn, [8, 4, 7, 10])
        self.assertEqual(player_1_deck_after_2_turn, [6, 3, 1, 9, 5])
        self.assertEqual(player_2_deck_after_2_turn, [4, 7, 10, 8, 2])

    def test_play_one_game(self):
        # Given
        test_filepath = "test_file.txt"
        player_1_deck, player_2_deck = day_22.parse_inputs(test_filepath)
        # When
        number_of_turns, winning_deck = day_22.play_one_game_part_1(
            player_1_deck, player_2_deck)
        # Then
        self.assertEqual(number_of_turns, 29)
        self.assertEqual(winning_deck, [3, 2, 10, 6, 8, 5, 9, 4, 7, 1])

    def test_calculate_score(self):
        # Given
        player_deck = [3, 2, 10, 6, 8, 5, 9, 4, 7, 1]
        # When
        score = day_22.calculate_score(player_deck)
        # Then
        self.assertEqual(score, 306)

    def test_part_2(self):
        # Given
        test_filepath = "test_file.txt"
        # When
        result = day_22.part_2(test_filepath)
        # Then
        self.assertEqual(result, 291)

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


# https://www.acmicpc.net/problem/1926
# BFS
# 37104KB, 652ms

from collections import deque
import sys
input = sys.stdin.readline

def bfs():
    global cnt
    while Q:
        r, c = Q.popleft()
        for k in range(4):
            nr = r + dr[k]
            nc = c + dc[k]
            if nr < 0 or nr >= N or nc < 0 or nc >= M: continue
            if picture[nr][nc] == 1 and visited[nr][nc] == 0:
                visited[nr][nc] = 1
                cnt += 1
                Q.append((nr, nc))
    ans.append(cnt)

N, M = map(int, input().split())
picture = [list(map(int, input().split())) for _ in range(N)]
visited = [[0] * M for _ in range(N)]
dr = [-1, 0, 1, 0]
dc = [0, 1, 0, -1]
ans = []
Q = deque()
for i in range(N):
    for j in range(M):
        if picture[i][j] == 1 and visited[i][j] == 0:
           visited[i][j] = 1
           Q.append((i, j))
           cnt = 1
           bfs()

if len(ans):
    print(len(ans))
    print(sorted(ans)[-1])
else:   # 없는 경우 처리하기!! -> 없으면 런타임에러 발생
    print(0)
    print(0)


from __future__ import unicode_literals

from django import forms
from django.conf import settings
from django.utils.translation import ugettext_lazy as _

from shuup.admin.forms.widgets import TextEditorWidget
from shuup.notify.actions import SendEmail
from shuup.notify.script import Step, StepNext
from shuup.notify.script_template import BaseScriptTemplate
from shuup.utils.form_group import FormGroup

class GenericScriptTemplateEmailContentForm(forms.Form):
    """
    Generic form which contains the content of a email: subject and body.
    """

    subject = forms.CharField(label=_("Subject"), help_text=_("The subject of the email"))
    body = forms.CharField(label=_("Email content"), widget=TextEditorWidget, help_text=_("The content of the email."))

class GenericScriptTemplateEmailForm(forms.Form):
    """
    Generic form which contains a destination of the email.
    """

    SEND_TO_CHOICES = [
        ("customer", _("Customer")),
        ("other", _("Other destination")),
    ]
    send_to = forms.ChoiceField(
        label=_("Send to?"),
        initial="customer",
        choices=SEND_TO_CHOICES,
        widget=forms.Select(attrs={"class": "no-select2"}),
        help_text=_("You can send this email to the customer or to " "other email of your choice."),
    )
    recipient = forms.EmailField(
        label=_("Destination"), required=False, help_text=_("Fill with the destination email address.")
    )

    def clean(self):
        cleaned_data = super(GenericScriptTemplateEmailForm, self).clean()
        send_to = cleaned_data.get("send_to")
        recipient = cleaned_data.get("recipient")

        if send_to == "other" and not recipient:
            self.add_error(
                "recipient", _("Recipient is a required field when you don't want to " "send the email to customer.")
            )
        return cleaned_data

class GenericSendEmailScriptTemplate(BaseScriptTemplate):
    """
    A generic ScriptTemplate which needs email configurations such as recipient, subject and body.

    This class also deals with a multi-language form to receive translated email's subject and body.

    The form of this ScriptTemplate is a `FormGroup` which will contain a `base` form which has no translation
    and also intances of `multilingual_form_class`, one for each available LANGUAGE. Only the form for the
    default language (provided by `PARLER_DEFAULT_LANGUAGE_CODE` setting) is required.

    :ivar: django.form.Form base_form_class: the main form, not included in the group of translation fields.
    :ivar: django.form.Form multilingual_form_class: the form which will be created for each available language.
    """

    template_name = "notify/admin/generic_script_template.jinja"
    extra_js_template_name = "notify/admin/generic_script_template_extra_js.jinja"
    base_form_class = GenericScriptTemplateEmailForm
    multilingual_form_class = GenericScriptTemplateEmailContentForm

    def get_script_steps(self, form):
        action_data = {
            "template_data": {},
            "language": {"constant": settings.PARLER_DEFAULT_LANGUAGE_CODE},
        }

        if form["base"].cleaned_data.get("send_to") == "other":
            action_data["recipient"] = {"constant": form["base"].cleaned_data["recipient"]}
        else:
            action_data["recipient"] = {"variable": "customer_email"}

        for language in form.forms:
            form_lang = form[language]
            # tries to get the cleaned data, otherwise the initial value
            # since cleaned_data will be blank if the user did not change anything
            action_data["template_data"][language] = {
                "content_type": "html",
                "subject": form_lang.cleaned_data.get("subject", form_lang.initial.get("subject", "")).strip(),
                "body": form_lang.cleaned_data.get("body", form_lang.initial.get("body", "")).strip(),
            }

        send_mail_action = SendEmail(action_data)
        return [Step(next=StepNext.STOP, actions=(send_mail_action,))]

    def get_context_data(self):
        context = super(GenericSendEmailScriptTemplate, self).get_context_data()
        context["languages"] = dict(settings.LANGUAGES)
        context["default_language"] = settings.PARLER_DEFAULT_LANGUAGE_CODE
        return context

    def get_form(self, **kwargs):
        """
        Create a `FormGroup` and put the necessary forms inside.
        """
        kwargs.update(self.get_form_kwargs())
        form_group = FormGroup(**kwargs)
        form_group.add_form_def("base", self.base_form_class, required=True)
        default_language = settings.PARLER_DEFAULT_LANGUAGE_CODE

        # the first form must be the first form, and required, as it is the fallback
        form_group.add_form_def(default_language, self.multilingual_form_class, required=True)

        for language, __ in settings.LANGUAGES:
            # the default language was already added!
            if language == default_language:
                continue
            form_group.add_form_def(language, self.multilingual_form_class, required=False)

        return form_group

    def get_initial(self):
        # if we have a script bound, parse its content
        if self.script_instance:
            send_email = None

            # search for the SendEmail action
            for step in self.script_instance.get_steps():
                for action in step._actions:
                    if isinstance(action, SendEmail):
                        send_email = action
                        break

            send_to_customer = send_email.data.get("recipient", {}).get("variable") == "customer_email"
            recipient = "" if send_to_customer else send_email.data["recipient"].get("constant", "")

            initial = {"base-recipient": recipient, "base-send_to": "customer" if send_to_customer else "other"}

            for language, data in send_email.data["template_data"].items():
                for data_key, data_value in data.items():
                    initial["{0}-{1}".format(language, data_key)] = data_value
            return initial

        else:
            return super(GenericSendEmailScriptTemplate, self).get_initial()

    def can_edit_script(self):
        """
        We can only edit the script when:
            * the event is what we expect
            * has a single SendMail action in steps (oterwise we don't know which to edit)
        """
        if self.script_instance.event_identifier != self.event.identifier:
            return False

        send_mails = []
        for step in self.script_instance.get_steps():
            send_mails.extend(list(filter(lambda action: isinstance(action, SendEmail), step._actions)))
        return len(send_mails) == 1


#!/usr/bin/env python2

FW_BIN = '../res/fw.bin'
FW_TIMEOUT = 10000

ID_VENDOR = 0x10CF
ID_PRODUCT = 0x2501
FW_START = b'\x08'
VERSION_GET = b'\x0F'
VERSION_SIZE = 64
VERSION_DELIMITER = b'\r'
LOAD_SETTING = b'\x0E'
SCOPE_RESET = b'\x09'
SCOPE_TRIGGER = b'\x0B'
SCOPE_WAITING = b'\x4E'
SCOPE_READY = b'\x44'
SCOPE_READ = b'\x0A'
SCOPE_TRANSIENT = b'\x0C'
SCOPE_DATA_SIZE = 8192
SCOPE_TRANSIENT_SIZE = 64
GENERATOR_START = b'\x06'
GENERATOR_WAVE_SETTING = b'\x04'
GENERATOR_WAVE_SIZE = 512
SHUTDOWN_CMD = b'\x14'

def float_to_chr(float, max=0xff):
  if not 0 <= float <= 1:
    raise ValueError('Invalid float range')
  return chr(int(round(max * float)))

import struct

class ScopeSettings:
  SCOPE_SETTING = b'\x80'
  AVERAGE_OFFSET = float(0x78) / float(0xf7)

  VOLT_DIV_TABLE = { 10:   0x22,
                     30:   0x02,
                     100:  0x24,
                     300:  0x04,
                     1000: 0x28,
                     3000: 0x08,
                   }

  TIME_DIV_TABLE = { 5:      b'\x40',
                     10:     b'\x80',
                     20:     b'\xfe',
                     50:     b'\xfd',
                     100:    b'\xfc',
                     200:    b'\xfa',
                     500:    b'\xf9',
                     1000:   b'\xf8',
                     2000:   b'\xf2',
                     5000:   b'\xf1',
                     10000:  b'\xf0',
                     20000:  b'\xe2',
                     50000:  b'\xe1',
                     100000: b'\xe0',
                     200000: b'\xc2',
                     500000: b'\xc1',
                     0:      b'\x02',
                   }

  TRIGGER_UP = 0
  TRIGGER_DOWN = 1

  COUPLING_AC = 0
  COUPLING_DC = 1
  COUPLING_GND = 1 << 4

  def __init__(self):
    self.volt_div = [1000, 1000]
    self.couping = [self.COUPLING_DC, self.COUPLING_DC]
    self.y_position = [self.AVERAGE_OFFSET, self.AVERAGE_OFFSET]
    self.trigger_level = 0.5
    self.time_div = 1000
    self.trigger_ch = 0
    self.trigger = False
    self.trigger_edge = self.TRIGGER_UP
    self.digital = False

  def packet(self):
    packet = LOAD_SETTING + self.SCOPE_SETTING
    settings = ''
    for i in range(0, 2):
      settings += chr(self.VOLT_DIV_TABLE[self.volt_div[i]] \
          + self.couping[i])
    for i in range(0, 2):
      settings += float_to_chr(self.y_position[i], max=0xf7)
    settings += float_to_chr(self.trigger_level)
    settings += self.TIME_DIV_TABLE[self.time_div]
    if not self.trigger_edge in (self.TRIGGER_UP, self.TRIGGER_DOWN):
      raise ValueError("Invalid trigger edge value")
    settings += chr(self.trigger_ch + (self.trigger << 1) + (self.trigger_edge << 2) \
        + (self.digital << 3))
    packet += chr(len(settings)) + settings
    return packet

class GeneratorSettings:
  GENERATOR_SETTING = b'\x05'
  GENERATOR_FREQ_SETTING = b'\x02\x13'
  AVERAGE_DC_OFFSET = 0
  AVERAGE_AMPLITUDE = 7 / 2

  FILTER_TABLE = { 'SWEEP':  { 50000:   7,
                               150000:  6,
                               300000:  5,
                               500000:  4,
                               700000:  2,
                               1000000: 1,
                             },
                   'SINE':   { 50000:   7,
                               150000:  6,
                               300000:  5,
                               400000:  3,
                               500000:  2,
                               1000000: 1,
                             },
                   'SINE/X': { 5000:    7,
                               50000:   6,
                               500000:  1,
                             },
                   'SQUARE': { 1000000: 0,
                             },
                   'DC':     { 1000000: 7,
                             },
                   'OTHER':  { 50000:   7,
                               500000:  0,
                             },
                 }
  CLK_TABLE = { 5: 6.25 * 10**6,
                0: 12.5 * 10**6,
              }
  PHASE_INCREMENT_SIZE = 2**44
  SWEEP_INCREMENT_SIZE = 2**64

  SWEEP_LINEAR = 0
  SWEEP_LOG = 2**33

  @staticmethod
  def _dc_offset_to_chr(dc):
    if not -5 <= dc <= 5:
      raise ValueError('Invalid DC offset')
    return chr(int(round((dc + 5.0) / 10 * 0xff)))

  @staticmethod
  def _correction_to_int(corr):
    if not -5 <= corr <= 5:
      raise ValueError("Invalid correction value")
    val = int(round(corr / 5.0 * 3.0))
    if corr >= 0:
      val += 4
    return val

  def __init__(self):
    self.dc_offset = self.AVERAGE_DC_OFFSET
    self.amplitude = self.AVERAGE_AMPLITUDE
    self.freq_range = 0
    self.relay_mode = 0
    self.correction = 0
    self.power_led = 2
    self.sweep = False
    self.sweep_type = self.SWEEP_LINEAR
    self.sweep_start = 0
    self.sweep_end = 0
    self.sweep_time = 10000
    self.frequency = 0
    self.type = 'OTHER'

  def _filter(self):
    return [w for (k, w) in sorted(self.FILTER_TABLE[self.type].items())
        if self.frequency < k][0]

  def packet(self):
    packet = LOAD_SETTING + self.GENERATOR_SETTING
    settings = ''
    settings += self._dc_offset_to_chr(self.dc_offset)
    if not 0 <= self.amplitude < 8:
      raise ValueError("Invalid amplitude")
    if not 0 <= self.freq_range < 8:
      raise ValueError("Invalid frequency range")
    if not 0 <= self.relay_mode < 4:
      raise ValueError("Invalid relay mode")
    settings += chr(self.amplitude + (self.freq_range << 3) + (self.relay_mode << 6))
    if not 0 <= self.power_led <= 2:
      raise ValueError("Invalid power LED level")
    settings += chr(self._correction_to_int(self.correction) \
        + (self.power_led << 4))
    settings += chr(self._filter() + (self.sweep << 3))
    packet += chr(len(settings)) + settings
    return packet

  def frequency_packet(self):
    filter = self._filter()
    clk = [w for (k, w) in sorted(self.CLK_TABLE.items()) if filter > k][-1]
    packet = LOAD_SETTING + self.GENERATOR_FREQ_SETTING
    sweep_increment = 2**59 * (self.sweep_end - self.sweep_start) / clk / self.sweep_time
    if filter > 5:
      sweep_increment *= 2
    if self.sweep_type == self.SWEEP_LINEAR:
      sweep_increment *= 2**5
    packet += struct.pack('<Q', round(sweep_increment))
    phase_increment = 2**44 * self.frequency / clk
    packet += struct.pack('<Q', round(phase_increment))[:6]
    sweep_complete = self.sweep_time / 10**2
    if filter > 5:
      sweep_complete /= 2
    if self.sweep_type == self.SWEEP_LOG:
      sweep_complete /= 8
      sweep_complete += self.sweep_type
    packet += struct.pack('<Q', round(sweep_complete))[:5]
    return packet

from itertools import *

def get_waveform(func, start, period):
  y = []
  for i in xrange(0, GENERATOR_WAVE_SIZE):
    y.append(func(start + float(i) / GENERATOR_WAVE_SIZE * period))
  miny = min(y)
  maxy = max(y)
  y = bytearray([int(round((i - miny) / (maxy - miny) * 0xff)) for i in y])
  return y

import usb.core

dev = usb.core.find(idVendor=ID_VENDOR, idProduct=ID_PRODUCT)
if dev is None:
  raise ValueError('Device not found')
dev.set_configuration()
cfg = dev.get_active_configuration()

interface_number = cfg[(0,0)].bInterfaceNumber
alternate_setting = usb.control.get_interface(dev, interface_number)
intf = usb.util.find_descriptor(
   cfg, bInterfaceNumber = interface_number,
    bAlternateSetting = alternate_setting
)

e_in = usb.util.find_descriptor(
    intf,
    custom_match = \
    lambda e: \
        usb.util.endpoint_direction(e.bEndpointAddress) == \
        usb.util.ENDPOINT_IN
)

e_out = usb.util.find_descriptor(
    intf,
    custom_match = \
    lambda e: \
        usb.util.endpoint_direction(e.bEndpointAddress) == \
        usb.util.ENDPOINT_OUT
)

assert e_in is not None and e_out is not None

e_out.write(FW_START)
fw = open(FW_BIN, 'r').read()
e_out.write(fw, timeout=FW_TIMEOUT)

e_out.write(VERSION_GET)
ver = e_in.read(VERSION_SIZE)
ver = ''.join(map(chr, ver[:ver.index(ord(VERSION_DELIMITER))]))
print(ver)

from math import *

scope_settings = ScopeSettings()
generator_settings = GeneratorSettings()
e_out.write(scope_settings.packet())
generator_settings.amplitude = 6
generator_settings.frequency = 500
generator_settings.type = 'SINE'
generator_settings.sweep = 1
e_out.write(generator_settings.packet())
e_out.write(generator_settings.frequency_packet())
wave = get_waveform(sin, 0, 2 * pi)
e_out.write(GENERATOR_WAVE_SETTING)
e_out.write(wave)
e_out.write(GENERATOR_START)

def wait_trigger():
  e_out.write(SCOPE_TRIGGER)
  b = None
  try:
    b = chr(e_in.read(1)[0])
  except usb.core.USBError:
    #e_in.read(63) # read junk data
    #shitty PyUSB
    e_out.write(SCOPE_TRIGGER)
  while b != SCOPE_READY:
    b = chr(e_in.read(1)[0])

def transient_init():
  wait_trigger()
  e_out.write(SCOPE_READ)
  e_in.read(SCOPE_DATA_SIZE)
  e_out.write(SCOPE_TRANSIENT)
  e_out.write(SCOPE_RESET)

e_out.write(SCOPE_RESET)
#transient_init()

from itertools import *
from collections import *

import matplotlib
matplotlib.use("Qt4Agg")
from matplotlib.animation import *
import matplotlib.pyplot as plt

fig = plt.figure()
lim = SCOPE_DATA_SIZE
ax = plt.axes(xlim=(0, lim), ylim=(-1.2, 1.2))
lines = [ax.plot([], [], color="g")[0], ax.plot([], [], color="r")[0]]
x = range(0, lim)
ys = [deque(maxlen=lim), deque(maxlen=lim)]

def oscilloscope(i):
  wait_trigger()
  e_out.write(SCOPE_READ)
  data = e_in.read(SCOPE_DATA_SIZE)
  for y, n in izip(ys, count()):
    y.extend(map(lambda x : (float(x) / 0x7f - 1) * scope_settings.volt_div[n]
        / 1000, data[n::2]))
  for l, y in izip(lines, ys):
    l.set_data(x[:len(y)], y)
  return lines

def transient(i):
  wait_trigger()
  e_out.write(SCOPE_TRANSIENT)
  data = e_in.read(SCOPE_TRANSIENT_SIZE)
  for y, n in izip(ys, count()):
    y.extend(map(lambda x : (float(x) / 0x7f - 1) * scope_settings.volt_div[n]
        / 1000, data[n::2]))
  for l, y in izip(lines, ys):
    l.set_data(x[:len(y)], y)
  return lines

def init():
  for i in lines:
    i.set_data([], [])
  return lines

anim = FuncAnimation(fig, oscilloscope, interval=0, init_func=init, blit=True)
plt.show()

try:
  e_out.write(SHUTDOWN_CMD)
except usb.core.USBError:
  pass
try:
  dev.reset()
except usb.core.USBError:
  pass


import asyncio
import logging
from collections import defaultdict

from azure.eventprocessorhost import (
    AbstractEventProcessor,
    AzureStorageCheckpointLeaseManager,
    EventHubConfig,
    EventProcessorHost,
    EPHOptions, Checkpoint)
from azure.eventprocessorhost.abstract_checkpoint_manager import AbstractCheckpointManager
from azure.eventprocessorhost.abstract_lease_manager import AbstractLeaseManager
from azure.eventprocessorhost.lease import Lease

class EventProcessor(AbstractEventProcessor):
    """
    Example Implementation of AbstractEventProcessor
    """

    def __init__(self, params=None):
        """
        Init Event processor
        """
        super().__init__(params)
        self._on_receive_callback, = params
        self._msg_counter = 0

    async def open_async(self, context):
        """
        Called by processor host to initialize the event processor.
        """
        logging.info("Connection established {}".format(context.partition_id))

    async def close_async(self, context, reason):
        """
        Called by processor host to indicate that the event processor is being stopped.
        :param context: Information about the partition
        :type context: ~azure.eventprocessorhost.PartitionContext
        """
        logging.info("Connection closed (reason {}, id {}, offset {}, sq_number {})".format(
            reason,
            context.partition_id,
            context.offset,
            context.sequence_number))

    async def process_events_async(self, context, messages):
        """
        Called by the processor host when a batch of events has arrived.
        This is where the real work of the event processor is done.
        :param context: Information about the partition
        :type context: ~azure.eventprocessorhost.PartitionContext
        :param messages: The events to be processed.
        :type messages: list[~azure.eventhub.common.EventData]
        """
        for event_data in messages:
            last_offset = event_data.offset
            last_sn = event_data.sequence_number
            # print('Received: {}, {}'.format(last_offset, last_sn))

            body_segments = list(event_data.message.get_data())
            self._on_receive_callback(body_segments[0])

        # logging.info('Events processed {}'.format(context.sequence_number))
        await context.checkpoint_async()

    async def process_error_async(self, context, error):
        """
        Called when the underlying client experiences an error while receiving.
        EventProcessorHost will take care of recovering from the error and
        continuing to pump messages,so no action is required from
        :param context: Information about the partition
        :type context: ~azure.eventprocessorhost.PartitionContext
        :param error: The error that occurred.
        """
        logging.error("Event Processor Error {!r}".format(error))

async def wait_and_close(host):
    """
    Run EventProcessorHost for 7 days then shutdown.
    """
    await asyncio.sleep(604800)
    await host.close_async()

class EqualToEverything(object):
    """
    This object will be always equal to any other
    """

    def __eq__(self, other):
        return True

class DummyLease(Lease):
    """
    Lease object with the owner equal to anything else (simplifies testing)
    """

    def __init__(self):
        super().__init__()
        self.owner = EqualToEverything()

    def serializable(self):
        """
        Returns Serializable instance of `__dict__`.
        """
        serial = self.__dict__.copy()
        return serial

class DummyStorageCheckpointLeaseManager(AbstractCheckpointManager, AbstractLeaseManager):
    """
    Overriden interface of checkpoint manager.
    Normally it is implemented via Azure storage but can as well use any other storage.
    Here it does nothing except storing in memory. Just a proof of concept.
    """

    def __init__(self):
        AbstractCheckpointManager.__init__(self)
        AbstractLeaseManager.__init__(self, lease_renew_interval=10, lease_duration=30)

        self.checkpoints = defaultdict(Checkpoint)
        self.leases = defaultdict(DummyLease)

    def initialize(self, *args, **kwargs):
        pass

    async def create_checkpoint_store_if_not_exists_async(self):
        return True

    async def get_checkpoint_async(self, partition_id):
        if partition_id in self.checkpoints:
            return self.checkpoints[partition_id]
        else:
            return None

    async def create_checkpoint_if_not_exists_async(self, partition_id):
        # print('TODO: Replace this with check pointing.')
        checkpoint = await self.get_checkpoint_async(partition_id)
        if not checkpoint:
            await self.create_lease_if_not_exists_async(partition_id)
            checkpoint = Checkpoint(partition_id)
        return checkpoint

    async def update_checkpoint_async(self, lease, checkpoint):
        self.checkpoints[lease.partition_id] = checkpoint
        return True

    async def delete_checkpoint_async(self, partition_id):
        pass

    async def create_lease_store_if_not_exists_async(self):
        return True

    async def delete_lease_store_async(self):
        return True

    async def get_lease_async(self, partition_id):
        return self.leases[partition_id]

    async def get_all_leases(self):
        results = []

        for partition_id in self.leases.keys():
            results.append(self.get_lease_async(partition_id))
        return results

    async def create_lease_if_not_exists_async(self, partition_id):
        lease = self.leases[partition_id]
        lease.partition_id = partition_id

    async def delete_lease_async(self, lease):
        pass

    async def acquire_lease_async(self, lease):
        return True

    async def renew_lease_async(self, lease):
        return True

    async def release_lease_async(self, lease):
        return True

    async def update_lease_async(self, lease):
        return True

class AMQPConsumer:
    def __init__(self, namespace, eventhub, user, key, consumer_group, storage_container,
                 storage_account, storage_key):
        self.namespace = namespace
        self.evenhub = eventhub
        self.user = user
        self.key = key
        self.consumer_group = consumer_group
        self.storage_container = storage_container
        self.storage_account = storage_account
        self.storage_key = storage_key
        self.on_receive_callback = None

    def set_callback(self, on_receive_callback):
        self.on_receive_callback = on_receive_callback

    def consume(self):
        try:
            loop = asyncio.get_event_loop()

            # Eventhub config and storage manager
            eh_config = EventHubConfig(self.namespace, self.evenhub, self.user, self.key,
                                       consumer_group=self.consumer_group)
            eh_options = EPHOptions()
            eh_options.release_pump_on_timeout = False
            eh_options.debug_trace = False

            if self._is_storage_checkpoint_enabled():
                storage_manager = AzureStorageCheckpointLeaseManager(
                    self.storage_account, self.storage_key, self.storage_container)
            else:
                storage_manager = DummyStorageCheckpointLeaseManager()

            # Event loop and host
            host = EventProcessorHost(
                EventProcessor,
                eh_config,
                storage_manager,
                ep_params=[self.on_receive_callback],
                eph_options=eh_options,
                loop=loop)

            tasks = asyncio.gather(
                host.open_async(),
                wait_and_close(host))
            loop.run_until_complete(tasks)

        except KeyboardInterrupt:
            # Canceling pending tasks and stopping the loop
            for task in asyncio.Task.all_tasks():
                task.cancel()
            loop.run_forever()
            tasks.exception()

        finally:
            loop.stop()

    def _is_storage_checkpoint_enabled(self):
        return self.storage_account and self.storage_key and self.storage_container


#Importing necessary libraries
import sys
import os
import pandas as pd
import cv2
import mediapipe as mp
import json
import argparse

#1. SUMMARY
def videoSummary(videoPath, saveDirPath):
    summaryDict = {}
    summaryDict['video_path'] = videoPath
    #Getting components of the path seperated by '_' after removing .mp4 extension
    videoPathComp = videoFileName.strip('.mp4').split('_')
    # Extracting necessary parameters and adding it onto the dictionary
    if(videoPathComp[0][1] == 'H'):
        summaryDict['env']="home"
    else:
        summaryDict['env']="studio"
    summaryDict['signer_id'] = int(videoPathComp[1][1])
    summaryDict['gloss_id'] = int(videoPathComp[2])
    if(videoPathComp[0][1] == 'H'):
        summaryDict['position'] = videoPathComp[3]
    else:
        summaryDict['position'] = "S"
    videoElem = cv2.VideoCapture(videoPath)
    summaryDict['num_of_frames'] = int(videoElem.get(cv2.CAP_PROP_FRAME_COUNT))
    summaryDict['fps'] = float(videoElem.get(cv2.CAP_PROP_FPS))
    summaryDict['height'] = int(videoElem.get(cv2.CAP_PROP_FRAME_HEIGHT))
    summaryDict['width'] = int(videoElem.get(cv2.CAP_PROP_FRAME_WIDTH))
    summaryDict['rgb_path'] = os.path.join(saveDirPath+"/", videoPath.split('/')[-1].strip('.mp4') + '_lowResRGB.avi')
    summaryDict['pose_path'] = os.path.join(saveDirPath+"/", videoPath.split('/')[-1].strip('.mp4') + '_poseEstimate.json')
    return summaryDict

#2. LOW RESOLUTION RGB SQUARE VIDEO
def resizeAndCrop(videoPath, saveDirPath):
    videoElem = cv2.VideoCapture(videoPath.split('/')[-1])
    #Saving the resized and cropped video in the path specified by the user taking in -input video file, codec to compress frames using FourCC code, framerate (fps), resolution
    out = cv2.VideoWriter(os.path.join(saveDirPath+"/", videoPath.split('/')[-1].strip('.mp4') + '_lowResRGB.avi'),cv2.VideoWriter_fourcc('m', 'p', '4', 'v'), float(videoElem.get(cv2.CAP_PROP_FPS)), (320,320))
    while True:
        #Taking each frame of the video
        success, frame = videoElem.read()
        if success == True:
            #Resizing the original frame to 320x320 resolution with no scaling on x (fx) and y (fy) axis using bicubic interpolation
            resizedFrame = cv2.resize(frame,(320,320),fx=0,fy=0, interpolation = cv2.INTER_CUBIC)
            out.write(resizedFrame)
        else:
            break
    print()

#3. BODY AND HAND POSE ESTIMATION
def retrievePoseEstimates(videoPath, saveDirPath):
    videoElem = cv2.VideoCapture(videoPath)
    # Initialize mediapipe Holistic class.
    mpPose = mp.solutions.holistic
    # Setup the Holistic model with 2 parameters: detection confidence of 50% and tracking confidence of 50%
    poseVideo = mpPose.Holistic(min_detection_confidence=0.5, min_tracking_confidence=0.5)
    #Lists to store estimated pose cordinates and hand (both left and right) cordinates
    pose_x = []
    pose_y = []
    right_hand_x = []
    right_hand_y = []
    left_hand_x = []
    left_hand_y = []
    while True:
        success, frame = videoElem.read()
        if success == True:
            frameRGB = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            #Make estimation of poses
            results = poseVideo.process(frameRGB)
            #x and y cordinates of each estimated body landmark i.e., results.pose_landmarks.landmark
            if(results.pose_landmarks):
                #Iterate through each landmark and take its x and y cordinates
                for _,lm in enumerate(results.pose_landmarks.landmark):
                    pose_x.append(lm.x)
                    pose_y.append(lm.y)
            #if pose landmark does not exist- Fill in NaN to both the list
            else:
                pose_x.append('NaN')
                pose_y.append('NaN')
            if(results.right_hand_landmarks):
                for _,lm in enumerate(results.right_hand_landmarks.landmark):
                    right_hand_x.append(lm.x)
                    right_hand_y.append(lm.y)
            else:
                right_hand_x.append('NaN')
                right_hand_y.append('NaN')
            if(results.left_hand_landmarks):
                for _,lm in enumerate(results.left_hand_landmarks.landmark):
                    left_hand_x.append(lm.x)
                    left_hand_y.append(lm.y)
            else:
                left_hand_x.append('NaN')
                left_hand_y.append('NaN')
        else:
            break

    with open(os.path.join(saveDirPath+"/", videoPath.split('/')[-1].strip('.mp4') + '_poseEstimate.json'),"w") as outputFile:
        #Adding the pose estimates as a dictionary to the file using dump command to the specified output json file
        json.dump({"pose_x": pose_x, "pose_y": pose_y, "hand1_x": right_hand_x, "hand1_y": right_hand_y, "hand2_x": left_hand_x, "hand2_y": left_hand_y}, outputFile)

if __name__=="__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('--file_path', type=str, required=True)
    parser.add_argument('--save_dir', type=str, required=True)
    args = parser.parse_args()
    videoPath = args.file_path
    saveDirPath = args.save_dir
    #Checking whether the specified path exist or not
    if(os.path.isfile(videoPath)):
        videoFileName = videoPath.split('/')[-1]
        videoPathComp = videoFileName.strip('.mp4').split('_')
        if(len(videoPathComp)==3 or len(videoPathComp)==4):
            summaryDict = videoSummary(videoPath, saveDirPath)
            print('\n----------------------------------VIDEO SUMMARY CREATED--------------------------------------------\n')
            resizeAndCrop(videoPath, saveDirPath)
            print('\n-------------------------------LOW RESOLUTION RGB VIDEO CREATED--------------------------------------------\n')
            retrievePoseEstimates(videoPath, saveDirPath)
            print('\n--------------------------------BODY POSE ESTIMATES CREATED--------------------------------------------\n')
        else:
            print("\n INVALID!!! NAME OF THE VIDEO FILE IS NOT FOLLOWING THE NAMING CONVENTION\n")
    else:
        print("\nINVALID VIDEO PATH!!!\n")


import sys
sys_input=sys.stdin.readline

n,m=map(int,sys_input().rstrip().split())

def find(x,d):
    cnt=0

    while x!=0:
        x//=d
        cnt+=x

    return cnt

up_2,up_5=find(n,2),find(n,5)
down_2,down_5=find(m,2)+find(n-m,2),find(m,5)+find(n-m,5)

two,five=up_2-down_2,up_5-down_5

if two<=0 or five<=0:
    print(0)
else:
    print(min(two,five))


import pandas as pd

df = pd.read_csv('output_data\SHANGHAI.csv')
df['Standard_Time'] = df['Time At Port'].apply(lambda x: ''.join('_'.join('_'.join(x.split('d')).split('h')).split('m')).strip().replace(' ','').split('_'))
time = []
for i in df['Standard_Time'].values:
    i = [ 0 if value == '' else int(value) for value in i]
    try:
        if len(i) == 1:
            time.append(int(i[0])*60)
        elif len(i) == 2:
            time.append(int(i[0])*3600+int(i[1])*60)
        elif len(i) == 3:
            time.append(int(i[0])*86400+int(i[1])*3600+int(i[2])*60)
        else:
            print('三小拉',i)
    except:
        print(i)

df['Standard_Time'] = time
df = df[['Vessel Name', 'Port Call Type', 'Port Type', 'Port At Call',
       'Ata/atd11', 'Time At Port', 'Standard_Time', 'In Transit Port Calls',
       'Vessel Type - Detailed', 'Commercial Market']]

df.columns = ['Vessel Name', 'Port Call Type', 'Port Type', 'Port At Call',
       'Ata/atd11', 'Time At Port', 'Time At Port(sec)', 'In Transit Port Calls',
       'Vessel Type - Detailed', 'Commercial Market']

df.to_csv('SHANGHAI2.csv')

from datetime import datetime,timedelta

df['Time At Port(sec)']
df['Ata/atd11'].apply(lambda x: datetime.strptime(x.replace(' UTC',''),'%Y-%m-%d %H:%M'))
arrive = []
for i in  range(len(df)):
    x = datetime.strptime(df['Ata/atd11'].values[i].replace(' UTC',''),'%Y-%m-%d %H:%M') - timedelta(seconds=int(df['Time At Port(sec)'].values[i]))
    arrive.append(x)

df['Arrive Time'] = arrive


"""
Tic Tac Toe Player
"""

import math
import copy

X = "X"
O = "O"
EMPTY = None

def initial_state():
    """
    Returns starting state of the board.
    """
    return [[EMPTY, EMPTY, EMPTY],
            [EMPTY, EMPTY, EMPTY],
            [EMPTY, EMPTY, EMPTY]]

def player(board):
    """
    Returns player who has the next turn on a board.
    """
    X_count = 0
    O_count = 0
    for i in range(len(board)):
        for j in range(len(board[0])):
            if board[i][j] == X:
                X_count = X_count + 1
            elif board[i][j] == O:
                O_count = O_count + 1

    if X_count == O_count:
        return X
    else:
        return O

def actions(board):
    """
    Returns set of all possible actions (i, j) available on the board.
    """
    possible_actions = set()
    for i in range(len(board)):
        for j in range(len(board[0])):
            if board[i][j] == EMPTY:
                possible_actions.add((i, j))
    return possible_actions

def result(board, action):
    """
    Returns the board that results from making move (i, j) on the board.
    """

    if action not in actions(board):
        raise Exception("This is not a valid move, choose another move")

    new_board = copy.deepcopy(board)
    i = action[0]
    j = action[1]
    new_board[i][j] = player(board)
    return new_board

def winner(board):
    """
    Returns the winner of the game, if there is one.
    """
    for i in range(len(board)):
        if board[i][0] == board[i][1] and board[i][0] == board[i][2]:
            if board[i][0] == X or board[i][0] == O:
                return board[i][0]
        if board[0][i] == board[1][i] and board[0][i] == board[2][i]:
            if board[0][i] == X or board[0][i] == O:
                return board[0][i]

    if board[0][0] == board[1][1] and board[1][1] == board[2][2]:
        if board[0][0] == X or board[0][0] == O:
            return board[0][0]
    elif board[0][2] == board[1][1] and board[1][1] == board[2][0]:
        if board[0][2] == X or board[0][2] == O:
            return board[0][2]

    return None

def terminal(board):
    """
    Returns True if game is over, False otherwise.
    """

    if winner(board) is not None:
        return True

    for i in range(len(board)):
        for j in range(len(board[0])):
            if board[i][j] == EMPTY:
                return False
    return True

def utility(board):
    """
    Returns 1 if X has won the game, -1 if O has won, 0 otherwise.
    """
    if winner(board) == X:
        return 1
    elif winner(board) == O:
        return -1
    else:
        return 0

def max_value(board):
    if terminal(board):
        return utility(board)
    v = -math.inf
    for action in actions(board):
        v = max(v, min_value((result(board, action))))
    return v

def min_value(board):
    if terminal(board):
        return utility(board)
    v = math.inf
    for action in actions(board):
        v = min(v, max_value((result(board, action))))
    return v

def minimax(board):
    """
    Returns the optimal action for the current player on the board.
    """

    if terminal(board):
        return None

    if player(board) == X:
        v = -math.inf
        chosen_action = None
        for action in actions(board):
            minimised_option = min_value(result(board, action))
            if minimised_option > v:
                v = minimised_option
                chosen_action = action
    elif player(board) == O:
        v = math.inf
        chosen_action = None
        for action in actions(board):
            maximised_option = max_value(result(board, action))
            if maximised_option < v:
                v = maximised_option
                chosen_action = action
    return chosen_action


import pandas as pd
import numpy as np
import os
from sklearn.externals import joblib
from gensim.models import word2vec
from keras.preprocessing.sequence import pad_sequences
from keras.callbacks import History
from keras.models import load_model
import jieba
import json

from SentimentAnalysis.creat_data import bat
from SentimentAnalysis.sentence_transform.creat_vocab_word2vec import creat_vocab_word2vec
from SentimentAnalysis.models.sklearn_supervised import sklearn_supervised
from SentimentAnalysis.models import sklearn_config
from SentimentAnalysis.models.neural_bulit import neural_bulit

jieba.setLogLevel('WARN')
DIR = os.path.dirname(__file__)

class SentimentAnalysis():
    # def __init__(self):
    #     pass

    # open api
    def open_api(self):
        os.system("python %s" % (DIR + '/flask_api.py'))
        os.close()

    # get labels from baidu,ali,tencent
    def creat_label(self, texts):
        results_dataframe = bat.creat_label(texts)
        return results_dataframe

    def creat_vocab(self,
                    texts=None,
                    sg=0,
                    size=5,
                    window=5,
                    min_count=1,
                    vocab_savepath=DIR + '/models/vocab_word2vec.model'):
        '''
        get dictionary by word2vec
        :param texts: list of text
        :param sg: 0 CBOW,1 skip-gram
        :param size: the dimensionality of the feature vectors
        :param window: the maximum distance between the current and predicted word within a sentence
        :param min_count: ignore all words with total frequency lower than this
        :param vocab_savepath: path to save word2vec dictionary
        :return: None
        '''
        # 构建词向量词库
        self.vocab_word2vec = creat_vocab_word2vec(texts=texts,
                                                   sg=sg,
                                                   vocab_savepath=vocab_savepath,
                                                   size=size,
                                                   window=window,
                                                   min_count=min_count)

    def load_vocab_word2vec(self,
                            vocab_loadpath=DIR + '/models/vocab_word2vec.model'):
        '''
        load dictionary
        :param vocab_loadpath: path to load word2vec dictionary
        :return:
        '''
        self.vocab_word2vec = word2vec.Word2Vec.load(vocab_loadpath)

    def train(self,
              texts=None,
              label=None,
              model_name='SVM',
              model_savepath=DIR + '/models/classify.model',
              net_shape=None,
              batch_size=100,  # 神经网络参数
              epochs=2,  # 神经网络参数
              verbose=2,  # 神经网络参数
              maxlen=None,  # 神经网络参数
              **sklearn_param):
        '''
        use sklearn/keras to train model
        :param texts: x
        :param label: y
        :param model_name: name want to train
        :param model_savepath: model save path
        :param batch_size: for keras fit
        :param epochs: for keras fit
        :param verbose: for keras fit
        :param maxlen: for keras pad_sequences
        :param sklearn_param: param for sklearn
        :return: None
        '''
        self.model_name = model_name
        self.label = np.unique(np.array(label))
        # 文本转词向量
        vocab_word2vec = self.vocab_word2vec
        texts_cut = [[word for word in jieba.lcut(one_text) if word != ' '] for one_text in texts]  # 分词
        data = [[vocab_word2vec[word] for word in one_text if word in vocab_word2vec] for one_text in texts_cut]
        if maxlen is None:
            maxlen = max([len(i) for i in texts_cut])
        self.maxlen = maxlen
        # sklearn模型，词向量计算均值
        if model_name in ['SVM', 'KNN', 'Logistic']:
            data = [sum(i) / len(i) for i in data]
            # 配置sklearn模型参数
            if model_name == 'SVM':
                if sklearn_param == {}:
                    sklearn_param = sklearn_config.SVC
            elif model_name == 'KNN':
                if sklearn_param == {}:
                    sklearn_param = sklearn_config.KNN
            elif model_name == 'Logistic':
                if sklearn_param == {}:
                    sklearn_param = sklearn_config.Logistic
            # 返回训练模型
            self.model = sklearn_supervised(data=data,
                                            label=label,
                                            model_savepath=model_savepath,
                                            model_name=model_name,
                                            **sklearn_param)

        # keras神经网络模型，
        elif model_name in ['Conv1D_LSTM', 'Conv1D', 'LSTM']:
            data = pad_sequences(data, maxlen=maxlen, padding='post', value=0, dtype='float32')
            label_transform = np.array(pd.get_dummies(label))
            if net_shape is None:
                if model_name == 'Conv1D_LSTM':
                    net_shape = [
                        {'name': 'InputLayer', 'input_shape': data.shape[1:]},
                        {'name': 'Conv1D', 'filters': 64, 'kernel_size': 3, 'strides': 1, 'padding': 'same',
                         'activation': 'relu'},
                        {'name': 'MaxPooling1D', 'pool_size': 5, 'padding': 'same', 'strides': 2},
                        {'name': 'LSTM', 'units': 16, 'activation': 'tanh', 'recurrent_activation': 'hard_sigmoid',
                         'dropout': 0., 'recurrent_dropout': 0.},
                        {'name': 'Flatten'},
                        {'name': 'Dense', 'activation': 'relu', 'units': 64},
                        {'name': 'Dropout', 'rate': 0.2, },
                        {'name': 'softmax', 'activation': 'softmax', 'units': len(np.unique(label))}
                    ]

                elif model_name == 'LSTM':
                    net_shape = [
                        {'name': 'InputLayer', 'input_shape': data.shape[1:]},
                        {'name': 'Masking'},
                        {'name': 'LSTM', 'units': 16, 'activation': 'tanh', 'recurrent_activation': 'hard_sigmoid',
                         'dropout': 0., 'recurrent_dropout': 0.},
                        {'name': 'Dense', 'activation': 'relu', 'units': 64},
                        {'name': 'Dropout', 'rate': 0.2, },
                        {'name': 'softmax', 'activation': 'softmax', 'units': len(np.unique(label))}
                    ]
                elif model_name == 'Conv1D':
                    net_shape = [
                        {'name': 'InputLayer', 'input_shape': data.shape[1:]},
                        {'name': 'Conv1D', 'filters': 64, 'kernel_size': 3, 'strides': 1, 'padding': 'same',
                         'activation': 'relu'},
                        {'name': 'MaxPooling1D', 'pool_size': 5, 'padding': 'same', 'strides': 2},
                        {'name': 'Flatten'},
                        {'name': 'Dense', 'activation': 'relu', 'units': 64},
                        {'name': 'Dropout', 'rate': 0.2, },
                        {'name': 'softmax', 'activation': 'softmax', 'units': len(np.unique(label))}
                    ]

            model = neural_bulit(net_shape=net_shape,
                                 optimizer_name='Adagrad',
                                 lr=0.001,
                                 loss='categorical_crossentropy')
            history = History()
            model.fit(data, label_transform,
                      batch_size=batch_size, epochs=epochs, verbose=verbose, callbacks=[history])
            train_log = pd.DataFrame(history.history)
            self.model = model
            self.train_log = train_log
            if model_savepath != None:
                model.save(model_savepath)
        with open(DIR + '/data_info.json', mode='w', encoding='utf-8') as f:
            json.dump({'maxlen': maxlen, 'label': list(self.label)}, f)

    def load_model(self,
                   model_loadpath=DIR + '/models/classify.model',
                   model_name=None,
                   data_info_path=DIR + '/data_info.json'):
        '''
        load sklearn/keras model
        :param model_loadpath: path to load sklearn/keras model
        :param model_name: load model name
        :param data_info_path: date information path
        :return: None
        '''

        with open(data_info_path, encoding='utf-8') as f:
            data_info = json.load(f)
        self.maxlen = data_info['maxlen']
        self.label = data_info['label']
        self.model_name = model_name

        if self.model_name in ['SVM', 'KNN', 'Logistic']:
            self.model = joblib.load(model_loadpath)
        elif self.model_name in ['Conv1D_LSTM', 'Conv1D', 'LSTM']:
            self.model = load_model(model_loadpath)

    def predict_prob(self,
                     texts=None):
        '''
        predict probability
        :param texts:  list of text
        :return: list of probability
        '''
        # 文本转词向量
        vocab_word2vec = self.vocab_word2vec
        if self.model_name in ['SVM', 'KNN', 'Logistic']:
            texts_cut = [[word for word in jieba.lcut(one_text) if word != ' '] for one_text in texts]  # 分词
            data = [[vocab_word2vec[word] for word in one_text if word in vocab_word2vec] for one_text in texts_cut]
            data = [sum(i) / len(i) for i in data]
            self.testdata = data
            results = self.model.predict_proba(data)
        elif self.model_name in ['Conv1D_LSTM', 'Conv1D', 'LSTM']:
            texts_cut = [[word for word in jieba.lcut(one_text) if word != ' '] for one_text in texts]  # 分词
            data = [[vocab_word2vec[word] for word in one_text if word in vocab_word2vec] for one_text in texts_cut]
            data = pad_sequences(data, maxlen=self.maxlen, padding='post', value=0, dtype='float32')
            self.testdata = data
            results = self.model.predict(data)
        return results

    def predict(self,
                texts=None):
        '''
        predict class
        :param texts:  list of text
        :return: list of classify
        '''
        # 文本转词向量
        vocab_word2vec = self.vocab_word2vec
        if self.model_name in ['SVM', 'KNN', 'Logistic']:
            texts_cut = [[word for word in jieba.lcut(one_text) if word != ' '] for one_text in texts]  # 分词
            data = [[vocab_word2vec[word] for word in one_text if word in vocab_word2vec] for one_text in texts_cut]
            data = [sum(i) / len(i) for i in data]
            self.testdata = data
            results = self.model.predict(data)
        elif self.model_name in ['Conv1D_LSTM', 'Conv1D', 'LSTM']:
            texts_cut = [[word for word in jieba.lcut(one_text) if word != ' '] for one_text in texts]  # 分词
            data = [[vocab_word2vec[word] for word in one_text if word in vocab_word2vec] for one_text in texts_cut]
            data = pad_sequences(data, maxlen=self.maxlen, padding='post', value=0, dtype='float32')
            self.testdata = data
            results = self.model.predict(data)
            results = pd.DataFrame(results, columns=self.label)
            results = results.idxmax(axis=1)
        return results

if __name__ == '__main__':
    train_data = ['国王喜欢吃苹果',
                  '国王非常喜欢吃苹果',
                  '国王讨厌吃苹果',
                  '国王非常讨厌吃苹果']
    train_label = ['正面', '正面', '负面', '负面']
    # print('train data\n',
    #       pd.DataFrame({'data': train_data,
    #                     'label': train_label},
    #                    columns=['data', 'label']))
    test_data = ['涛哥喜欢吃苹果',
                 '涛哥讨厌吃苹果',
                 '涛哥非常喜欢吃苹果',
                 '涛哥非常讨厌吃苹果']
    test_label = ['正面', '负面', '正面', '负面']

    # 创建模型
    model = SentimentAnalysis()

    # 查看bat打的标签
    print(model.creat_label(test_data))

    model.creat_vocab(texts=train_data,
                      sg=0,
                      size=5,
                      window=5,
                      min_count=1,
                      vocab_savepath=None)

    # 导入词向量词包
    # model.load_vocab_word2vec(vocab_loadpath=DIR + '/vocab_word2vec.model')

    ###################################################################################
    # 进行机器学习
    model.train(texts=train_data,
                label=train_label,
                model_name='SVM',
                model_savepath=DIR + '/models/classify.model')

    # 导入机器学习模型
    model.load_model(model_loadpath=DIR + '/models/classify.model',
                     model_name='SVM',
                     data_info_path=DIR + '/data_info.json')

    # 进行预测:概率
    result_prob = model.predict_prob(texts=test_data)
    result_prob = pd.DataFrame(result_prob, columns=model.label)
    result_prob['predict'] = result_prob.idxmax(axis=1)
    result_prob['data'] = test_data
    result_prob = result_prob[['data'] + list(model.label) + ['predict']]
    print('prob:\n', result_prob)
    print('score:', np.sum(result_prob['predict'] == np.array(test_label)) / len(result_prob['predict']))


import time
from turtle import Screen
from player import Player
from car_manager import CarManager
from scoreboard import Scoreboard

screen = Screen()
screen.setup(width=600, height=600)
screen.bgcolor("white")
screen.tracer(0)
screen.listen()

player = Player()
cars = CarManager()
level = Scoreboard()

screen.onkey(player.move, "Up")

game_is_on = True
while game_is_on:
    time.sleep(0.1)
    screen.update()
    cars.make_cars()
    cars.move()

    # Increasing car speed and levels
    if player.ycor() > 280:
        cars.increment_speed()
        level.level_up()
        player.reposition()

    # Detect collision with cars
    for car in cars.all_cars:
        if player.distance(car) < 21:
            game_is_on = False
            level.game_over()

screen.exitonclick()


import cv2,os
from cv2 import CAP_PVAPI_DECIMATION_2OUTOF16
import numpy as np
from PyQt5.QtWidgets import (QMainWindow, QApplication, QFileDialog,QMessageBox)
import threading
import threadpool
from CvPyGui import ImageCvQtContainer
from CvPyGui.ui import gui
import time
from datetime import datetime
import pygame
import pygame.camera
import pyaudio
#import sounddevice as sd

Ui_MainWindow = gui.Ui_MainWindow

#shot
shotmark1 = 0
shotmark2 = 0
shotmark3 = 0

#更新视图
update1 = 0
update2 = 0
update3 = 0

#相机编号
capnum1 = -1
capnum2 = -1
capnum3 = -1

#全局视频分辨率
vw = 640
vh = 480

#录像状态
stop = 1

# pool = threadpool.ThreadPool(4)

camera_t1 = -1
camera_t2 = -1
camera_t3 = -1

p1 = None
p2 = None
p3 = None

img_no_camera = cv2.imread('no_camera.jpg', cv2.IMREAD_COLOR)
img_no_voice = cv2.imread('no_voice.jpg', cv2.IMREAD_COLOR)

class MyApp(QMainWindow, Ui_MainWindow, threading.Thread):

    filter_count = 0

    def __init__(self):
        super().__init__()
        threading.Thread.__init__(self)
        QMainWindow.__init__(self)
        Ui_MainWindow.__init__(self)
        self.setupUi(self)
        self.initUI()

    def initUI(self):

        self.original1_image = ImageCvQtContainer.Image(
            'camera1', self.original_frame_lbl)
        self.original2_image = ImageCvQtContainer.Image(
            'camera2', self.processed_frame_lbl)
        self.eye_image = ImageCvQtContainer.Image('eye_camera',self.eye_lbl)
        self.voice_image = ImageCvQtContainer.Image('voice_mic',self.voice_lbl)

        self.setBackground()
        self.createButtons()

    def initfrom(self):
        global update1
        update1 = 0
        global update2
        update2 = 0
        self.maxcap=0;
        testmax = 4;
        global caps
        caps = []
        for i in range(testmax):
            cap = cv2.VideoCapture(i)
            if(cap.isOpened()):
                self.maxcap+=1
                caps.append(cap)
            #cap.release()
        self.selecamera1.clear()
        self.selecamera2.clear()
        self.comboBox_2.clear()

        pygame.init()
        pygame.camera.init()
        cameralist = pygame.camera.list_cameras()

        self.selecamera1.addItems([str(i) for i in cameralist])
        self.selecamera2.addItems([str(i) for i in cameralist])
        self.comboBox_2.addItems([str(i) for i in cameralist])

    def stopfrom(self):
        global update1
        update1 = 0
        global update2
        update2 = 0
        global update3
        update3 = 0

    def loop1(self,index,w=1280,h=720):

        cap = cv2.VideoCapture(index)
        # cap = caps[index]
        cap.set(6 ,cv2.VideoWriter_fourcc('M', 'J', 'P', 'G') )
        # cap.set(3,w)
        # cap.set(4,h)
        global capnum1
        capnum1 = index

        global update1
        update1 = 1
        global shotmark1
        while (update1 == 1):

            ret, frame = cap.read()

            if ret:
                frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                self.original1_image.updateImage(frame)

            if shotmark1 == 1:
                fn = self.lineEdit.text()
                name = "photo/1_"+fn + "video.jpg"
                if os.path.exists(name):
                    name = "photo/1_"+fn + "video"+str(int(time.time()))+".jpg"
                cv2.imwrite(name, frame)
                shotmark1 = 0

        cap.release()
        # cv_img_rgb = np.zeros((700,700,3))
        self.original1_image.updateImage(img_no_camera)

    def selecamera1act(self,index,w=1280,h=720):
        global camera_t1
        if camera_t1 != index:
            global p1
            global update1
            update1 = 0
            if p1 and p1.is_alive():
                p1.join()

            p1=threading.Thread(target=self.loop1,args=(index,w,h))
            p1.setDaemon(True)
            p1.start()
            camera_t1 = index
         # threading.Thread.start_new_thread(loop1,text,w=640,h=480)

    def loop2(self,index,w=1280,h=720):
        cap = cv2.VideoCapture(index)
        # cap = caps[index]
        cap.set(6 ,cv2.VideoWriter_fourcc('M', 'J', 'P', 'G') )
        global capnum2
        capnum2 = index
        # cap.set(3,w)
        # cap.set(4,h)
        global update2
        update2 = 1
        global shotmark2

        while (update2 == 1):

            ret, frame = cap.read()
            if shotmark2 == 1:
                fn = self.lineEdit.text()
                name = "photo/2_"+fn + "video.jpg"
                if os.path.exists(name):
                    name = "photo/2_" + fn + "video"+str(int(time.time()))+".jpg"
                cv2.imwrite(name, frame)
                shotmark2 = 0
            if ret:
                frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                self.original2_image.updateImage(frame)
        cap.release()
        # cv_img_rgb = np.zeros((700,700,3))
        self.original2_image.updateImage(img_no_camera)

    def selecamera2act(self,index,w=1280,h=720):
        global camera_t2
        if camera_t2 != index:
            global p2
            global update2
            update2 = 0
            if p2 and p2.is_alive():
                p2.join()

            p2=threading.Thread(target=self.loop2,args=(index,w,h))
            p2.setDaemon(True)
            p2.start()
            camera_t2 = index

    def loop3(self,index,w=1280,h=720):
        cap = cv2.VideoCapture(index)
        # cap = caps[index]
        cap.set(6 ,cv2.VideoWriter_fourcc('M', 'J', 'P', 'G') )
        global capnum3
        capnum3 = index
        # cap.set(3,w)
        # cap.set(4,h)
        global update3
        update3 = 1
        global shotmark3

        while (update3 == 1):

            ret, frame = cap.read()
            if shotmark3 == 1:
                fn = self.lineEdit.text()
                name = "photo/3_"+fn + "video.jpg"
                if os.path.exists(name):
                    name = "photo/3_" + fn + "video"+str(int(time.time()))+".jpg"
                cv2.imwrite(name, frame)
                shotmark3 = 0
            if ret:
                frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                self.eye_image.updateImage(frame)
        cap.release()
        # cv_img_rgb = np.zeros((700,700,3))
        self.eye_image.updateImage(img_no_camera)

    def selecamera3act(self,index,w=1280,h=720):
        global camera_t3
        if camera_t3 != index:
            global p3
            global update3
            update3 = 0
            if p3 and p3.is_alive():
                p3.join()

            p3=threading.Thread(target=self.loop3,args=(index,w,h))
            p3.setDaemon(True)
            p3.start()
            camera_t3 = index

    def threadRe(self,text="",w=1280,h=720):
        global stop
        stop = 0
        c = 1
        fn = self.lineEdit.text()
        fourcc = cv2.VideoWriter_fourcc(*'XVID')
        if capnum1 == capnum2:
            c = 0
        cap1 = cv2.VideoCapture(capnum1)
        cap1.set(6 ,cv2.VideoWriter_fourcc('M', 'J', 'P', 'G') )
        cap1.set(3,w)
        cap1.set(4,h)
        if c != 0:
            cap2 = cv2.VideoCapture(capnum2)
            cap2.set(6 ,cv2.VideoWriter_fourcc('M', 'J', 'P', 'G') )
            cap2.set(3,w)
            cap2.set(4,h)
            # name2 = "video/2_" + fn + "video.avi"
            # if os.path.exists(name2):
            name2 = "video/2_" + fn + "_" + datetime.now().strftime('%Y%m%d%H%M%S') + ".avi"
            out2 = cv2.VideoWriter(name2,fourcc, 20.0, (w,h))
        # name1 = "video/1_" + fn + "video.avi"
        # if os.path.exists(name1):
        name1 = "video/1_" + fn + "_"+ datetime.now().strftime('%Y%m%d%H%M%S') +".avi"

        out1 = cv2.VideoWriter(name1,fourcc, 20.0, (w,h))

        if capnum3 != -1 and capnum3 != capnum1 and capnum3 != capnum1:
            cap3 = cv2.VideoCapture(capnum3)
            cap3.set(6 ,cv2.VideoWriter_fourcc('M', 'J', 'P', 'G') )
            cap3.set(3,w)
            cap3.set(4,h)
            name3 = "video/3_"+fn+"_" + datetime.now().strftime('%Y%m%d%H%M%S') + ".avi"
            out3 = cv2.VideoWriter(name3,fourcc, 20.0, (w,h))

        self.statusbar.showMessage('开始录制...',5000)
        while(stop==0):
            ret1, frame1 = cap1.read()
            out1.write(frame1)
            frame1 = cv2.cvtColor(frame1, cv2.COLOR_BGR2RGB)
            self.original1_image.updateImage(frame1)

            if c != 0:
                ret2, frame2 = cap2.read()
            # # frame = cv2.flip(frame,0)
                out2.write(frame2)
                frame2 = cv2.cvtColor(frame2, cv2.COLOR_BGR2RGB)
                self.original2_image.updateImage(frame2)

            if capnum3 != -1 and capnum3 != capnum1 and capnum3 != capnum1:
                ret3, frame3 = cap3.read()
                out3.write(frame3)
                frame3 = cv2.cvtColor(frame3, cv2.COLOR_BGR2RGB)
                self.eye_image.updateImage(frame3)

        cap1.release()
        out1.release()
        if c != 0:
            cap2.release()
            out2.release()

        if capnum3 != -1 and capnum3 != capnum1 and capnum3 != capnum1:
            cap3.release()
            out3.release()

    def startRe(self):
        if stop == 1:
            global update1
            update1 = 0
            global update2
            update2 = 0
            global p1
            p1=threading.Thread(target=self.threadRe,args=())
            p1.setDaemon(True)
            p1.start()
            self.statusbar.showMessage('准备录制...',5000)

    def endRe(self):
        global stop
        stop = 1

        global p1
        global p2

        self.statusbar.showMessage('结束录制...',5000)

        if p1 and p1.is_alive():
            p1.join()

        if camera_t1 != -1:
            p1=threading.Thread(target=self.loop1,args=(camera_t1,1280,720))
            p1.setDaemon(True)
            p1.start()

        if camera_t2 != -1:
            p2=threading.Thread(target=self.loop2,args=(camera_t2,1280,720))
            p2.setDaemon(True)
            p2.start()

        self.statusbar.showMessage('空闲中...',5000)

    def shotP(self):
        global shotmark1
        shotmark1 = 1
        global shotmark2
        shotmark2 = 1
        global shotmark3
        shotmark3 = 1

    def about(self):
        QMessageBox.about(self, "多通道音视频采集软件",
                "<p>山东大学健康医疗大数据研究院")

    def createButtons(self):

        self.initButton.clicked.connect(self.initfrom)
        self.pushButton.clicked.connect(self.stopfrom)
        self.selecamera1.activated[int].connect(self.selecamera1act)
        self.selecamera2.activated[int].connect(self.selecamera2act)
        self.comboBox_2.activated[int].connect(self.selecamera3act)
        self.startButton.clicked.connect(self.startRe)
        self.endButton.clicked.connect(self.endRe)
        self.shotButton.clicked.connect(self.shotP)
        self.actionAbout.triggered.connect(self.about)

        # Checkbox for countours
        # self.countours_check_box.stateChanged.connect(self.calculateOriginal)
        # Button for selecting image
        # self.actionOpen_image.triggered.connect(self.openImage)
        # Buttons for saving images
        # self.actionSave_processed_image.triggered.connect(self.processed_image.saveImage)
        # self.actionSave_original_image.triggered.connect(self.original_image.saveImage)
        # self.actionAbout.clicked.connect(self.about)

    def updateImages(self):
        self.calculateProcessed()
        self.calculateOriginal()

    def setBackground(self):
        #cv_img_rgb = np.zeros((700,700,3))
        cv_img_rgb = img_no_camera
        self.original1_image.updateImage(cv_img_rgb)
        self.original2_image.updateImage(cv_img_rgb)
        self.eye_image.updateImage(cv_img_rgb)
        self.voice_image.updateImage(img_no_voice)


import os
from PIL import Image
import numpy as np
import cv2

if __name__ == '__main__':
    #img = Image.open("C:/Users/HP/Desktop/python/background/DIS-main/demo_datasets/your_dataset_result/your_dataset/image_000000000.png").convert('L')
    path = "C:/Users/HP/Desktop/python/background/DANCE/Dance_result/sample_png"
    out_path = "C:/Users/HP/Desktop/python/background/DANCE/erosion"
    dir = os.listdir(path)
    for i in dir:
        img = cv2.imread(os.path.join(path,i), cv2.IMREAD_GRAYSCALE)
        print(i)
        M1 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
        M2 = cv2.getStructuringElement(cv2.MORPH_CROSS, (5,5))
        ero_img = cv2.erode(img,M1,iterations=1)
        cv2.imwrite(os.path.join(out_path,i),ero_img)
    '''
    p = 0.01
    width1, height1 = img.size
    img = img.resize((int(width1*(1-p)),int(height1*(1-p))))
    width2, height2 = img.size

    right = int(width1*p/2)
    left = int(width1*p/2)
    top = int(height1*p/2)
    bottom = int(height1*p/2)
    new_width = width2 + right + left
    new_height = height2 + top + bottom

    result = Image.new(img.mode, (new_width, new_height), (255))

    result.paste(img, (left, top))
    result = result.resize((width1, height1))

    result.save('sdfsdf.png')
    '''


import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

np.random.seed( 0 )
sns.set_style( "darkgrid" )

def zoom_factory(ax, max_xlim, max_ylim, base_scale=2.0):
    def zoom_fun(event):
        # get the current x and y limits
        cur_xlim = ax.get_xlim()
        cur_ylim = ax.get_ylim()
        xdata = event.xdata  # get event x location
        ydata = event.ydata  # get event y location
        if event.button == "up":
            # deal with zoom in
            scale_factor = 1 / base_scale
            x_scale = scale_factor / 2
        elif event.button == "down":
            # deal with zoom out
            scale_factor = base_scale
            x_scale = scale_factor * 2
        else:
            # deal with something that should never happen
            scale_factor = 1
            print(event.button)
        # set new limits
        new_width = (cur_xlim[1] - cur_xlim[0]) * x_scale
        new_height = (cur_ylim[1] - cur_ylim[0]) * scale_factor

        relx = (cur_xlim[1] - xdata) / (cur_xlim[1] - cur_xlim[0])
        rely = (cur_ylim[1] - ydata) / (cur_ylim[1] - cur_ylim[0])

        if xdata - new_width * (1 - relx) > max_xlim[0]:
            x_min = xdata - new_width * (1 - relx)
        else:
            x_min = max_xlim[0]
        if xdata + new_width * (relx) < max_xlim[1]:
            x_max = xdata + new_width * (relx)
        else:
            x_max = max_xlim[1]
        if ydata - new_height * (1 - rely) > max_ylim[0]:
            y_min = ydata - new_height * (1 - rely)
        else:
            y_min = max_ylim[0]
        if ydata + new_height * (rely) < max_ylim[1]:
            y_max = ydata + new_height * (rely)
        else:
            y_max = max_ylim[1]
        ax.set_xlim([x_min, x_max])
        ax.set_ylim([y_min, y_max])
        ax.figure.canvas.draw()

    fig = ax.get_figure()  # get the figure of interest
    # attach the call back
    fig.canvas.mpl_connect("scroll_event", zoom_fun)

    # return the function
    return zoom_fun

annotated_csv = "/Users/lselig/Desktop/annotations.csv"
try:
    annotated_df = pd.read_csv(annotated_csv)
except:
    annotated_df = pd.DataFrame(
        {
            "marked_ts": [],
        }
    )

figure_mosaic = """
                AAAAA
                """

fig, axs = plt.subplot_mosaic( figure_mosaic, figsize = (15, 9) )
df = pd.read_parquet("/Users/lselig/Desktop/happy_data/data/pq/ea148700010f/0B09C3CF-C70D-46C4-BE89-E0BD26481621/0B09C3CF-C70D-46C4-BE89-E0BD26481621-HH_010f-20220721_082821/eda.parquet")
axs["A"].plot(df.etime, df.conductance, label = "parquet")
max_xlim = axs["A"].get_xlim()  # get current x_limits to set max zoom out
max_ylim = axs["A"].get_ylim()  # get current y_limits to set max zoom out
f = zoom_factory( axs["A"], max_xlim, max_ylim, base_scale = 1.1 )
clicks = plt.ginput(-1, timeout=0)

clicks = list(np.vstack(clicks)[:, 0])
for i, click in enumerate(clicks):
    event = clicks[i]
    annotated_df = annotated_df.append(
        pd.DataFrame(
            {
                "marked_ts": [event * 24 * 60 * 60],
            }
        )
    )
    annotated_df = annotated_df.reset_index(drop=True)
    annotated_df.to_csv(annotated_csv, index=False)


import random
from card import Card

def main():
    card = Card()
    print(card)
    bingo_seq = random.sample(range(1, 76), 75)
    num = 0
    while not card.check_win():
        roll = bingo_seq[num]
        char = [k for k, v in Card.col_range.items() if v[0] <= roll <= v[1]][0]
        print(f"{char} {roll}")
        action = input("Enter / if no action; Enter 2,2 to circle row 3 column 3: ")
        if action == "/":
            pass
        else:
            card.update_card(int(action[0]), int(action[-1]))
        num += 1
        print("\r")

if __name__ == "__main__":
    main()


import numpy as np
from euphonic.cli.utils import (load_data_from_file, _grid_spec_from_args, _get_energy_bins)
from euphonic.util import mp_grid, mode_gradients_to_widths
from euphonic import ureg
import matplotlib.pyplot as plt
import os

"""
Script that produces violin plots of the sigma values associated with different data sets.
Can be used to determine whether to calculate sigma samples over whole sigma range, or whether
to skip over some values.
"""

#filenames = ['mp-147-20180417.yaml', 'mp-200-20180417.yaml', 'mp-216-20180417.yaml', 'mp-226-20180417.yaml',
#             'mp-306-20180417.yaml', 'mp-661-20180417.yaml', 'mp-830-20180417.yaml', 'mp-917-20180417.yaml',
#             'mp-1818-20180417.yaml', 'mp-2319-20180417.yaml', 'mp-7041-20180417.yaml']

filenames = ['mp-661-20180417.yaml', 'mp-917-20180417.yaml']

file_dir = os.path.dirname(os.path.abspath(__file__))
parent_dir = os.path.dirname(file_dir)

for filename in filenames:
    data = load_data_from_file(parent_dir+'/Data/'+filename)

    recip_length_unit = ureg('1 /angstrom')
    grid_spec = _grid_spec_from_args(data.crystal, grid=None,
                                        grid_spacing=(0.1
                                                    * recip_length_unit))

    # for adaptive broadening
    modes, mode_grads = data.calculate_qpoint_phonon_modes(mp_grid(grid_spec), return_mode_gradients=True)
    mode_widths = mode_gradients_to_widths(mode_grads, modes.crystal.cell_vectors)

    modes.frequencies_unit = 'hartree'

    sigma = mode_widths.to('hartree').magnitude

    plt.figure()
    plt.violinplot(np.ravel(sigma))

plt.show()


import time
from time import strftime, localtime

# Hora horaObjetivo transformada a segundos
horaObjetivo = 68400
hora = strftime("%H:%M:%S", localtime())
horaformateada = time.strptime(hora, "%H:%M:%S")
tsegundos = horaformateada.tm_hour * 3600 + horaformateada.tm_min * 60 + horaformateada.tm_sec
if tsegundos < horaObjetivo:
    segundos = horaObjetivo - tsegundos
    h = int(segundos/3600)
    m = segundos % 3600
    minutos = int(m / 60)
    s = m % 60
    print(f"Faltan {h} horas, {minutos} minutos, {s} segundos para las 19:00")
else:
    segundos = tsegundos - horaObjetivo
    h = int(segundos / 3600)
    m = segundos % 3600
    minutos = int(m / 60)
    s = m % 60
    print(f"Pasan {h} horas, {minutos} minutos, {s} segundos de las 19:00")


#Multiply a List
#Create a list of numbers and a single factor
#Create and print a new list multiplying them together

simple_list = [2, 3, 4]
factor = 2
new_list = []

for num in simple_list:
    new_list.append(num * factor)

print(new_list)


import numpy as np
from pathlib import Path
def get_project_root():
    """
    Return the root of the project.
    """
    from pathlib import Path
    return Path(__file__).parent

project_root = Path(__file__).parent
experiment_directory = "{}/.experiments".format(Path(__file__).parent.parent)
int_dtype = np.int32
float_dtype = np.float64
NUMPY_INT_DTYPE = np.int32
NUMPY_FLOAT_DTYPE = np.float64


# -*- coding: utf-8 -*-

"""
***********************************
tests._fixtures
***********************************

Fixtures used by the Census Geocoder test suite.

"""
import os

import pytest

from validator_collection import checkers

class State(object):
    """Class to hold incremental test state."""
    # pylint: disable=too-few-public-methods
    pass

@pytest.fixture
def input_files(request):
    """Return the ``--inputs`` command-line option."""
    return request.config.getoption("--inputs")

def check_input_file(input_directory, input_value):
    inputs = os.path.abspath(input_directory)
    if not os.path.exists(input_directory):
        raise AssertionError('input directory (%s) does not exist' % inputs)
    elif not os.path.isdir(input_directory):
        raise AssertionError('input directory (%s) is not a directory' % inputs)

    try:
        input_file = os.path.join(input_directory, input_value)
    except (TypeError, AttributeError):
        input_file = None

    if input_file is not None and checkers.is_file(input_file):
        input_value = input_file

    return input_value