from __future__ import annotations

import copy
import dataclasses
import json
from typing import TYPE_CHECKING

import pytest

from randovania.game_description.db.node_identifier import NodeIdentifier
from randovania.games.prime2.layout.echoes_configuration import EchoesConfiguration
from randovania.games.prime2.layout.translator_configuration import LayoutTranslatorRequirement
from randovania.gui import tracker_window
from randovania.layout.lib.teleporters import TeleporterShuffleMode
from randovania.layout.versioned_preset import VersionedPreset

if TYPE_CHECKING:
    from pathlib import Path
    from unittest.mock import MagicMock

@pytest.fixture(params=[{}, {"teleporters": TeleporterShuffleMode.ONE_WAY_ANYTHING, "translator_configuration": True}])
def layout_config(request, default_echoes_configuration):
    if "translator_configuration" in request.param:
        translator_requirement = copy.copy(default_echoes_configuration.translator_configuration.translator_requirement)
        for gate in translator_requirement.keys():
            translator_requirement[gate] = LayoutTranslatorRequirement.RANDOM
            break

        new_gate = dataclasses.replace(
            default_echoes_configuration.translator_configuration, translator_requirement=translator_requirement
        )
        request.param["translator_configuration"] = new_gate
    return dataclasses.replace(default_echoes_configuration, **request.param)

def test_load_previous_state_no_previous_layout(tmp_path: Path, default_echoes_configuration):
    # Run
    result = tracker_window._load_previous_state(tmp_path, default_echoes_configuration)

    # Assert
    assert result is None

def test_load_previous_state_previous_layout_not_json(tmp_path: Path, default_echoes_configuration):
    # Setup
    tmp_path.joinpath("preset.rdvpreset").write_text("this is not a json")

    # Run
    result = tracker_window._load_previous_state(tmp_path, default_echoes_configuration)

    # Assert
    assert result is None

def test_load_previous_state_previous_layout_not_layout(tmp_path: Path, default_echoes_configuration):
    # Setup
    tmp_path.joinpath("preset.rdvpreset").write_text(json.dumps({"trick_level": "foo"}))
    tmp_path.joinpath("state.json").write_text("[]")

    # Run
    result = tracker_window._load_previous_state(tmp_path, default_echoes_configuration)

    # Assert
    assert result is None

def test_load_previous_state_missing_state(tmp_path: Path, default_preset):
    # Setup
    VersionedPreset.with_preset(default_preset).save_to_file(tmp_path.joinpath("preset.rdvpreset"))

    # Run
    result = tracker_window._load_previous_state(tmp_path, default_preset.configuration)

    # Assert
    assert result is None

def test_load_previous_state_invalid_state(tmp_path: Path, default_preset):
    # Setup
    VersionedPreset.with_preset(default_preset).save_to_file(tmp_path.joinpath("preset.rdvpreset"))
    tmp_path.joinpath("state.json").write_text("")

    # Run
    result = tracker_window._load_previous_state(tmp_path, default_preset.configuration)

    # Assert
    assert result is None

def test_load_previous_state_success(tmp_path: Path, default_preset):
    # Setup
    data = {"asdf": 5, "zxcv": 123}
    VersionedPreset.with_preset(default_preset).save_to_file(tmp_path.joinpath("preset.rdvpreset"))
    tmp_path.joinpath("state.json").write_text(json.dumps(data))

    # Run
    result = tracker_window._load_previous_state(tmp_path, default_preset.configuration)

    # Assert
    assert result == data

@pytest.mark.parametrize("shuffle_advanced", [False, True])
async def test_apply_previous_state(
    skip_qtbot, tmp_path: Path, default_echoes_preset, shuffle_advanced, echoes_game_description
):
    configuration = default_echoes_preset.configuration
    assert isinstance(configuration, EchoesConfiguration)

    if shuffle_advanced:
        translator_requirement = copy.copy(configuration.translator_configuration.translator_requirement)
        for gate in translator_requirement.keys():
            translator_requirement[gate] = LayoutTranslatorRequirement.RANDOM
            break

        new_gate = dataclasses.replace(
            configuration.translator_configuration, translator_requirement=translator_requirement
        )
        layout_config = dataclasses.replace(
            configuration,
            teleporters=dataclasses.replace(
                configuration.teleporters,
                mode=TeleporterShuffleMode.ONE_WAY_ANYTHING,
            ),
            translator_configuration=new_gate,
        )

        preset = dataclasses.replace(default_echoes_preset.fork(), configuration=layout_config)

    else:
        preset = default_echoes_preset

    state: dict = {
        "actions": ["Temple Grounds/Landing Site/Save Station"],
        "collected_pickups": {
            "Amber Translator": 0,
            "Annihilator Beam": 0,
            "Boost Ball": 0,
            "Cobalt Translator": 0,
            "Dark Agon Key 1": 0,
            "Dark Agon Key 2": 0,
            "Dark Agon Key 3": 0,
            "Dark Ammo Expansion": 0,
            "Dark Beam": 0,
            "Dark Torvus Key 1": 0,
            "Dark Torvus Key 2": 0,
            "Dark Torvus Key 3": 0,
            "Dark Visor": 0,
            "Darkburst": 0,
            "Echo Visor": 0,
            "Emerald Translator": 0,
            "Energy Tank": 0,
            "Grapple Beam": 0,
            "Gravity Boost": 0,
            "Ing Hive Key 1": 0,
            "Ing Hive Key 2": 0,
            "Ing Hive Key 3": 0,
            "Light Ammo Expansion": 0,
            "Light Beam": 0,
            "Missile Expansion": 0,
            "Missile Launcher": 0,
            "Morph Ball Bomb": 0,
            "Power Bomb": 0,
            "Power Bomb Expansion": 0,
            "Progressive Suit": 0,
            "Screw Attack": 0,
            "Seeker Launcher": 0,
            "Sky Temple Key 1": 0,
            "Sky Temple Key 2": 0,
            "Sky Temple Key 3": 0,
            "Sky Temple Key 4": 0,
            "Sky Temple Key 5": 0,
            "Sky Temple Key 6": 0,
            "Sky Temple Key 7": 0,
            "Sky Temple Key 8": 0,
            "Sky Temple Key 9": 0,
            "Sonic Boom": 0,
            "Space Jump Boots": 1,
            "Spider Ball": 0,
            "Sunburst": 0,
            "Super Missile": 0,
            "Violet Translator": 0,
        },
        "teleporters": [
            {
                "data": None,
                "teleporter": {
                    "area": "Transport to Temple Grounds",
                    "node": "Elevator to Temple Grounds",
                    "region": "Agon Wastes",
                },
            },
            {
                "data": None,
                "teleporter": {
                    "area": "Transport to Torvus Bog",
                    "node": "Elevator to Torvus Bog",
                    "region": "Agon Wastes",
                },
            },
            {
                "data": None,
                "teleporter": {
                    "area": "Transport to Sanctuary Fortress",
                    "node": "Elevator to Sanctuary Fortress",
                    "region": "Agon Wastes",
                },
            },
            {
                "data": None,
                "teleporter": {
                    "area": "Temple Transport C",
                    "node": "Elevator to Temple Grounds",
                    "region": "Great Temple",
                },
            },
            {
                "data": None,
                "teleporter": {
                    "area": "Temple Transport A",
                    "node": "Elevator to Temple Grounds",
                    "region": "Great Temple",
                },
            },
            {
                "data": None,
                "teleporter": {
                    "area": "Temple Transport B",
                    "node": "Elevator to Temple Grounds",
                    "region": "Great Temple",
                },
            },
            {
                "data": None,
                "teleporter": {
                    "area": "Aerie",
                    "node": "Elevator to Aerie Transport Station",
                    "region": "Sanctuary Fortress",
                },
            },
            {
                "data": None,
                "teleporter": {
                    "area": "Aerie Transport Station",
                    "node": "Elevator to Aerie",
                    "region": "Sanctuary Fortress",
                },
            },
            {
                "data": None,
                "teleporter": {
                    "area": "Transport to Temple Grounds",
                    "node": "Elevator to Temple Grounds",
                    "region": "Sanctuary Fortress",
                },
            },
            {
                "data": None,
                "teleporter": {
                    "area": "Transport to Agon Wastes",
                    "node": "Elevator to Agon Wastes",
                    "region": "Sanctuary Fortress",
                },
            },
            {
                "data": None,
                "teleporter": {
                    "area": "Transport to Torvus Bog",
                    "node": "Elevator to Torvus Bog",
                    "region": "Sanctuary Fortress",
                },
            },
            {
                "data": None,
                "teleporter": {
                    "area": "Sky Temple Energy Controller",
                    "node": "Elevator to Temple Grounds",
                    "region": "Great Temple",
                },
            },
            {
                "data": None,
                "teleporter": {
                    "area": "Sky Temple Gateway",
                    "node": "Elevator to Great Temple",
                    "region": "Temple Grounds",
                },
            },
            {
                "data": None,
                "teleporter": {
                    "area": "Transport to Agon Wastes",
                    "node": "Elevator to Agon Wastes",
                    "region": "Temple Grounds",
                },
            },
            {
                "data": None,
                "teleporter": {
                    "area": "Temple Transport B",
                    "node": "Elevator to Great Temple",
                    "region": "Temple Grounds",
                },
            },
            {
                "data": None,
                "teleporter": {
                    "area": "Transport to Sanctuary Fortress",
                    "node": "Elevator to Sanctuary Fortress",
                    "region": "Temple Grounds",
                },
            },
            {
                "data": None,
                "teleporter": {
                    "area": "Temple Transport A",
                    "node": "Elevator to Great Temple",
                    "region": "Temple Grounds",
                },
            },
            {
                "data": None,
                "teleporter": {
                    "area": "Transport to Torvus Bog",
                    "node": "Elevator to Torvus Bog",
                    "region": "Temple Grounds",
                },
            },
            {
                "data": None,
                "teleporter": {
                    "area": "Temple Transport C",
                    "node": "Elevator to Great Temple",
                    "region": "Temple Grounds",
                },
            },
            {
                "data": None,
                "teleporter": {
                    "area": "Transport to Sanctuary Fortress",
                    "node": "Elevator to Sanctuary Fortress",
                    "region": "Torvus Bog",
                },
            },
            {
                "data": None,
                "teleporter": {
                    "area": "Transport to Temple Grounds",
                    "node": "Elevator to Temple Grounds",
                    "region": "Torvus Bog",
                },
            },
            {
                "data": None,
                "teleporter": {
                    "area": "Transport to Agon Wastes",
                    "node": "Elevator to Agon Wastes",
                    "region": "Torvus Bog",
                },
            },
        ],
        "configurable_nodes": {
            "Agon Wastes/Mining Plaza/Translator Gate": None,
            "Agon Wastes/Mining Station A/Translator Gate": None,
            "Great Temple/Temple Sanctuary/Transport A Translator Gate": None,
            "Great Temple/Temple Sanctuary/Transport B Translator Gate": None,
            "Great Temple/Temple Sanctuary/Transport C Translator Gate": None,
            "Sanctuary Fortress/Reactor Core/Translator Gate": None,
            "Sanctuary Fortress/Sanctuary Temple/Translator Gate": None,
            "Temple Grounds/GFMC Compound/Translator Gate": None,
            "Temple Grounds/Hive Access Tunnel/Translator Gate": None,
            "Temple Grounds/Hive Transport Area/Translator Gate": None,
            "Temple Grounds/Industrial Site/Translator Gate": None,
            "Temple Grounds/Meeting Grounds/Translator Gate": None,
            "Temple Grounds/Path of Eyes/Translator Gate": None,
            "Temple Grounds/Temple Assembly Site/Translator Gate": None,
            "Torvus Bog/Great Bridge/Translator Gate": None,
            "Torvus Bog/Torvus Temple/Elevator Translator Scan": None,
            "Torvus Bog/Torvus Temple/Translator Gate": None,
        },
        "starting_location": {"region": "Temple Grounds", "area": "Landing Site", "node": "Save Station"},
    }

    if shuffle_advanced:
        for teleporter in state["teleporters"]:
            if (
                teleporter["teleporter"]["region"] == "Agon Wastes"
                and teleporter["teleporter"]["node"] == "Elevator to Sanctuary Fortress"
                and teleporter["teleporter"]["area"] == "Transport to Sanctuary Fortress"
            ):
                teleporter["data"] = {
                    "area": "Agon Energy Controller",
                    "region": "Agon Wastes",
                    "node": "Door to Controller Access",
                }
        state["configurable_nodes"]["Temple Grounds/Hive Access Tunnel/Translator Gate"] = "violet"
    VersionedPreset.with_preset(preset).save_to_file(tmp_path.joinpath("preset.rdvpreset"))
    tmp_path.joinpath("state.json").write_text(json.dumps(state), "utf-8")

    # Run
    window = await tracker_window.TrackerWindow.create_new(tmp_path, preset)
    skip_qtbot.add_widget(window)

    # Assert
    assert window.state_for_current_configuration() is not None
    persisted_data = json.loads(tmp_path.joinpath("state.json").read_text("utf-8"))
    assert persisted_data == state

    window.reset()
    window.persist_current_state()

    persisted_data = json.loads(tmp_path.joinpath("state.json").read_text("utf-8"))
    assert persisted_data != state

async def test_load_multi_starting_location(
    skip_qtbot, tmp_path: Path, default_echoes_configuration, default_echoes_preset, mocker
):
    preset = default_echoes_preset
    new_start_loc = (
        NodeIdentifier.create("Temple Grounds", "Landing Site", "Save Station"),
        NodeIdentifier.create("Temple Grounds", "Temple Transport C", "Elevator to Great Temple"),
    )
    layout_config = dataclasses.replace(
        default_echoes_configuration,
        starting_location=dataclasses.replace(default_echoes_configuration.starting_location, locations=new_start_loc),
    )
    preset = dataclasses.replace(default_echoes_preset.fork(), configuration=layout_config)
    mock_return = ("Temple Grounds/Temple Transport C/Elevator to Great Temple", True)

    # Run
    mock_get_item: MagicMock = mocker.patch("PySide6.QtWidgets.QInputDialog.getItem", return_value=mock_return)
    window = await tracker_window.TrackerWindow.create_new(tmp_path, preset)
    skip_qtbot.add_widget(window)

    # Assert
    mock_get_item.assert_called_once()
    state = window.state_for_current_configuration()
    assert state is not None
    assert state.node.identifier == new_start_loc[1]

async def test_load_single_starting_location(
    skip_qtbot, tmp_path: Path, default_echoes_configuration, default_echoes_preset
):
    preset = default_echoes_preset
    new_start_loc = (NodeIdentifier.create("Temple Grounds", "Temple Transport C", "Elevator to Great Temple"),)
    layout_config = dataclasses.replace(
        default_echoes_configuration,
        starting_location=dataclasses.replace(default_echoes_configuration.starting_location, locations=new_start_loc),
    )
    preset = dataclasses.replace(default_echoes_preset.fork(), configuration=layout_config)

    # Run
    window = await tracker_window.TrackerWindow.create_new(tmp_path, preset)
    skip_qtbot.add_widget(window)

    # Assert
    state = window.state_for_current_configuration()
    assert state is not None
    assert state.node.identifier == new_start_loc[0]

async def test_preset_without_starting_location(
    skip_qtbot, tmp_path: Path, default_echoes_configuration, default_echoes_preset
):
    preset = default_echoes_preset
    new_start_loc = ()
    layout_config = dataclasses.replace(
        default_echoes_configuration,
        starting_location=dataclasses.replace(default_echoes_configuration.starting_location, locations=new_start_loc),
    )
    preset = dataclasses.replace(default_echoes_preset.fork(), configuration=layout_config)

    # Run
    with pytest.raises(ValueError, match="Preset without a starting location"):
        await tracker_window.TrackerWindow.create_new(tmp_path, preset)


import boto3
from botocore.exceptions import NoCredentialsError

def upload_to_aws(local_file, bucket, s3_file):
    s3 = boto3.client('s3')
    try:
        s3.upload_file(local_file, bucket, s3_file)
        print("Upload Successful")
        return True
    except FileNotFoundError:
        print("The file was not found")
        return False
    except NoCredentialsError:
        print("Credentials not available")
        return False

if __name__ == "__main__":
    uploaded = upload_to_aws('Screenshot (288).png', 'group-6-marxel-pictures', 'test.png')


from typing import List

# 438. 找到字符串中所有字母异位词
# https://leetcode-cn.com/problems/find-all-anagrams-in-a-string/

class Solution:
    def findAnagrams(self, s: str, p: str) -> List[int]:
        p_vec = self.to_vector(p)
        s_vec = self.to_vector(s[0: len(p) - 1])
        # print(s_vec, p_vec)
        i = 0
        ans = []
        for j in range(len(p) - 1, len(s)):
            s_vec[ord(s[j]) - ord('a')] += 1
            if p_vec == s_vec:
                # print(i)
                ans.append(i)
            s_vec[ord(s[i]) - ord('a')] -= 1
            i += 1
        return ans

    # 用不到
    def compare(self, p_vec, word):
        d = dict()
        for i, c in enumerate(word):
            if c in d:
                d[c] += 1
            else:
                d[c] = 1

            if c not in p_vec:
                return False, i + 1
            elif d[c] > p_vec[c]:
                return False, 1

        return p_vec == d, 1

    def to_vector(self, word):
        # d = dict()
        # for each in word:
        #     if each in d:
        #         d[each] += 1
        #     else:
        #         d[each] = 1
        # return d

        vec = [0] * 26
        for each in word:
           vec[ord(each) - ord('a')] += 1
        return vec

s = "abab"
p = "ab"
print(s)
r = Solution().findAnagrams(s, p)
print(r)


import pygame
from pygame.sprite import Sprite

class Button(Sprite):

    def __init__(self, ai_settings, screen, msg, position, function_num):
        super(Button, self).__init__()
        self.screen = screen
        self.screen_rect = screen.get_rect()
        self.ai_settings = ai_settings
        self.function_num = function_num

        # 设置按钮的尺寸和其他属性
        self.width, self.height = 160, 50
        self.button_color = (230, 230, 230)
        self.text_color = self.ai_settings.BLACK
        self.font = pygame.font.SysFont(None, 48)

        self.rect = pygame.Rect(0, 0, self.width, self.height)
        self.rect.topleft = position

        # 按钮的标签只需创建一次
        self.prep_msg(msg)

    def prep_msg(self, msg):
        """
        将msg渲染成图像，并使其在按钮上居中
        :param msg:
        :return:
        """
        self.msg_image = self.font.render(msg, True, self.text_color, self.button_color)
        self.msg_image_rect = self.msg_image.get_rect()
        self.msg_image_rect.center = self.rect.center

    def is_over(self):
        """判断鼠标是否在按钮上"""
        point_x, point_y = pygame.mouse.get_pos()
        x, y = self.rect.x, self.rect.y

        in_x = x < point_x < x + self.width
        in_y = y < point_y < y + self.height
        return in_x and in_y

    def update(self):
        button_color = self.button_color
        if self.is_over():
            if self.ai_settings.pressed[0] and self.ai_settings.is_upped:
                button_color = (190, 190, 190)
                self.ai_settings.mouse_state = self.function_num
                self.ai_settings.is_upped = False
            else:
                button_color = (220, 220, 220)
        self.screen.fill(button_color, self.rect)
        self.screen.blit(self.msg_image, self.msg_image_rect)

    # r1rect = pygame.draw.rect(screen, BLACK, (20, 52.25, 160, 50), 1)
    # r2rect = pygame.draw.rect(screen, BLACK, (20, 206.75, 160, 50), 1)
    # r3rect = pygame.draw.rect(screen, BLACK, (20, 361.25, 160, 50), 1)
    # r4rect = pygame.draw.rect(screen, BLACK, (20, 515.75, 160, 50), 1)
    # r5rect = pygame.draw.rect(screen, BLACK, (205, 52.25, 160, 50), 1)
    # r6rect = pygame.draw.rect(screen, BLACK, (205, 206.75, 160, 50), 1)
    # r7rect = pygame.draw.rect(screen, BLACK, (205, 361.25, 160, 50), 1)
    # r8rect = pygame.draw.rect(screen, BLACK, (205, 515.75, 160, 50), 1)
    #
    # f1 = pygame.freetype.Font('德彪钢笔行书字库.TTF', 36)
    # f1rect = f1.render_to(screen, (40, 58), "上一层", fgcolor=BLACK, size=40)
    # f2rect = f1.render_to(screen, (40, 212.5), "下一层", fgcolor=BLACK, size=40)
    # f3rect = f1.render_to(screen, (57, 367), "删除", fgcolor=BLACK, size=40)
    # f4rect = f1.render_to(screen, (57, 521.5), "完成", fgcolor=BLACK, size=40)
    # f5rect = f1.render_to(screen, (225, 58), "长砖块", fgcolor=BLACK, size=40)
    # f6rect = f1.render_to(screen, (225, 212.5), "短砖块", fgcolor=BLACK, size=40)
    # f7rect = f1.render_to(screen, (225, 367), "厚砖块", fgcolor=BLACK, size=40)
    # f8rect = f1.render_to(screen, (225, 521.5), "其他块", fgcolor=BLACK, size=40)


import sys
import nimfa
import numpy as np
import scipy.sparse as sp
import pandas as pd
import gc
import os
import math
import mysql.connector
import random
import collections
from scipy.sparse.linalg import svds
from sklearn.model_selection import KFold
from multiprocessing import Pool

# import module
import machine_learning as ml
import evaluation as ev
import parsonal_value as pv
#np.set_printoptions(threshold=np.inf)
# Default values
CPU = 1
dataset = "movie.review"
eta0 = 0.45
repeate = 10
sepalate = 1
attribute = 5

def learning(method, train_matrix, train_index, data, user_list, item_list):
  if method == "SVD":
    u, s, vt = svds(train_matrix, k=attribute)
    np.savetxt("u.csv", u, delimiter=",")
    np.savetxt("s.csv", s, delimiter=",")
    np.savetxt("vt.csv", vt, delimiter=",")
    s_diag_matrix = np.diag(s)
    return u
  elif method == "ML3_liner":
    u, v = pv.rmrate(train_index, data, user_list, item_list, attribute)
    R = ml.pv_ml3(train_matrix, eta0, u, v, attribute)
    return u

def learning2(method, train_matrix, train_index, data, user_list, item_list, u2):
  if method == "SVD":
    u, s, vt = svds(train_matrix, k=attribute)
    s_diag_matrix = np.diag(s)
    return np.dot(np.dot(u2, s_diag_matrix), vt)
  elif method == "ML3_liner":
    u, v = pv.rmrate(train_index, data, user_list, item_list, attribute)
    R = ml.pv_ml3(train_matrix, eta0, u, v, attribute)
    return np.dot(np.dot(u2, R), v.T)

#=======================================================================================================================
# Name : makeMatrix
# Argument : ALL ... All data from numpy
#    Purpose ... porpese index
# Role :  make user-item matrix from evaluation format
#=======================================================================================================================

def makeMatrix(data, index, user_list, item_list):
  # lil matrix is a sparse matrix format (eliminated zero values)
  matrix = sp.lil_matrix((len(user_list), len(item_list)))
  # translate numpy into Dataframe
  data = pd.DataFrame(assign_index(data, index))
  for line in data.itertuples():
    # line[1] ... userID
    # line[2] ... itemID
    # line[3] ... rating value
    matrix[line[1], line[2]] = line[3]
  return matrix.tocsr()

#=======================================================================================================================
# Name : assign_index
# Argument : ALL ... All data from numpy
#            Purpose ... purpose index
# Role :  assign separated index data into numpy format
#=======================================================================================================================

def assign_index(ALL, Purpose):
  # attribute + 3 equals dataset format; user_ID, item_ID, time, attributes
  # Assigned ... all data in numpy format
  Assigned = np.zeros((len(Purpose), attribute + 3)).astype(np.int64)

  for i, j in enumerate(Purpose):
    Assigned[i] = ALL[j]
  return Assigned

#=======================================================================================================================
# Name : users_in_testdata
# Argument : n ... top-N recommendation count
#            test_matrix ... matrix witch elements include only in the test data
#            user_list ... user's ID
# Role :  make users list (the number of evaluations in test data is more than n)
#=======================================================================================================================

def users_in_testdata(n, test_matrix, user_list):
  test_user_list = np.zeros(len(user_list)).astype(np.int64)
  test_matrix = test_matrix.todense()
  for i,t in enumerate(test_matrix):
    if(t[t.nonzero()].size >= n):
      test_user_list[i] = 1
  return test_user_list

def nDCG(n, pred, test, user_list, item_list, count_dict):
  # initialization
  nDCG = np.zeros(len(user_list))
  D02 = 0
  D04 = 0
  D06 = 0
  D08 = 0
  D10 = 0
  l = 0
  count = np.array([0.,0.,0.,0.,0.,0.,0.])
  count_c = np.array([0,0,0,0,0,0,0])

  for i,p in enumerate(pred):
    # user : i
    # predicted score : p

    # initialize DCG and iDCG
    DCG = 0.
    iDCG = 0.

    # extract test data for user i
    t = test[i]

    # ground_truth : non zero list for test data
    ground_truth = t.nonzero()

    # predicted score corresponding to test data
    p_test = p[ground_truth]

    # ranking of predicted score
    ranking_p_arg = np.argsort(p_test)[::-1]

    # item ID of test data
    test_item = item_list[ground_truth]

    # test data rating
    truth = t[ground_truth]

    # ranking of test data's ratings
    ranking_t = np.sort(truth)[::-1]

    # the number of evaluation in test data more than n
    if len(ranking_p_arg) >= n:

      # j : recommendation result of top-N
      # k : item ID in test data
      for j in range(n):
        for k in range(len(test_item)):

          # calculate DCG
          if k == ranking_p_arg[j]:
            if j == 0:
              DCG = truth[k]
            else:
              DCG = DCG + (truth[k] / math.log(j + 1, 2))

        # calculate iDCG
        if j == 0:
          iDCG = ranking_t[j]
        else:
          iDCG = iDCG + (ranking_t[j] / math.log(j + 1, 2))

      # calc111ulate nDCG
      nDCG[i] = DCG / iDCG

      if nDCG[i] <= 0.2:
        D02 = D02 + 1
      elif nDCG[i] <= 0.4:
        D04 = D04 + 1
      elif nDCG[i] <= 0.6:
        D06 = D06 + 1
      elif nDCG[i] <= 0.8:
        D08 = D08 + 1
      else:
        D10 = D10 + 1

      if len(ranking_p_arg) <= 3:
        count[0] = count[0] + nDCG[i]
        count_c[0] = count_c[0] + 1
      elif len(ranking_p_arg) <= 6:
        count[1] = count[1] + nDCG[i]
        count_c[1] = count_c[1] + 1
      elif len(ranking_p_arg) <= 10:
        count[2] = count[2] + nDCG[i]
        count_c[2] = count_c[2] + 1
      elif len(ranking_p_arg) <= 20:
        count[3] = count[3] + nDCG[i]
        count_c[3] = count_c[3] + 1
      elif len(ranking_p_arg) <= 30:
        count[4] = count[4] + nDCG[i]
        count_c[4] = count_c[4] + 1
      elif len(ranking_p_arg) <= 40:
        count[5] = count[5] + nDCG[i]
        count_c[5] = count_c[5] + 1
      else:
        count[6] = count[6] + nDCG[i]
        count_c[6] = count_c[6] + 1

  count = count / count_c
  return nDCG, np.mean(nDCG), np.std(nDCG), np.max(nDCG), np.min(nDCG), D02, D04, D06, D08, D10, count, count_c

def precision(n, pred, test, user_list, item_list, count_dict):
  # initialization
  precision = np.zeros(len(user_list))
  recall = np.zeros(len(user_list))
  p00 = 0
  p033 = 0
  p066 = 0
  p100 = 0
  r02 = 0
  r04 = 0
  r06 = 0
  r08 = 0
  r10 = 0
  count_pre = np.array([0.,0.,0.,0.,0.,0.,0.])
  count_c_pre = np.array([0,0,0,0,0,0,0])
  count_rec = np.array([0.,0.,0.,0.,0.,0.,0.])
  count_c_rec = np.array([0,0,0,0,0,0,0])
  count_recom = np.array([0.,0.,0.,0.,0.,0.,0.])
  count_recom2 = np.array([0.,0.,0.,0.,0.,0.,0.])
  x = np.array( [] )

  for i, p in enumerate(pred):
    #initialization
    tp = 0
    fp = 0
    truth_all = 0
    t = test[i]
    ground_truth = t.nonzero()
    ground_truth2 = p.nonzero()
    ranking_p_arg = np.argsort(p[ground_truth])[::-1]
    ranking_p_arg2 = np.argsort(p[ground_truth2])[::-1]
    test_item = item_list[ground_truth]

    if len(ranking_p_arg2) >= 3:
      print(i,item_list[ranking_p_arg2[0:3]])
      if i == 0:
        x = np.append( x, ranking_p_arg2 )
      else:
        for v in range(n):
          if count_dict[item_list[ranking_p_arg2[v]]] <= 3:
            count_recom[0] += 1
            if ranking_p_arg2[v] not in x:
              x = np.append( x, ranking_p_arg2[v] )
              count_recom2[0] += 1
          elif count_dict[item_list[ranking_p_arg2[v]]] <= 6:
            count_recom[1] += 1
            if ranking_p_arg2[v] not in x:
              x = np.append( x, ranking_p_arg2[v] )
              count_recom2[1] += 1
          elif count_dict[item_list[ranking_p_arg2[v]]] <= 10:
            count_recom[2] += 1
            if ranking_p_arg2[v] not in x:
              x = np.append( x, ranking_p_arg2[v] )
              count_recom2[2] += 1
          elif count_dict[item_list[ranking_p_arg2[v]]] <= 20:
            count_recom[3] += 1
            if ranking_p_arg2[v] not in x:
              x = np.append( x, ranking_p_arg2[v] )
              count_recom2[3] += 1
          elif count_dict[item_list[ranking_p_arg2[v]]] <= 30:
            count_recom[4] += 1
            if ranking_p_arg2[v] not in x:
              x = np.append( x, ranking_p_arg2[v] )
              count_recom2[4] += 1
          elif count_dict[item_list[ranking_p_arg2[v]]] <= 40:
            count_recom[5] += 1
            if ranking_p_arg2[v] not in x:
              x = np.append( x, ranking_p_arg2[v] )
              count_recom2[5] += 1
          else:
            count_recom[6] += 1
            if ranking_p_arg2[v] not in x:
              x = np.append( x, ranking_p_arg2[v] )
              count_recom2[6] += 1

    if len(ranking_p_arg) >= 3:
      # true ratings
      truth = t[ground_truth]

      for j in range(n):
        for k in range(len(test_item)):
          if k == ranking_p_arg[j]:
            # good impression for items
            if truth[k] >= 4.:
              tp = tp + 1.0
            # bad impression
            else:
              fp = fp + 1.0

      # all items having good impression
      for j in range(len(truth)):
        if truth[j] >= 4.0:
          truth_all += 1

      # calculate precision
      precision[i] = tp / (tp + fp)

      # calculate recall
      if truth_all > 0:
        recall[i] = tp / truth_all

      if precision[i] == 0:
        p00 = p00 + 1
      elif precision[i] < 0.4:
        p033 = p033 + 1
      elif precision[i] < 0.7:
        p066 = p066 + 1
      else:
        p100 = p100 + 1

      if recall[i] <= 0.2:
        r02 = r02 + 1
      elif recall[i] <= 0.4:
        r04 = r04 + 1
      elif recall[i] <= 0.6:
        r06 = r06 + 1
      elif recall[i] <= 0.8:
        r08 = r08 + 1
      else:
        r10 = r10 + 1

      if len(ranking_p_arg) <= 3:
        count_pre[0] = count_pre[0] + precision[i]
        count_c_pre[0] = count_c_pre[0] + 1
      elif len(ranking_p_arg) <= 6:
        count_pre[1] = count_pre[1] + precision[i]
        count_c_pre[1] = count_c_pre[1] + 1
      elif len(ranking_p_arg) <= 10:
        count_pre[2] = count_pre[2] + precision[i]
        count_c_pre[2] = count_c_pre[2] + 1
      elif len(ranking_p_arg) <= 20:
        count_pre[3] = count_pre[3] + precision[i]
        count_c_pre[3] = count_c_pre[3] + 1
      elif len(ranking_p_arg) <= 30:
        count_pre[4] = count_pre[4] + precision[i]
        count_c_pre[4] = count_c_pre[4] + 1
      elif len(ranking_p_arg) <= 40:
        count_pre[5] = count_pre[5] + precision[i]
        count_c_pre[5] = count_c_pre[5] + 1
      else:
        count_pre[6] = count_pre[6] + precision[i]
        count_c_pre[6] = count_c_pre[6] + 1

      if len(ranking_p_arg) <= 3:
        count_rec[0] = count_rec[0] + recall[i]
        count_c_rec[0] = count_c_rec[0] + 1
      elif len(ranking_p_arg) <= 6:
        count_rec[1] = count_rec[1] + recall[i]
        count_c_rec[1] = count_c_rec[1] + 1
      elif len(ranking_p_arg) <= 10:
        count_rec[2] = count_rec[2] + recall[i]
        count_c_rec[2] = count_c_rec[2] + 1
      elif len(ranking_p_arg) <= 20:
        count_rec[3] = count_rec[3] + recall[i]
        count_c_rec[3] = count_c_rec[3] + 1
      elif len(ranking_p_arg) <= 30:
        count_rec[4] = count_rec[4] + recall[i]
        count_c_rec[4] = count_c_rec[4] + 1
      elif len(ranking_p_arg) <= 40:
        count_rec[5] = count_rec[5] + recall[i]
        count_c_rec[5] = count_c_rec[5] + 1
      else:
        count_rec[6] = count_rec[6] + recall[i]
        count_c_rec[6] = count_c_rec[6] + 1

  count_pre = count_pre / count_c_pre
  count_rec = count_rec / count_c_rec

  return precision,recall,precision.mean(), precision.std(), precision.max(), precision.min(), recall.mean(), recall.std(), recall.max(), recall.min(), p00, p033, p066, p100, r02, r04, r06, r08, r10, count_pre, count_c_pre, count_rec, count_c_rec, count_recom , count_recom2

def search_lt_n(n, test_data):
  lt_n = 0
  for t in test_data:
    if t[t.nonzero()].shape[0] < n:
      lt_n = lt_n + 1

  return lt_n

def calculate(method):
  a=0.0
  b=0.0
  c=0.0
  eta0 = 0.45

  set_data = sys.argv[1]
  setting = sys.argv[2]

  Pat3_ave = np.zeros((10, 3))
  Pat3_std = np.zeros((10, 3))
  Pat3_max = np.zeros((10, 3))
  Pat3_min = np.zeros((10, 3))
  Rat3_ave = np.zeros((10,3))
  Rat3_std = np.zeros((10,3))
  Rat3_max = np.zeros((10,3))
  Rat3_min = np.zeros((10,3))
  nDCGat3_ave = np.zeros((10,3))
  nDCGat3_std = np.zeros((10,3))
  nDCGat3_max = np.zeros((10,3))
  nDCGat3_min = np.zeros((10,3))
  P0 = np.zeros((10,3)).astype(np.int64)
  P03 = np.zeros((10,3)).astype(np.int64)
  P06 = np.zeros((10,3)).astype(np.int64)
  P10 = np.zeros((10,3)).astype(np.int64)
  D02 = np.zeros((10,3)).astype(np.int64)
  D04 = np.zeros((10,3)).astype(np.int64)
  D06 = np.zeros((10,3)).astype(np.int64)
  D08 = np.zeros((10,3)).astype(np.int64)
  D10 = np.zeros((10,3)).astype(np.int64)
  R02 = np.zeros((10,3)).astype(np.int64)
  R04 = np.zeros((10,3)).astype(np.int64)
  R06 = np.zeros((10,3)).astype(np.int64)
  R08 = np.zeros((10,3)).astype(np.int64)
  R10 = np.zeros((10,3)).astype(np.int64)
  lt_3 = np.zeros((10,3)).astype(np.int64)

  c_pre = np.array([0.,0.,0.,0.,0.,0.,0.])
  c_rec = np.array([0.,0.,0.,0.,0.,0.,0.])
  c_dcg = np.array([0.,0.,0.,0.,0.,0.,0.])
  pre_count = np.array([0,0,0,0,0,0,0])
  rec_count = np.array([0,0,0,0,0,0,0])
  dcg_count = np.array([0,0,0,0,0,0,0])

  if setting == '4':
    #setting 4
    user_Mu = np.loadtxt("./genre"+ set_data +"/data/d11/user.csv",delimiter=",").astype(np.int64)
    user_Mv = np.loadtxt("./genre"+ set_data +"/data/d22/user.csv",delimiter=",").astype(np.int64)
    test_user = np.loadtxt("./genre"+ set_data +"/data/d12/user.csv",delimiter=",").astype(np.int64)

    item_Mu = np.loadtxt("./genre"+ set_data +"/data/d11/item.csv",delimiter=",").astype(np.int64)
    item_Mv = np.loadtxt("./genre"+ set_data +"/data/d22/item.csv",delimiter=",").astype(np.int64)
    test_item = np.loadtxt("./genre"+ set_data +"/data/d12/item.csv",delimiter=",").astype(np.int64)

    data_Mu = np.loadtxt("./genre"+ set_data +"/data/d11/data.csv",delimiter=",").astype(np.int64)
    data_Mv = np.loadtxt("./genre"+ set_data +"/data/d22/data.csv",delimiter=",").astype(np.int64)
    test_data = np.loadtxt("./genre"+ set_data +"/data/d12/data.csv",delimiter=",").astype(np.int64)

    train_index = np.loadtxt("./genre"+ set_data +"/data/d11/index.csv",delimiter=",").astype(np.int64)
    train_index2 = np.loadtxt("./genre"+ set_data +"/data/d22/index.csv",delimiter=",").astype(np.int64)
    train_index3 = np.loadtxt("./genre"+ set_data +"/data/d12/index.csv",delimiter=",").astype(np.int64)

  elif setting == '5':
    #setting 5
    user_Mu = np.loadtxt("./genre"+ set_data +"/data/d22/user.csv",delimiter=",").astype(np.int64)
    user_Mv = np.loadtxt("./genre"+ set_data +"/data/d11/user.csv",delimiter=",").astype(np.int64)
    test_user = np.loadtxt("./genre"+ set_data +"/data/d21/user.csv",delimiter=",").astype(np.int64)

    item_Mu = np.loadtxt("./genre"+ set_data +"/data/d22/item.csv",delimiter=",").astype(np.int64)
    item_Mv = np.loadtxt("./genre"+ set_data +"/data/d11/item.csv",delimiter=",").astype(np.int64)
    test_item = np.loadtxt("./genre"+ set_data +"/data/d21/item.csv",delimiter=",").astype(np.int64)

    data_Mu = np.loadtxt("./genre"+ set_data +"/data/d22/data.csv",delimiter=",").astype(np.int64)
    data_Mv = np.loadtxt("./genre"+ set_data +"/data/d11/data.csv",delimiter=",").astype(np.int64)
    test_data = np.loadtxt("./genre"+ set_data +"/data/d21/data.csv",delimiter=",").astype(np.int64)

    train_index = np.loadtxt("./genre"+ set_data +"/data/d22/index.csv",delimiter=",").astype(np.int64)
    train_index2 = np.loadtxt("./genre"+ set_data +"/data/d11/index.csv",delimiter=",").astype(np.int64)
    train_index3 = np.loadtxt("./genre"+ set_data +"/data/d21/index.csv",delimiter=",").astype(np.int64)
  else:
    print("Select setting.")
    sys.exit()

  for i in range(repeate):
    j = 0
    Mu_matrix = makeMatrix(data_Mu, train_index, user_Mu, item_Mu)
    u = learning(method, Mu_matrix, train_index, data_Mu, user_Mu, item_Mu)

    Mv_matrix = makeMatrix(data_Mv, train_index2, user_Mv, item_Mv)
    pred = learning2(method, Mv_matrix, train_index2, data_Mv, user_Mv, item_Mv, u)
    np.savetxt("./result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/pred_temp.csv", pred, delimiter=",")

    test_matrix = makeMatrix(test_data, train_index3, test_user, test_item)
    test_users = users_in_testdata(3, test_matrix, test_user)

    # calculating precision, recall, and nDCG using "pred"
    lt_3[i,j] = search_lt_n(3, test_matrix)
    count_dict = collections.Counter(test_data[:,1])
    pre,rec,Pat3_ave[i,j], Pat3_std[i,j], Pat3_max[i,j], Pat3_min[i,j], Rat3_ave[i,j], Rat3_std[i,j], Rat3_max[i,j], Rat3_min[i,j], P0[i,j], P03[i,j], P06[i,j], P10[i,j], R02[i,j], R04[i,j], R06[i,j], R08[i,j], R10[i,j], new_c_pre, new_pre_count, new_c_rec, new_rec_count, recom, recom2 = precision(3, pred, np.array(test_matrix.todense()), test_user, test_item,count_dict)
    dcg, nDCGat3_ave[i,j], nDCGat3_std[i,j], nDCGat3_max[i,j], nDCGat3_min[i,j], D02[i,j], D04[i,j], D06[i,j], D08[i,j], D10[i,j], new_c_dcg, new_dcg_count = nDCG(3, pred, np.array(test_matrix.todense()), test_user, test_item,count_dict)

    c_pre = c_pre + new_c_pre
    c_rec = c_rec + new_c_rec
    c_dcg = c_dcg + new_c_dcg
    pre_count = pre_count + new_pre_count
    rec_count = rec_count + new_rec_count
    dcg_count = dcg_count + new_dcg_count

    print("count:" + str(i) + ", precision=" + str(np.mean(pre[test_users.nonzero()])) + ", recall=" + str(np.mean(rec[test_users.nonzero()])) +", nDCG=" + str(np.mean(dcg[test_users.nonzero()])))
    a += np.mean(pre[test_users.nonzero()])
    b += np.mean(rec[test_users.nonzero()])
    c += np.mean(dcg[test_users.nonzero()])
    #del pred
    #del train_matrix
    #del test_matrix
    gc.collect()
    j = j + 1

  c_pre = c_pre / 10
  c_rec = c_rec / 10
  c_dcg = c_dcg / 10
  pre_count = pre_count / 10
  rec_count = rec_count / 10
  dcg_count = dcg_count / 10
  print(c_pre)
  print("Precision AVE : " + str(a / 10))
  print("Recall AVE : " + str(b / 10))
  print("nDCG AVE : " + str(c / 10))

  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/Pat3_ave.npy", Pat3_ave)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/Pat3_std.npy", Pat3_std)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/Pat3_max.npy", Pat3_max)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/Pat3_min.npy", Pat3_min)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/Rat3_ave.npy", Rat3_ave)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/Rat3_std.npy", Rat3_std)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/Rat3_max.npy", Rat3_max)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/Rat3_min.npy", Rat3_min)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/nDCGat3_ave.npy", nDCGat3_ave)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/nDCGat3_std.npy", nDCGat3_std)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/nDCGat3_max.npy", nDCGat3_max)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/nDCGat3_min.npy", nDCGat3_min)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/P00.npy", P0)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/P03.npy", P03)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/P06.npy", P06)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/P10.npy", P10)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/D02.npy", D02)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/D04.npy", D04)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/D06.npy", D06)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/D08.npy", D08)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/D10.npy", D10)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/R02.npy", R02)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/R04.npy", R04)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/R06.npy", R06)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/R08.npy", R08)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/R10.npy", R10)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/lt_3.npy", lt_3)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/c_pre.npy", c_pre)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/c_rec.npy", c_rec)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/c_dcg.npy", c_dcg)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/pre_count.npy", pre_count)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/rec_count.npy", rec_count)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/dcg_count.npy", dcg_count)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/recom.npy", recom)
  np.save("result/movie.review/" + method + "/genre"+ set_data +"_set"+ setting +"/recom2.npy", recom2)

if __name__ == "__main__":

  # Pool : the number of CPU.
  p = Pool(CPU)
  '''
  methods = ["SVD", "NMF", "RMrate_liner", "D1_liner", "D2_liner", "D3_liner", "D4_liner", "D5_liner", "RMrate_square",
             "D1_square", "D2_square", "D3_square", "D4_square", "D5_square", "ML1_liner", "ML2_liner", "ML3_liner",
             "ML1_square", "ML2_square", "ML3_square"]
  '''
  methods = ["SVD","ML3_liner"]
  p.map(calculate,methods)

  print("Program completed...")


import math
import random
import time

import carla
import cv2
import numpy as np

actor_list = []

def pure_pursuit(tar_location, v_transform):
    L = 2.875
    yaw = v_transform.rotation.yaw * (math.pi / 180)
    x = v_transform.location.x - L / 2 * math.cos(yaw)
    y = v_transform.location.y - L / 2 * math.sin(yaw)
    dx = tar_location.x - x
    dy = tar_location.y - y
    ld = math.sqrt(dx ** 2 + dy ** 2)
    alpha = math.atan2(dy, dx) - yaw
    delta = math.atan(2 * math.sin(alpha) * L / ld) * 180 / math.pi
    steer = delta/90
    if steer > 1:
        steer = 1
    elif steer < -1:
        steer = -1
    return steer

def img_process(data):
    img = np.array(data.raw_data)
    img = img.reshape((1080, 1920, 4))
    img = img[:, :, :3]
    cv2.imwrite('car.png', img)
    # cv2.imshow('', img)
    # cv2.waitKey(1)
    pass

def callback(event):
    print("碰撞")

def callback2(event):
    print("穿越车道")

try:
    client = carla.Client('localhost', 2000)
    client.set_timeout(5.0)

    world = client.get_world()
    map = world.get_map()
    blueprint_library = world.get_blueprint_library()
    v_bp = blueprint_library.filter("model3")[0]
    spawn_point = random.choice(world.get_map().get_spawn_points())
    vehicle = world.spawn_actor(v_bp, spawn_point)
    actor_list.append(vehicle)

    # Find the blueprint of the sensor.
    blueprint = blueprint_library.find('sensor.camera.rgb')
    # Modify the attributes of the blueprint to set image resolution and field of view.
    blueprint.set_attribute('image_size_x', '1920')
    blueprint.set_attribute('image_size_y', '1080')
    blueprint.set_attribute('fov', '110')
    # Set the time in seconds between sensor captures
    blueprint.set_attribute('sensor_tick', '1.0')
    transform = carla.Transform(carla.Location(x=0.8, z=1.7))
    sensor = world.spawn_actor(blueprint, transform, attach_to=vehicle)
    actor_list.append(sensor)
    sensor.listen(lambda data: img_process(data))

    blueprint_collision = blueprint_library.find('sensor.other.collision')
    transform = carla.Transform(carla.Location(x=0.8, z=1.7))
    sensor_collision = world.spawn_actor(blueprint_collision, transform, attach_to=vehicle)
    actor_list.append(sensor_collision)
    sensor_collision.listen(callback)

    blueprint_lane_invasion = blueprint_library.find('sensor.other.lane_invasion')
    transform = carla.Transform(carla.Location(x=0.8, z=1.7))
    sensor_lane_invasion = world.spawn_actor(blueprint_lane_invasion, transform, attach_to=vehicle)
    actor_list.append(sensor_lane_invasion)
    sensor_lane_invasion.listen(callback2)

    vehicle.apply_control(carla.VehicleControl(throttle=1.0, steer=0))
    while True:
        waypoint01 = map.get_waypoint(vehicle.get_location(), project_to_road=True,
                                      lane_type=(carla.LaneType.Driving | carla.LaneType.Sidewalk))
        v_trans = vehicle.get_transform()
        waypoints = waypoint01.next(8.0)
        waypoint02 = waypoints[0]
        tar_loc = waypoint02.transform.location
        steer = pure_pursuit(tar_loc, v_trans)
        vehicle.apply_control(carla.VehicleControl(throttle=0.6, steer=steer))
        time.sleep(0.02)

finally:
    for actor in actor_list:
        actor.destroy()
    print("结束")


import unittest
from car_simulation import Car, Field, main
from unittest.mock import patch
from io import StringIO

class TestCar(unittest.TestCase):
    def test_change_direction(self):
        car = Car("TestCar", 0, 0, "N", "F")
        car.change_direction("R")
        self.assertEqual(car.direction, "E")

    def test_move_within_field(self):
        field = Field(5, 5)
        car = Car("TestCar", 2, 2, "N", "F")
        car.move(field)
        self.assertEqual((car.x, car.y), (2, 3))

    def test_move_out_of_bounds(self):
        field = Field(5, 5)
        car = Car("TestCar", 4, 4, "E", "F")
        car.move(field)
        self.assertEqual((car.x, car.y), (4, 4))  # Should not move out of bounds

    def test_execute_commands(self):
        field = Field(5, 5)
        car = Car("TestCar", 0, 0, "N", "F")
        car.execute_commands(field)
        self.assertEqual(car.direction, "N")
        self.assertEqual((car.x, car.y), (0, 1))

    def test_execute_empty_commands(self):
        field = Field(5, 5)
        car = Car("TestCar", 0, 0, "N", "")
        car.execute_commands(field)
        self.assertEqual((car.x, car.y), (0, 0))  # Should not move with empty commands

    def test_get_status(self):
        car = Car("TestCar", 3, 3, "W", "FFL")
        status = car.get_status()
        self.assertEqual(status, "TestCar, (3, 3) W, FFL")

    def test_collide(self):
        car = Car("TestCar", 2, 2, "S", "F")
        car.collid(1, "AnotherCar")
        self.assertTrue(car.collided)
        self.assertEqual(car.step, 1)
        self.assertEqual(car.collided_with, "AnotherCar")

class TestField(unittest.TestCase):
    def test_add_car_within_field(self):
        field = Field(5, 5)
        car = Car("TestCar", 1, 1, "N", "F")
        field.add_car(car)
        self.assertIn(car, field.cars)

    def test_add_car_out_of_bounds(self):
        field = Field(5, 5)
        car = Car("TestCar", 6, 6, "N", "F")
        field.add_car(car)
        self.assertNotIn(car, field.cars)

    def test_add_car_collision(self):
        field = Field(5, 5)
        car1 = Car("Car1", 2, 2, "N", "F")
        car2 = Car("Car2", 2, 2, "S", "F")
        field.add_car(car1)
        field.add_car(car2)
        self.assertNotIn(car2, field.cars)  # Car2 should not be added due to collision

    def test_is_within_field(self):
        field = Field(5, 5)
        self.assertTrue(field.is_within_field(2, 3))
        self.assertFalse(field.is_within_field(6, 6))

class TestCarSimulation(unittest.TestCase):
    @patch("builtins.input", side_effect=["10 10", "1", "A", "1 2 N", "FFRFFFFRRL", "2", "2"])
    def test_simulation_with_single_car(self, mock_input):
        with patch("sys.stdout", new_callable=StringIO) as mock_stdout:
            main()

        output = mock_stdout.getvalue().strip()

        self.assertIn("Your current list of cars are:", output)
        self.assertIn("- A, (1, 2) N, FFRFFFFRRL", output)
        self.assertIn("After simulation, the result is:", output)
        self.assertIn("- A, (5, 4) S", output)

    @patch("builtins.input", side_effect=["10 10", "1", "A", "1 2 N", "FFRFFFFRRL", "1", "B", "7 8 W", "FFLFFFFFFF", "2", "2"])
    def test_simulation_with_multiple_car(self, mock_input):
        with patch("sys.stdout", new_callable=StringIO) as mock_stdout:
            main()

        output = mock_stdout.getvalue().strip()

        self.assertIn("Your current list of cars are:", output)
        self.assertIn("- A, (1, 2) N, FFRFFFFRRL", output)
        self.assertIn("- B, (7, 8) W, FFLFFFFFFF", output)
        self.assertIn("After simulation, the result is:", output)
        self.assertIn("- A, collides with B at (5, 4) at step 7", output)
        self.assertIn("- B, collides with A at (5, 4) at step 7", output)

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


# convolution 계산 함수

import numpy as np
import pycuda.autoinit
from pycuda.compiler import SourceModule
from pycuda import gpuarray, tools
import pycuda.driver as cuda

class padding():
    # CUDA Limit size
    cu_lim = 32
    def __init__(self,D,K,mode='vaild'):
        # D : Data, K = kernel,
        kw = int(K.shape[0]) # kernel width
        kh = int(K.shape[1]) # kernel height

        # size setting (padding)
        if mode == 'vaild':
            aw = D.shape[0]-kw+1
            ah = D.shape[1]-kh+1
            P = D
        elif mode == 'same':
            D = D.astype(np.float32)
            aw = int(D.shape[0])
            ah = int(D.shape[1])

            if (aw % self.cu_lim == 0):
                aw_n = int(aw/self.cu_lim)
            else :
                aw_n = int(aw/self.cu_lim +1)

            if (ah % self.cu_lim == 0):
                ah_n = int(ah/self.cu_lim)
            else :
                ah_n = int(ah/self.cu_lim +1)

            # result size
            P = np.zeros([aw+kw-1,ah+kh-1]).astype(np.float32)
            # Module
            mod = SourceModule(open("CUDAKernelStudy\\padding.cu", "r", encoding="utf-8").read())
            cu_pad = mod.get_function("padding")

            # allocate memory on device
            d_gpu = cuda.mem_alloc(D.nbytes)
            p_gpu = cuda.mem_alloc(P.nbytes)

            # memory copy (host to device)
            cuda.memcpy_htod(d_gpu, D)
            cuda.memcpy_htod(p_gpu, P)

            kw32 = np.int32(kw)
            kh32 = np.int32(kh)
            cusiz = np.int32(self.cu_lim)
            # padding by CUDA
            cu_pad(d_gpu,kw32,kh32,cusiz,p_gpu,block=(self.cu_lim,self.cu_lim,1),grid=(aw_n,ah_n,1))

            # memory copy (device to host)
            cuda.memcpy_dtoh(P, p_gpu)

            d_gpu.free()
            p_gpu.free()

        self.D = D
        self.P = P
        self.C = np.zeros([aw,ah])


import six
from c7n_azure.actions.tagging import Tag, AutoTagUser, RemoveTag, TagTrim, TagDelayedAction
from c7n_azure.actions.delete import DeleteAction
from c7n_azure.filters import (MetricFilter, TagActionFilter,
                               DiagnosticSettingsFilter, PolicyCompliantFilter)
from c7n_azure.provider import resources
from c7n_azure.query import QueryResourceManager, QueryMeta, ChildResourceManager, TypeInfo, \
    ChildTypeInfo, TypeMeta
from c7n_azure.utils import ResourceIdParser

from c7n.utils import local_session

@six.add_metaclass(TypeMeta)
class ArmTypeInfo(TypeInfo):
    # api client construction information for ARM resources
    id = 'id'
    name = 'name'
    diagnostic_settings_enabled = True
    default_report_fields = (
        'name',
        'location',
        'resourceGroup'
    )

@resources.register('armresource')
@six.add_metaclass(QueryMeta)
class ArmResourceManager(QueryResourceManager):

    class resource_type(ArmTypeInfo):
        service = 'azure.mgmt.resource'
        client = 'ResourceManagementClient'
        enum_spec = ('resources', 'list', None)

    def augment(self, resources):
        for resource in resources:
            if 'id' in resource:
                resource['resourceGroup'] = ResourceIdParser.get_resource_group(resource['id'])
        return resources

    def get_resources(self, resource_ids):
        resource_client = self.get_client('azure.mgmt.resource.ResourceManagementClient')
        session = local_session(self.session_factory)
        data = [
            resource_client.resources.get_by_id(rid, session.resource_api_version(rid))
            for rid in resource_ids
        ]
        return [r.serialize(True) for r in data]

    @staticmethod
    def register_arm_specific(registry, _):
        for resource in registry.keys():
            klass = registry.get(resource)
            if issubclass(klass, ArmResourceManager):
                klass.action_registry.register('tag', Tag)
                klass.action_registry.register('untag', RemoveTag)
                klass.action_registry.register('auto-tag-user', AutoTagUser)
                klass.action_registry.register('tag-trim', TagTrim)
                klass.filter_registry.register('metric', MetricFilter)
                klass.filter_registry.register('marked-for-op', TagActionFilter)
                klass.action_registry.register('mark-for-op', TagDelayedAction)
                klass.filter_registry.register('policy-compliant', PolicyCompliantFilter)

                if resource != 'resourcegroup':
                    klass.action_registry.register('delete', DeleteAction)

                if hasattr(klass.resource_type, 'diagnostic_settings_enabled') \
                        and klass.resource_type.diagnostic_settings_enabled:
                    klass.filter_registry.register('diagnostic-settings', DiagnosticSettingsFilter)

@six.add_metaclass(QueryMeta)
class ChildArmResourceManager(ChildResourceManager, ArmResourceManager):

    class resource_type(ChildTypeInfo, ArmTypeInfo):
        pass

resources.subscribe(resources.EVENT_FINAL, ArmResourceManager.register_arm_specific)


# -*- coding: utf-8 -*-
"""
Created on Fri Dec  7 15:39:51 2018

@author: Akitaka
"""

import numpy as np
from sklearn.model_selection import cross_val_score
from lwpls import LWPLS

def psi(xlist,M):
    """ make a design matrix """
    ret = []
    for x in xlist:
        ret.append([x**i for i in range(0,M+1)])
    return np.array(ret)

np.random.seed(1)

""" Data """
N = 10
M = 15
xlist = np.linspace(0, 1, N)
ylist = np.sin(2 * np.pi * xlist) + np.random.normal(0, 0.2, xlist.size)
X = psi(xlist,M)
y = ylist

""" Cross validation"""
reg = LWPLS(n_components=2)
reg.fit(X,y)
y_pred = reg.predict(X)

scores = cross_val_score(reg, X, y, cv=5, scoring='neg_mean_squared_error')
print(scores.mean())


import django
from django.conf import settings

import pandas as pd
import os, sys

proj_path = "/home/webuser/webapps/tigaserver/"
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tigaserver_project.settings")
sys.path.append(proj_path)

django.setup()

from tigaserver_app.models import Fix

FILE = os.path.join(settings.STATIC_ROOT, "geo_user_fixes.csv")

# Getting all fixes and create a new DataFrame.
# Selecting only the desired fields for speed reasons.
df = pd.DataFrame.from_records(
    Fix.objects.all().values('server_upload_time', 'masked_lon', 'masked_lat')
)

# Remove any NaN value
df.dropna(inplace=True)

# Rename the datetime colume to a more readable name
df.rename(
    columns={"server_upload_time": "datetime"},
    inplace=True
)

# Convert datetime column to just date
df['datetime'] = pd.to_datetime(df['datetime']).dt.normalize()
# Round float to 2 decimals (lat and lon)
df = df.round(decimals=2)

##########
# Group by date, lat, lon and count the number of elements
# to make the resulting file smaller.
##########
# If the dataviz is slow, create bins for the latitude and longitue.
# Example: https://stackoverflow.com/questions/39254704/pandas-group-bins-of-data-per-longitude-latitude
# import numpy as np
# degres_step = 0.1
# to_bin = lambda x: np.floor(x / step) * step
# df["latBin"] = to_bin(df.masked_lat)
# df["lonBin"] = to_bin(df.masked_lon)

# See: https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html
df.groupby(
    [
        pd.Grouper(key='datetime', freq='3W-MON'), # Every 3 weeks.
        df['masked_lon'],
        df['masked_lat']
    ]).size()\
    .reset_index(name='count')\
    .to_csv(FILE, index=False)


from collections import deque

n, m = map(int, input().split())
number = list(map(int, input().split()))

deq = deque(i for i in range(1, n+1))

count = 0

for i in range(m):
    while True:
        if (deq[0] == number[i]):
            deq.popleft()
            break
        else:
            if(len(deq) / 2 > deq.index(number[i])):
                deq.append(deq.popleft())
                count += 1
            else:
                deq.appendleft(deq.pop())
                count += 1

print(count)


import json
from logging import info
import boto3
from botocore.exceptions import ClientError
from lgw.lambda_util import get_lambda_info, grant_permission_to_api_resource

def create_rest_api(
    api_name,
    api_description,
    binary_types,
    lambda_name,
    resource_path,
    deploy_stage,
    integration_role,
    method_response_models,
):
    '''
    Creates & deploys a REST API that proxies to a Lambda function, returning the URL
    pointing to this API.

    :param api_name: Name of the REST API
    :param api_description: Textual description of the API
    :param binary_types: A list of binary types that this API may serve up
    :param lambda_name: Name of an existing Lambda function
    :param resource_path: The resource path that points to the lambda.
    :param deploy_stage: The name of the deployment stage.
    :param integration_role
    :param method_response_models: Dictionary of content-type => response-model mappings to be applied to child method

    :return: URL of API. If error, returns None.
    '''

    api_client = boto3.client('apigateway')

    api_id = create_api_gateway(api_client, api_name, api_description, binary_types)

    (lambda_arn, lambda_uri, region, account_id) = get_lambda_info(lambda_name)

    root_resource_id = get_root_resource_id(api_client, api_id)
    create_method(api_client, api_id, root_resource_id, 'ANY')
    create_lambda_integration(api_client, api_id, root_resource_id, lambda_uri, integration_role)

    child_resource_id = create_resource(api_client, api_id, root_resource_id, resource_path)
    create_method(api_client, api_id, child_resource_id, 'ANY', method_response_models)
    create_lambda_integration(api_client, api_id, child_resource_id, lambda_uri, integration_role)

    deploy_to_stage(api_client, api_id, deploy_stage)

    # grant_permission_to_api_resource(api_id, region, account_id, lambda_arn, resource_path)

    return f'https://{api_id}.execute-api.{region}.amazonaws.com/{deploy_stage}'

def delete_rest_api(api_name):
    api_client = boto3.client('apigateway')
    delete_api_gateway(api_client, api_name)

def deploy_to_stage(api_client, api_id, deploy_stage):
    return api_client.create_deployment(restApiId=api_id, stageName=deploy_stage)

def create_lambda_integration(api_client, api_id, root_resource_id, lambda_uri, role_arn=None):
    '''
    Set the Lambda function as the destination for the ANY method
    Extract the Lambda region and AWS account ID from the Lambda ARN
    ARN format="arn:aws:lambda:REGION:ACCOUNT_ID:function:FUNCTION_NAME"
    '''
    api_client.put_integration(
        restApiId=api_id,
        resourceId=root_resource_id,
        httpMethod='ANY',
        type='AWS_PROXY',
        integrationHttpMethod='POST',
        uri=lambda_uri,
        credentials=role_arn,
    )

def create_method(api_client, api_id, resource_id, http_method, method_response_models={}):
    try:
        response = api_client.get_method(
            restApiId=api_id, resourceId=resource_id, httpMethod=http_method
        )
        if response and response.get('httpMethod'):
            info(f'{http_method} method already exists for resource {resource_id}')
            return
    except api_client.exceptions.NotFoundException:
        info(f'{http_method} method does not exist for resource {resource_id}, adding it.')

    api_client.put_method(
        resourceId=resource_id, restApiId=api_id, httpMethod=http_method, authorizationType='NONE'
    )

    # Set the content-type of the method response to JSON
    api_client.put_method_response(
        restApiId=api_id,
        resourceId=resource_id,
        httpMethod=http_method,
        statusCode='200',
        responseModels=method_response_models,
    )

def create_resource(api_client, api_id, parent_id, resource_path):
    resources = api_client.get_resources(restApiId=api_id)
    if 'items' in resources:
        for resource in resources['items']:
            if resource.get('parentId') == parent_id and resource.get('pathPart') == resource_path:
                info('Found existing resource for %s' % resource['parentId'])
                return resource['id']

    info(f'No existing resource found for {parent_id}/{resource_path}, creating a new one')
    result = api_client.create_resource(
        restApiId=api_id, parentId=parent_id, pathPart=resource_path
    )
    return result['id']

def get_root_resource_id(api_client, api_id):
    result = api_client.get_resources(restApiId=api_id)

    root_id = None
    for item in result['items']:
        if item['path'] == '/':
            root_id = item['id']

    if root_id is None:
        raise ClientError(
            'Could not retrieve the ID of the API root resource using api_id [%s]' % api_id
        )

    return root_id

def delete_api_gateway(api_client, api_name):
    api_id = lookup_api_gateway(api_client, api_name)
    if api_id:
        info(f'Deleting API with ID: {api_id}')
        api_client.delete_rest_api(restApiId=api_id)

def create_api_gateway(api_client, api_name, api_description, binary_types):
    api_id = lookup_api_gateway(api_client, api_name)
    if api_id:
        return api_id
    info(f'No existing API account found for {api_name}, creating it.')
    result = api_client.create_rest_api(
        name=api_name, description=api_description, binaryMediaTypes=binary_types
    )
    return result['id']

def lookup_api_gateway(api_client, api_name):
    apis = api_client.get_rest_apis()
    if 'items' in apis:
        for api in apis['items']:
            if api['name'] == api_name:
                info('Found existing API account for %s' % api['name'])
                return api['id']
    info(f'No API gateway found with name {api_name}')
    return None


from collections import deque

def solution(queue1, queue2):
    answer = -1
    queue1Sum = sum(queue1)
    queue2Sum = sum(queue2)
    sameSum = (queue1Sum + queue2Sum) // 2
    queue1Copy = deque(queue1)
    queue2Copy = deque(queue2)
    cnt = 0

    while cnt < len(queue1) * 3:
        if sameSum < queue1Sum:
            value = queue1Copy.popleft()
            queue2Copy.append(value)
            queue1Sum -= value
            queue2Sum += value
        elif sameSum > queue1Sum:
            value = queue2Copy.popleft()
            queue1Copy.append(value)
            queue1Sum += value
            queue2Sum -= value
        else:
            answer = cnt
            break
        cnt += 1

    return answer

queue1 = [3, 2, 7, 2]
queue2 = [4, 6, 5, 1]

print(solution(queue1,queue2))


from odoo import models, fields, api
from ..tools.nawh_error import NAWHError

class NetaddictionWhLocationsLine(models.Model):
    _name = 'netaddiction.wh.locations.line'
    _description = "Netaddiction WH Locations Line"
    _order = 'qty'

    product_id = fields.Many2one(
        'product.product',
        required=True,
        string="Prodotto",
    )

    qty = fields.Integer(
        default=1,
        required=True,
        string="Quantità",
    )

    wh_location_id = fields.Many2one(
        'netaddiction.wh.locations',
        required=True,
        string="Ripiano",
    )

    @api.model
    def get_products(self, barcode):
        """
        dato il barcode di un ripiano ritorna i prodotti allocati
        """
        result = self.search([('wh_location_id.barcode', '=', barcode)])
        if not result:
            return NAWHError(
                "Non sono stati trovati prodotti per il barcode"
            )
        return result

    ##########################
    # INVENTORY APP FUNCTION #
    # ritorna un dict simile #
    # ad un json per il web  #
    ##########################

    @api.model
    def get_json_products(self, barcode):
        """
        ritorna un json con i dati per la ricerca per ripiano
        """
        is_shelf = self.env['netaddiction.wh.locations'].check_barcode(barcode)
        if isinstance(is_shelf, NAWHError):
            return {'result': 0, 'error': is_shelf.msg}

        results = self.get_products(barcode)
        if isinstance(results, NAWHError):
            return {'result': 0, 'error': results.msg}

        return {
            'result': 1,
            'shelf': is_shelf.name,
            'barcode': barcode,
            'products': [
                {'product_name': res.product_id.display_name,
                 'qty': res.qty,
                 'barcode': res.product_id.barcode}
                for res in results
            ]
        }

    @api.model
    def put_json_new_allocation(self, barcode, qty, product_id, now_wh_line):
        """
        sposta la quantità qty dal ripiano barcode al new_shelf
        """
        is_shelf = self.env['netaddiction.wh.locations'].check_barcode(barcode)

        if isinstance(is_shelf, NAWHError):
            return {'result': 0, 'error': is_shelf.msg}

        new_shelf = is_shelf.id

        line = self.search(
            [('id', '=', int(now_wh_line)),
             ('product_id', '=', int(product_id))]
        )

        if not line:
            return {
                'result': 0,
                'error': 'Prodotto non più presente in questa locazione'
            }

        if line.wh_location_id.id == new_shelf:
            return {
                'result': 0,
                'error': 'Non puoi spostare un prodotto nella'
                         ' stessa locazione di partenza'
            }

        dec = line.decrease(qty)
        if isinstance(dec, NAWHError):
            return {'result': 0, 'error': dec.msg}

        self.allocate(product_id, qty, new_shelf)

        product = self.env['product.product'].browse(int(product_id))
        return {'result': 1, 'product_barcode': product.barcode}

    ##############################
    # END INVENTORY APP FUNCTION #
    ##############################

    ##################
    # FUNZIONI VARIE #
    ##################

    def decrease(self, qta):
        """ decrementa la quantità allocata di qta """
        self.ensure_one()
        end_qty = self.qty - int(qta)

        if end_qty < 0:
            return NAWHError(
                "Non puoi scaricare una quantità maggiore di quella allocata"
            )
        elif end_qty > 0:
            self.write({'qty': end_qty})
        else:
            self.unlink()

    def increase(self, qta):
        """ incrementa la quantità allocata di qta """
        self.ensure_one()
        self.qty += int(qta)

    @api.model
    def allocate(self, product_id, qta, new_location_id):
        """ alloca in new_location_id la qta di product_id """
        result = self.search(
            [('product_id', '=', int(product_id)),
             ('wh_location_id', '=', int(new_location_id))]
        )

        if result:
            # è già presente una locazione con questo prodotto
            # incremento
            for res in result:
                res.increase(qta)
        else:
            self.create([{
                'product_id': product_id,
                'qty': qta,
                'wh_location_id': new_location_id
            }])


from pathlib import Path
from datetime import timedelta
import environ
import os
import pymysql

pymysql.install_as_MySQLdb()

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

REST_AUTH = {
    'SESSION_LOGIN': False
}

###### 환경변수 쪽 설정 ##################
env = environ.Env(DEBUG=(bool, True))

environ.Env.read_env(
    env_file=os.path.join(BASE_DIR, '.env')
)

SECRET_KEY=env('SECRET_KEY')
DEBUG=env('DEBUG')
DATABASES = {
    'default': {
        'ENGINE': env('DATABASES_ENGINE'),
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

#######################################

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework.authtoken',
    'rest_framework',
    "corsheaders",
    'rest_framework_simplejwt',
    'rest_framework_simplejwt.token_blacklist',
    # In Folder Installed App
    'ycwg',
    'party_list',
    'account',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    "corsheaders.middleware.CorsMiddleware",
    "django.middleware.common.CommonMiddleware",
]

ROOT_URLCONF = 'ycwg.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'ycwg.wsgi.application'

# Database
# https://docs.djangoproject.com/en/dev/ref/settings/#databases

# Password validation
# https://docs.djangoproject.com/en/dev/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

# Internationalization
# https://docs.djangoproject.com/en/dev/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/dev/howto/static-files/

STATIC_URL = 'static/'

# Default primary key field type
# https://docs.djangoproject.com/en/dev/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

# CORS_ALLOWED_ORIGINS = [
#     "http://localhost:5173",
#     "http://localhost:8000",
#     "https://port-0-ycwg-backend-1maxx2klgvs8aq4.sel3.cloudtype.app"
# ]

CORS_ALLOW_ALL_ORIGINS = True

CORS_ALLOW_CREDENTIALS = True
CSRF_COOKIE_SECURE = True
CSRF_COOKIE_HTTP_ONLY = True
CSRF_TRUSTED_ORIGINS = [
    "http://localhost:8000",
    "http://localhost:5173",
    "https://port-0-ycwg-backend-1maxx2klgvs8aq4.sel3.cloudtype.app"
]

CORS_EXPOSE_HEADERS = ["Content-Type", "X-CSRFToken"]
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SAMESITE = "None"
SESSION_COOKIE_SAMESITE = "None"

MEDIA_URL = '/media/'		# ex) /media/photo1.png
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(days=30),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=30),
    'ROTATE_REFRESH_TOKENS': False,
    'BLACKLIST_AFTER_ROTATION': False,
    'UPDATE_LAST_LOGIN': False,

    'ALGORITHM': 'HS256',
    'SIGNING_KEY': SECRET_KEY,
    'VERIFYING_KEY': None,
    'AUDIENCE': None,
    'ISSUER': None,
    'JWK_URL': None,
    'LEEWAY': 0,

    'AUTH_HEADER_TYPES': ('Bearer',),
    'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',
    'USER_ID_FIELD': 'id',
    'USER_ID_CLAIM': 'user_id',
    'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule',

    'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
    'TOKEN_TYPE_CLAIM': 'token_type',
    'TOKEN_USER_CLASS': 'rest_framework_simplejwt.models.TokenUser',

    'JTI_CLAIM': 'jti',

    'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
    'SLIDING_TOKEN_LIFETIME': timedelta(days=30),
    'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=30),

    # custom
    'AUTH_COOKIE': 'access',
    # Cookie name. Enables cookies if value is set.
    'AUTH_COOKIE_REFRESH': 'refresh',
    # A string like "example.com", or None for standard domain cookie.
    'AUTH_COOKIE_DOMAIN': 'port-0-ycwg-backend-1maxx2klgvs8aq4.sel3.cloudtype.app',
    # Whether the auth cookies should be secure (https:// only).
    'AUTH_COOKIE_SECURE': False,
    # Http only cookie flag.It's not fetch by javascript.
    'AUTH_COOKIE_HTTP_ONLY': True,
    'AUTH_COOKIE_PATH': '/',        # The path of the auth cookie.
    # Whether to set the flag restricting cookie leaks on cross-site requests. This can be 'Lax', 'Strict', or None to disable the flag.
    'AUTH_COOKIE_SAMESITE': "Lax", # TODO: Modify to Lax
}

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": [
        'rest_framework_simplejwt.authentication.JWTAuthentication',
        'account.authenticate.CustomAuthentication',
    ],

    "DEFAULT_PERMISSION_CLASSES": [
        'rest_framework.permissions.AllowAny',
        'rest_framework.permissions.IsAuthenticated',
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
    ]
}

AUTH_USER_MODEL = "account.Account"

ALLOWED_HOSTS = [
    '*'
]


#!/bin/env python

# This script undoes the "WellFolders.py" script, aka it empties all of the well folders out into the parent folder.

import os
import re
import argparse

parser = argparse.ArgumentParser(description='Takes a folder formatted by WellFolders and undoes it ',
                                 usage='%(prog)s FOLDERPATH')
parser.add_argument('folderlocation', type=str, help='Absolute path of the folder to modify')
args = parser.parse_args()

regex = re.compile(r'\w{1}\d{2}_Day\d{1}')
allfolders = [file for file in os.scandir(args.folderlocation) if file.is_dir() and regex.match(file.name)]

for folder in allfolders:
    redfolder = folder.path + '/Red/'
    greenfolder = folder.path + '/Green/'
    brightfield = folder.path + '/Brightfield/'

    for foldpath in [redfolder, greenfolder, brightfield]:
        for file in os.scandir(foldpath):
            if file.name.endswith('.txt'):
                os.remove(file.path)
            elif file.name.endswith('.tif'):
                os.rename(file.path, f'{args.folderlocation}/{file.name}')
        os.rmdir(foldpath)

    os.rmdir(folder.path)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# @Description:
# @File: test.py
# @Project: ip_nlp
# @Author: Yiheng
# @Email: GuoYiheng89@gmail.com
# @Time: 7/15/2019 10:30
import time

from pymongo import ASCENDING

from common import logger_factory
from mongo.connect import get_collection
from mongo.utils.query_filter_utils import get_clf_query_filter

logger = logger_factory.get_logger('doc_service')

def create_index(db_name, clc_name, field_name, sort=ASCENDING):
    """
    create index of doc field to specified db's collection
    :param db_name:
    :param clc_name:
    :param field_name:
    :param sort: default direction is asc
    :return:
    """

    clc = get_collection(db_name, clc_name)
    clc.create_index([(field_name, sort)], background=True)

def remove_redundant(db_name, clc_name):
    """
    remove redundant docs
    :param db_name:
    :param clc_name:
    :return:
    """
    clc = get_collection(db_name, clc_name)

    redundant_docs = clc.aggregate([
            {'$group': {
                    '_id':       {'pubId': '$pubId'},
                    'uniqueIds': {'$addToSet': '$_id'},
                    'count':     {'$sum': 1}
            }},
            {'$match': {
                    'count': {'$gt': 1}
            }}], allowDiskUse=True)
    print('redundant_docs {}'.format(type(redundant_docs)))
    for doc in redundant_docs:
        logger.info(f'{doc}')
        obj_ids = doc['uniqueIds']
        logger.info(f'obj ids is {obj_ids}')
        for i in range(len(obj_ids)):
            if i == len(obj_ids) - 1:
                break
            clc.remove(obj_ids[i])

def find_some(db_name: str, clc_name: str, limit: int):
    """
    find specified count of docs return a generator, whose item is a Bson obj
    :param db_name:
    :param clc_name:
    :param limit:
    :return:
    """
    logger.info(f'start find_some with limit {limit}')
    clc = get_collection(db_name, clc_name)
    limit = 0 if limit < 0 else limit
    cursor = clc.find({}).limit(limit)
    for doc in cursor:
        yield doc

def find_all(db_name: str, clc_name: str):
    """
    find all docs and return a generator, whose item is a Bson obj
    :param db_name:
    :param clc_name:
    :return:
    """
    logger.info('start find_all')
    return find_some(db_name, clc_name, 0)

def find_by_clf(db_name, clc_name, limit=300, **kwargs):
    """
    find docs by classification infos and return a generator, whose item is a Bson obj
    :param db_name:
    :param clc_name:
    :param limit:
    :param kwargs:
    :return:
    """
    cursor = find_cursor_by_clf(db_name, clc_name, limit, **kwargs)
    for doc in cursor:
        yield doc

def find_cursor_by_clf(db_name, clc_name, limit, **kwargs):
    """
    get docs obj by classification params
    :param db_name:
    :param clc_name:
    :param limit:
    :param kwargs:
                section required
                mainClass
                subClass
    :return:
    """
    logger.info(f'start search tasks with {kwargs}')
    clc = get_collection(db_name, clc_name)

    query_filter = get_clf_query_filter(kwargs)

    cursor = clc.find(query_filter).limit(limit)
    logger.info(f'search tasks {kwargs} complete')
    return cursor

if __name__ == '__main__':
    db_ip_doc = 'ip_doc'
    clc_raw = 'raw'
    # remove_redundant('ip_doc', 'raw')
    start_time = time.time()
    docs = find_by_clf(db_ip_doc, clc_raw, section='B', mainClass='29', subClass='K')
    # count = len(list(docs))
    # print('count is {}'.format(count))

    for doc in docs:
        logger.info(f'find doc pubId {doc["pubId"]}')

    end_time = time.time()
    logger.info(f'complete...,take time {end_time - start_time}s')


import logging

from dvc.cli.command import CmdBase

logger = logging.getLogger(__name__)

class CmdQueueWorker(CmdBase):
    """Run the exp queue worker."""

    def run(self):
        self.repo.experiments.celery_queue.worker.start(self.args.name)
        return 0

def add_parser(experiments_subparsers, parent_parser):
    QUEUE_WORKER_HELP = "Run the exp queue worker."
    parser = experiments_subparsers.add_parser(
        "queue-worker",
        parents=[parent_parser],
        description=QUEUE_WORKER_HELP,
        add_help=False,
    )
    parser.add_argument("name", help="Celery worker name.")
    parser.set_defaults(func=CmdQueueWorker)