import torch.utils.data as data

from PIL import Image
import os
import os.path
import numpy as np
from numpy.random import randint

def abs_listdir(directory, prefix=None):
    def abspath_join(directory, path):
        return os.path.abspath(os.path.join(directory, path))

    if prefix:
        filepaths = [
            abspath_join(directory, path)
            for path in os.listdir(directory)
            if path.startswith(prefix)
        ]

    else:
        filepaths = [
            abspath_join(directory, path)
            for path in os.listdir(directory)
        ]

    return filepaths

class VideoRecord(object):
    def __init__(self, row, custom = False, prefix=None):
        self._data = row
        self.custom = custom

        filepaths = abs_listdir(self._data[0], prefix=prefix)
        self.__num_frames = len(filepaths)

        if self.__num_frames == 0:
            print("No Frames %s, %s" %(prefix, self.path))

    @property
    def path(self):
        return self._data[0]

    @property
    def num_frames(self):
        if self.custom:
            return int(self.__num_frames) - 9
        else:
            return int(self.__num_frames) - 1

    @property
    def label(self):
        return int(self._data[-1])

class TSNDataSet(data.Dataset):
    def __init__(self, root_path, list_file,
                 num_segments=1, new_length=1, modality='RGB',
                 image_tmpl='img_{:05d}.jpg', transform=None, custom_prefix = None,
                 force_grayscale=False, random_shift=True, test_mode=False):

        self.root_path = root_path
        self.list_file = list_file
        self.num_segments = num_segments
        self.new_length = new_length
        self.modality = modality
        self.custom_prefix = custom_prefix

        if custom_prefix:
            self.image_tmpl = self.custom_prefix + '{:05d}.jpg'
        else:
            self.image_tmpl = image_tmpl

        self.transform = transform
        self.random_shift = random_shift
        self.test_mode = test_mode

        if self.modality == 'RGBDiff':
            self.new_length += 1# Diff needs one more image to calculate diff

        self._parse_list()

    def _load_image(self, directory, idx):
        if self.modality == 'RGB' or self.modality == 'RGBDiff' or self.modality== 'ARP':
            return [Image.open(os.path.join(directory, self.image_tmpl.format(idx))).convert('RGB')]
        elif self.modality == 'Flow':
            if idx != 1: # WHAT IS THIS FOR???
                idx = idx - 1
            x_img = Image.open(os.path.join(directory, self.image_tmpl.format('x', idx))).convert('L')
            y_img = Image.open(os.path.join(directory, self.image_tmpl.format('y', idx))).convert('L')

            return [x_img, y_img]

    def _parse_list(self):
        prefix = self.modality.lower()
        if prefix == 'flow':
            prefix = prefix + '_x'

        if self.image_tmpl.startswith('rp'):
            self.video_list = [VideoRecord(x.strip().split(' '), True, prefix=prefix) for x in open(self.list_file)]
        else:
            self.video_list = [VideoRecord(x.strip().split(' '), False, prefix=prefix) for x in open(self.list_file)]

    def _sample_indices(self, record):
        """

        :param record: VideoRecord
        :return: list
        """

        average_duration = (record.num_frames - self.new_length + 1) // self.num_segments
        if average_duration > 0:
            offsets = np.multiply(list(range(self.num_segments)), average_duration) + randint(average_duration, size=self.num_segments)
        elif record.num_frames > self.num_segments:
            offsets = np.sort(randint(record.num_frames - self.new_length + 1, size=self.num_segments))
        else:
            offsets = np.zeros((self.num_segments,))
        return offsets + 1

    def _get_val_indices(self, record):
        if record.num_frames > self.num_segments + self.new_length - 1:
            tick = (record.num_frames - self.new_length + 1) / float(self.num_segments)
            offsets = np.array([int(tick / 2.0 + tick * x) for x in range(self.num_segments)])
        else:
            offsets = np.zeros((self.num_segments,))
        return offsets + 1

    def _get_test_indices(self, record):

        tick = (record.num_frames - self.new_length + 1) / float(self.num_segments)

        offsets = np.array([int(tick / 2.0 + tick * x) for x in range(self.num_segments)])

        return offsets + 1

    def __getitem__(self, index):
        record = self.video_list[index]

        if not self.test_mode:
            segment_indices = self._sample_indices(record) if self.random_shift else self._get_val_indices(record)
        else:
            segment_indices = self._get_test_indices(record)

        return self.get(record, segment_indices)

    def get(self, record, indices):

        images = list()
        for seg_ind in indices:
            p = int(seg_ind)
            for i in range(self.new_length):
                seg_imgs = self._load_image(record.path, p)
                images.extend(seg_imgs)
                if p < record.num_frames:
                    p += 1

        process_data = self.transform(images)
        return process_data, record.label

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


import math
import sys
import os
import bisect
import time
import csv
from matplotlib import pyplot as plt

input_dir = sys.argv[1]
output_dir = sys.argv[2]
stop_list_filename = 'stoplist.txt'
N = os.listdir(input_dir)   # count of corpus

def readFile(filename):
    file = open(filename, 'r')
    ret = file.read().splitlines()
    file.close()
    return ret

stop_words_list = readFile(stop_list_filename)

# searches a token in stop words list
def binarySearch(token):
    i = bisect.bisect_left(stop_words_list, token)
    return i if (i != len(stop_words_list) and stop_words_list[i] == token) else -1

# pre-processing on tokens in each document
def preProcessing2(file_data):
    pre_processed_hashmap = {}
    # remove remove stopwords, words that occur only once in the entire corpus, and words of length 1
    for i in range(len(file_data)):
        temp = file_data[i].split(" ")
        token, freq = temp[0], int(temp[1])

        if binarySearch(token) != -1 or len(token) == 1 or df_hashmap[token] == 1:
            continue
        pre_processed_hashmap[token] = freq

    return pre_processed_hashmap

# TF-IDF calculation
def calculateTF(pre_processed_hashmap, filename):
    # total tokens in d
    count_tokens_doc = len(pre_processed_hashmap.keys())

    out_filename = os.path.splitext(filename)[0] + ".wts"
    out_path = os.path.join(output_dir, out_filename)
    out = open(out_path, 'w')
    for token, freq in pre_processed_hashmap.items():
        tf = freq / count_tokens_doc
        df = df_hashmap[token]
        n = len(N)
        idf = math.log(n/df)
        tf_idf = tf * idf

        out.write("{} {}\n".format(token, tf_idf))
    out.close()

def calculate_DF_data():
    hm = {}
    for i in range(len(N)):
        filename = N[i]
        file_path = os.path.join(input_dir,filename)
        file_data = readFile(file_path) # file_data contains list of string: "<token> <its frequency>"
        for i in range(len(file_data)):
            temp = file_data[i].split(" ")
            hm[temp[0]] = 1 + hm.get(temp[0], 0)
    return hm

# gloabla hashmap to store count of documents in which a token occurs
df_hashmap = calculate_DF_data()

def start():
    if not os.path.isdir(output_dir):
        os.makedirs(output_dir)
    curr_time, total_time = 0.0, 0.0
    graph_interval = [53,103,153,203,253,303,353,403,453,503]
    graph_dict = {}
    for i in range(len(N)):
        filename = N[i]
        file_path = os.path.join(input_dir,filename)
        file_data = readFile(file_path) # file_data contains list of string: "<token> <its frequency>"

        ## start recording time
        start_time = time.process_time()

        pre_processed_hashmap = preProcessing2(file_data)
        calculateTF(pre_processed_hashmap, filename)

        ## stop time
        stop_time = (time.process_time()) - start_time
        curr_time += stop_time

        ## record time and write it into csv file
        if i+1 == graph_interval[0]:
            total_time += curr_time
            curr_time = 0
            print("CPU time for calculating tf-idf of {} docs: {}".format(i+1,total_time))
            graph_dict[i+1] = round(total_time,4)
            graph_interval.pop(0)

    graphfilename = 'out-graph.csv'
    graphfilepath = os.path.join(graphfilename)
    out = open(graphfilepath,'w')
    for key, value in graph_dict.items():
        out.write("{},{}\n".format(key,value))
    out.close()

    """# Plotting a graph"""
    x, y = [], []
    csvfile = open('out-graph.csv','r')
    lines = csv.reader(csvfile,delimiter=',')
    for row in lines:
        x.append(int(row[0]))
        y.append(float(row[1]))

    plt.plot(x,y,color='g',linestyle='dashed',marker='o',label='execution time')
    plt.xlabel('No. of documents')
    plt.ylabel('Time of execution (seconds)')
    plt.title('CPU execution speed vs No. of documents processed for TF-IDF calulation')
    plt.grid()
    plt.legend()
    plt.savefig('graph.png')
    plt.show()
    plt.close()
    csvfile.close()

if __name__ == "__main__":
    start()

# references : https://towardsdatascience.com/natural-language-processing-feature-engineering-using-tf-idf-e8b9d00e7e76
# https://towardsdatascience.com/tf-idf-for-document-ranking-from-scratch-in-python-on-real-world-dataset-796d339a4089


from fastapi import APIRouter
from fastapi.requests import Request
from fastapi.responses import Response
from piccolo.apps.user.tables import BaseUser
from piccolo_api.token_auth.tables import TokenAuth

from myk_trade.db.models.transactions import WalletModel

router = APIRouter()

@router.get("/")
async def get_profile(
    request: Request,
) -> dict:
    if request.user.is_authenticated is False:
        return Response(status_code=401, content="Unauthorized")

    user = (
        await BaseUser.select(
            exclude_secrets=True,
        )
        .where(
            BaseUser.id == request.user.user.id,
        )
        .first()
        .run()
    )
    return user

@router.get("/wallets")
async def get_wallets(
    request: Request,
) -> list:
    if request.user.is_authenticated is False:
        return Response(status_code=401, content="Unauthorized")

    wallets = (
        await WalletModel.select(
            exclude_secrets=True,
        )
        .where(
            WalletModel.user_id == request.user.user.id,
        )
        .run(nested=True)
    )
    return wallets

@router.get("/token")
async def get_token(
    request: Request,
) -> dict:
    if request.user.is_authenticated is False:
        return Response(status_code=401, content="Unauthorized")

    token = (
        await TokenAuth.select(
            TokenAuth.token,
            exclude_secrets=True,
        )
        .where(
            TokenAuth.user == request.user.user,
        )
        .first()
        .run()
    )
    return token  # {"token": token}

@router.post("/token")
async def create_token(
    request: Request,
) -> dict:
    if request.user.is_authenticated is False:
        return Response(status_code=401, content="Unauthorized")

    await TokenAuth.delete().where(
        TokenAuth.user == request.user.user,
    ).run()

    token = await TokenAuth.create_token(request.user.user.id)

    return {"token": token}


"""
Given folder of images and associated JSON label file, this script constructs corresponding class images (where each
colour is associated with a class).
If a region has a class-label 'nan' in the JSON file, then it is recorded in the image as 99 and adds one to the
'white count'.
The JSON file should be in the current working directory
"""

import os
import json
from PIL import Image, ImageDraw

def create_class_images(original_json, out_folder_suffix, data_dir, converter):
    """
    Assumes: all annotations in original_json have a corresponding JPEG image in either data_dir/train or data_dir/val

    Requires:
    - original_json: JSON file containing all annotations
    - out_folder_suffix: string; identifier that will be attached to the train and val folders
    - data_dir: directory containing train and val true-colour images, class image folders will be made here
    - converter: dictionary[string -> int]; maps class names to integer
    """
    # Import annotations
    with open(original_json) as jsonfile:
        labels = json.load(jsonfile)

    # Set folders to save class images to
    train_class_dir = os.path.join(data_dir, 'train_class_images_' + out_folder_suffix)
    if not os.path.exists(train_class_dir):
        os.makedirs(train_class_dir)
    val_class_dir = os.path.join(data_dir, 'val_class_images_' + out_folder_suffix)
    if not os.path.exists(val_class_dir):
        os.makedirs(val_class_dir)

    print(f"Processing: {original_json}...\n"
          f"Processing image number:", end="", flush=True)
    nan_count = 0
    for image_num, image_info in enumerate(labels.values()):
        # print progress
        if (image_num + 1) % 20 == 0:
            print(f"  {image_num + 1}", end="", flush=True)

        filename = image_info['filename']
        if filename in os.listdir(os.path.join(data_dir, 'train')):
            in_filepath = os.path.join(data_dir, 'train', filename)
            out_filepath = os.path.join(train_class_dir, filename)
        elif filename in os.listdir(os.path.join(data_dir, 'val')):
            in_filepath = os.path.join(data_dir, 'val', filename)
            out_filepath = os.path.join(val_class_dir, filename)

        # Get dimensions of original image
        image = Image.open(in_filepath)
        w, h = image.size

        # Construct class image
        class_image = Image.new(mode="P", size=(w, h), color=0)  # every pixel is initialised as black
        class_image1 = ImageDraw.Draw(class_image)
        for regions in image_info['regions']:
            polygon_info = regions['shape_attributes']
            xy = list(zip(polygon_info['all_points_x'], polygon_info['all_points_y']))

            class_name = regions['region_attributes']['label']
            if class_name in converter.keys():
                fill = converter[class_name]
            else:
                nan_count += 1

            class_image1.polygon(xy, fill=fill)

        # Save to disk (with same filename as original image)
        class_image.convert('RGB').save(out_filepath, "JPEG")

    # Print the number of nan entries
    print(f"\nNumber of NAN entries: {nan_count}")

if __name__ == "__main__":
    data_dir = os.path.join(os.getcwd(), "data_aug")

    manual_class_to_colours = {
        'water': 1,
        'vegetation': 2
    }
    create_class_images("manual_annotations_aug.json", "manual", data_dir, manual_class_to_colours)

    MW_class_to_colours = {
        'Artificial Surfaces': 1,
        'Bare or Lightly-vegetated Surfaces': 2,
        'Water Bodies': 3,
        'Cropland': 4,
        'Grassland, Sedgeland and Marshland': 5,
        'Scrub and Shrubland': 6,
        'Forest': 7
    }
#     create_class_images("MW_annotations_aug.json", "MW", data_dir, MW_class_to_colours)


import sympy

print(sympy.isprime(5))
count = 0
lists = []
for i in range(100,1000):
    if sympy.isprime(i) is True:
        count += 1
        lists.append(i)

print("100부터 1000까지의 소수 갯수{}",count)
print("소수 리스트",lists)

print(list(sympy.primerange(1,100)))


from django.utils.safestring import mark_safe
from django import template
from django.template.defaultfilters import striptags
from front.utils import states
from front.models import Startup

register = template.Library()

@register.filter(name='state_name')
def state_name_filter(value):
    try:
        return mark_safe(dict(states)[value])
    except KeyError:
        return mark_safe(value)

state_name_filter.is_safe = True

@register.filter(name='startup_name')
def startup_name_filter(value):
    try:
        startup = Startup.objects.get(owner__username=value)
        return mark_safe(startup.name)
    except:
        return value

startup_name_filter.is_safe = True


"""
Test LocalClient with normal FS operations and OS-specific ones (simulated).
See local_client_darwin.py and local_client_windows.py for more information.

See NXDRIVE-742.
"""
import hashlib
import os
from pathlib import Path

import pytest

from nxdrive.constants import ROOT, WINDOWS
from nxdrive.exceptions import DuplicationDisabledError, NotFound

from ..markers import not_linux, windows_only
from ..utils import random_png
from . import LocalTest
from .common import OneUserTest

if WINDOWS:
    import win32api

EMPTY_DIGEST = hashlib.md5().hexdigest()
SOME_TEXT_CONTENT = b"Some text content."
SOME_TEXT_DIGEST = hashlib.md5(SOME_TEXT_CONTENT).hexdigest()

class StubLocalClient:
    """
    All tests goes here. If you need to implement a special behavior for
    one OS, override the test method in the class TestLocalClientSimulation.
    Check TestLocalClientSimulation.test_complex_filenames() for a real
    world example.
    """

    def setUp(self):
        self.engine_1.start()
        self.wait_sync(wait_for_async=True)

    def test_make_documents(self):
        local = self.local_1
        doc_1 = local.make_file("/", "Document 1.txt")
        assert local.exists(doc_1)
        assert not local.get_content(doc_1)
        doc_1_info = local.get_info(doc_1)
        assert doc_1_info.name == "Document 1.txt"
        assert doc_1_info.path == doc_1
        assert doc_1_info.get_digest() == EMPTY_DIGEST
        assert not doc_1_info.folderish
        assert doc_1_info.size == 0

        doc_2 = local.make_file("/", "Document 2.txt", content=SOME_TEXT_CONTENT)
        assert local.exists(doc_2)
        assert local.get_content(doc_2) == SOME_TEXT_CONTENT
        doc_2_info = local.get_info(doc_2)
        assert doc_2_info.name == "Document 2.txt"
        assert doc_2_info.path == doc_2
        assert doc_2_info.get_digest() == SOME_TEXT_DIGEST
        assert not doc_2_info.folderish
        assert doc_2_info.size > 0

        local.delete(doc_2)
        assert local.exists(doc_1)
        assert not local.exists(doc_2)

        folder_1 = local.make_folder("/", "A new folder")
        assert local.exists(folder_1)
        folder_1_info = local.get_info(folder_1)
        assert folder_1_info.name == "A new folder"
        assert folder_1_info.path == folder_1
        assert folder_1_info.folderish
        # A folder has no size
        assert folder_1_info.size == 0

        doc_3 = local.make_file(folder_1, "Document 3.txt", content=SOME_TEXT_CONTENT)
        local.delete(folder_1)
        assert not local.exists(folder_1)
        assert not local.exists(doc_3)

    def test_get_info_invalid_date(self):
        local = self.local_1
        doc_1 = local.make_file("/", "Document 1.txt")
        os.utime(local.abspath("/Document 1.txt"), (0, 999999999999999))
        doc_1_info = local.get_info(doc_1)
        assert doc_1_info.name == "Document 1.txt"
        assert doc_1_info.path == doc_1
        assert doc_1_info.get_digest() == EMPTY_DIGEST
        assert not doc_1_info.folderish

    def test_complex_filenames(self):
        local = self.local_1
        # create another folder with the same title
        title_with_accents = "\xc7a c'est l'\xe9t\xe9 !"

        folder_1 = local.make_folder("/", title_with_accents)
        folder_1_info = local.get_info(folder_1)
        assert folder_1_info.name == title_with_accents

        # create another folder with the same title
        with pytest.raises(DuplicationDisabledError):
            local.make_folder("/", title_with_accents)

        # Create a long file name with weird chars
        long_filename = "\xe9" * 50 + "%$#!()[]{}+_-=';&^" + ".doc"
        file_1 = local.make_file(folder_1, long_filename)
        file_1 = local.get_info(file_1)
        assert file_1.name == long_filename
        assert file_1.path == folder_1_info.path / long_filename

        # Create a file with invalid chars
        invalid_filename = 'a/b\\c*d:e<f>g?h"i|j.doc'
        escaped_filename = "a-b-c-d-e-f-g-h-i-j.doc"
        file_2 = local.make_file(folder_1, invalid_filename)
        file_2 = local.get_info(file_2)
        assert file_2.name == escaped_filename
        assert file_2.path == folder_1_info.path / escaped_filename

    def test_missing_file(self):
        with pytest.raises(NotFound):
            self.local_1.get_info("/Something Missing")

    @pytest.mark.timeout(30)
    def test_case_sensitivity(self):
        local = self.local_1
        sensitive = local.is_case_sensitive()

        local.make_file("/", "abc.txt")
        if sensitive:
            local.make_file("/", "ABC.txt")
        else:
            with pytest.raises(DuplicationDisabledError):
                local.make_file("/", "ABC.txt")
        assert len(local.get_children_info("/")) == sensitive + 1

    @windows_only
    def test_windows_short_names(self):
        """
        Test 8.3 file name convention:
        https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
        """

        local = self.local_1
        remote = self.remote_document_client_1
        long_name = "a" * 32
        short_name = "AAAAAA~1"

        # Create the folder
        folder = local.make_file("/", long_name)
        with pytest.raises(DuplicationDisabledError):
            local.make_file("/", short_name)
        path = local.abspath(folder)
        assert path.name == long_name

        # Get the short name
        short = win32api.GetShortPathName(str(path))
        assert os.path.basename(short) == short_name

        # Sync and check the short name is nowhere
        self.wait_sync()
        children = remote.get_children_info(self.workspace)
        assert len(children) == 1
        assert children[0].name == long_name

    def test_get_children_info(self):
        local = self.local_1
        folder_1 = local.make_folder("/", "Folder 1")
        folder_2 = local.make_folder("/", "Folder 2")
        file_1 = local.make_file("/", "File 1.txt", content=b"foo\n")

        # not a direct child of '/'
        local.make_file(folder_1, "File 2.txt", content=b"bar\n")

        # ignored files
        data = b"baz\n"
        local.make_file("/", ".File 2.txt", content=data)
        local.make_file("/", "~$File 2.txt", content=data)
        local.make_file("/", "File 2.txt~", content=data)
        local.make_file("/", "File 2.txt.swp", content=data)
        local.make_file("/", "File 2.txt.lock", content=data)
        local.make_file("/", "File 2.txt.part", content=data)
        if local.is_case_sensitive():
            local.make_file("/", "File 2.txt.LOCK", content=data)
        else:
            with pytest.raises(DuplicationDisabledError):
                local.make_file("/", "File 2.txt.LOCK", content=data)

        workspace_children = local.get_children_info("/")
        assert len(workspace_children) == 3
        assert workspace_children[0].path == file_1
        assert workspace_children[1].path == folder_1
        assert workspace_children[2].path == folder_2

    def test_deep_folders(self):
        # Check that local client can workaround the default Windows
        # MAX_PATH limit
        local = self.local_1
        folder = "/"
        for _i in range(30):
            folder = local.make_folder(folder, "0123456789")

        # Last Level
        last_level_folder_info = local.get_info(folder)
        assert last_level_folder_info.path == Path("0123456789/" * 30)

        # Create a nested file
        deep_file = local.make_file(folder, "File.txt", content=b"Some Content.")

        # Check the consistency of get_children_info and get_info
        deep_file_info = local.get_info(deep_file)
        deep_children = local.get_children_info(folder)
        assert len(deep_children) == 1
        deep_child_info = deep_children[0]
        assert deep_file_info.name == deep_child_info.name
        assert deep_file_info.path == deep_child_info.path
        assert deep_file_info.get_digest() == deep_child_info.get_digest()

        # Update the file content
        local.update_content(deep_file, b"New Content.")
        assert local.get_content(deep_file) == b"New Content."

        # Delete the folder
        local.delete(folder)
        assert not local.exists(folder)
        assert not local.exists(deep_file)

        # Delete the root folder and descendants
        local.delete("/0123456789")
        assert not local.exists("/0123456789")

    def test_get_new_file(self):
        local = self.local_1
        path, os_path, name = local.get_new_file("/", "Document 1.txt")
        assert path == Path("Document 1.txt")
        assert str(os_path).endswith(
            os.path.join(self.workspace_title, "Document 1.txt")
        )
        assert name == "Document 1.txt"
        assert not local.exists(path)
        assert not os_path.exists()

    def test_get_path(self):
        local = self.local_1
        doc = Path("doc.txt")
        abs_path = self.local_nxdrive_folder_1 / self.workspace_title / doc
        assert local.get_path(abs_path) == doc

        # Encoding test
        assert local.get_path("été.txt") == ROOT

    def test_is_equal_digests(self):
        local = self.local_1
        content = b"joe"
        local_path = local.make_file("/", "File.txt", content=content)
        local_digest = hashlib.md5(content).hexdigest()
        # Equal digests
        assert local.is_equal_digests(local_digest, local_digest, local_path)

        # Different digests with same digest algorithm
        other_content = b"jack"
        remote_digest = hashlib.md5(other_content).hexdigest()
        assert local_digest != remote_digest
        assert not local.is_equal_digests(local_digest, remote_digest, local_path)

        # Different digests with different digest algorithms but same content
        remote_digest = hashlib.sha1(content).hexdigest()
        assert local_digest != remote_digest
        assert local.is_equal_digests(local_digest, remote_digest, local_path)

        # Different digests with different digest algorithms and different
        # content
        remote_digest = hashlib.sha1(other_content).hexdigest()
        assert local_digest != remote_digest
        assert not local.is_equal_digests(local_digest, remote_digest, local_path)

    def test_long_path(self):
        """NXDRIVE-1090: Long path names generates duplicata on folder creation.

        The final tree must be:
        .
        └── llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
            └── llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
                └── llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
                    ├── Par îçi
                    │   └── alive.png
                    └── stone.png
        """

        local = self.local_1
        remote = self.remote_document_client_1
        folder = "l" * 90
        folders = [self.workspace]

        self.engine_1.start()
        self.wait_sync(wait_for_async=True)

        # Remotely create 3 levels of folders, path will be > 270 chars
        for _ in range(3):
            folders.append(remote.make_folder(folders[-1], folder))

        # Create a file in it
        remote.make_file(folders[-1], "stone.png", content=random_png())
        picture = "/" + "/".join([folder] * 3) + "/stone.png"
        assert remote.exists(picture)

        # Check the whole tree is OK
        tree_needed = [1] * 4  # number of documents in each folder
        tree_current = [len(remote.get_children_info(fol)) for fol in folders]
        assert tree_needed == tree_current

        self.engine_1.start()
        self.wait_sync(wait_for_async=True)
        assert local.exists(picture)

        # Locally create a new folder and file in it
        path = "/" + "/".join([folder] * 3)
        local.make_folder(path, "Par îçi")
        path += "/Par îçi"
        local.make_file(path, "alive.png", random_png())
        picture = path + "/alive.png"
        assert local.exists(picture)

        self.wait_sync()

        # Check the whole tree is OK
        tree_needed = [1, 1, 1, 2]  # number of documents in each folder
        tree_current = [len(remote.get_children_info(fol)) for fol in folders]
        assert tree_needed == tree_current

        # Finally, check the last long folder contains only one folder and one file
        children = remote.get_children_info(folders[-1])
        assert children[0].name == "Par îçi"
        assert children[1].name == "stone.png"

        # And ensure the deepest folder "Par îçi" contains the lone file "alive.png"
        child = remote.get_children_info(children[0].uid)
        assert len(child) == 1
        assert child[0].name == "alive.png"

class TestLocalClientNative(StubLocalClient, OneUserTest):
    """
    Test LocalClient using Python commands to make FS operations.
    This will simulate Drive actions.
    """

    def get_local_client(self, path):
        return LocalTest(path)

    @pytest.mark.xfail(
        WINDOWS, raises=OSError, reason="Explorer cannot deal with very long paths"
    )
    def test_deep_folders(self):
        """
        It should fail on Windows:
            WindowsError: [Error 206] The filename or extension is too long
        Explorer cannot deal with very long paths.
        """
        super().test_deep_folders()

    def test_remote_changing_case_accentued_folder(self):
        """
        NXDRIVE-1061: Remote rename of an accentued folder on Windows fails.
        I put this test only here because we need to test the real implementation
        of LocalClient.rename().
        """

        local = self.local_1
        remote = self.remote_document_client_1

        # Step 1: remotely create an accentued folder
        root = remote.make_folder(self.workspace, "Project Hémodialyse")
        folder = remote.make_folder(root, "Pièces graphiques")

        self.wait_sync(wait_for_async=True)
        assert local.exists("/Project Hémodialyse")
        assert local.exists("/Project Hémodialyse/Pièces graphiques")

        # Step 2: remotely change the case of the subfolder
        remote.update(folder, properties={"dc:title": "Pièces Graphiques"})

        self.wait_sync(wait_for_async=True)
        children = local.get_children_info("/Project Hémodialyse")
        assert len(children) == 1
        assert children[0].name == "Pièces Graphiques"

@not_linux(reason="GNU/Linux does not use OS-specific LocalClient.")
class TestLocalClientSimulation(StubLocalClient, OneUserTest):
    """
    Test LocalClient using OS-specific commands to make FS operations.
    This will simulate user actions on:
        - Explorer (Windows)
        - File Manager (macOS)
    """

    @pytest.mark.xfail(
        WINDOWS,
        raises=OSError,
        reason="Explorer cannot find the directory as the path is way to long",
    )
    def test_complex_filenames(self):
        """OSError: [Errno 2] No such file or directory"""
        super().test_complex_filenames()

    @pytest.mark.xfail(
        WINDOWS, reason="Explorer cannot find the directory as the path is too long"
    )
    def test_long_path(self):
        """WindowsError: [Errno 3] The system cannot find the specified file"""
        super().test_long_path()

    @pytest.mark.xfail(
        WINDOWS, raises=OSError, reason="Explorer cannot deal with very long paths"
    )
    def test_deep_folders(self):
        """WindowsError: [Error 206] The filename or extension is too long"""
        super().test_deep_folders()


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import plotly.express as px
import unicodedata
import re
from helpers import get_more_specific_df, create_new_folder, inputpath, outputpath, get_play_description_from_number

'''
The following code can be used to produce an animation for a specific play in a
specific game. This animation can then be saved locally as a html file.

The plays and games can be looped through to produce multiple animations. Below
is an example of how to use the functions in the code. You may need to install
some of the packages above before using the code.
'''

def slugify(path, allow_unicode=False):
    """
    Taken from https://github.com/django/django/blob/master/django/utils/text.py
    Convert to ASCII if 'allow_unicode' is False. Convert spaces or repeated
    dashes to single dashes. Remove characters that aren't alphanumerics,
    underscores, or hyphens. Convert to lowercase. Also strip leading and
    trailing whitespace, dashes, and underscores.
    """
    if allow_unicode:
        path = unicodedata.normalize('NFKC', path)
    else:
        path = unicodedata.normalize('NFKD', path).encode('ascii', 'ignore').decode('ascii')
    path = re.sub(r'[^\w\s-]', '', path.lower())
    return re.sub(r'[-\s]+', '-', path).strip('-_')

def animation(csv, play_no, year, path=None, save_html=False, plotting=False):
    fig = px.scatter(csv, x='x', y='y', hover_name='displayName', color='team', animation_frame='frameId', range_x=[0, 120], range_y=[0, 53.3])
    # The plotly only needs the dataframe and some arguments to plot the positions
    fig.layout.updatemenus[0].buttons[0].args[1]['frame']['duration'] = 50
    fig.layout.updatemenus[0].buttons[0].args[1]['transition']['duration'] = 20
    if plotting == True:
        fig.show()
    if save_html == True:
        if path is not None:
            if len(path) < 200:
                writing_path = path
            else:
                writing_path = path[:200]
                # Only a certain length of string is allowed
            fig.write_html(outputpath+'Tracking_' + year + '\\Play' + str(play) + '\\' + writing_path + '.html')
            # Save the html of the plotly file
    return

def run_anim(year, playIndex):
    year = '2020'
    # Specifiy which year csv file to use
    plays_csv = pd.read_csv(inputpath+'plays.csv')
    # The csv for all the separate plays that have been used throughout all NFL games
    tracking_csv = pd.read_csv(inputpath+'tracking' + year + '.csv')
    # The csv with all the tracking data. All instances of a certain play can be taken from this
    plays = np.unique(tracking_csv['playId'])
    # All the different plays
    play = plays[playIndex]
    csv = get_more_specific_df(tracking_csv, 'playId', play)
    # A csv containing tracking data of all instances of the specific play
    games = np.unique(csv['gameId'])
    # All the games that the specific play has been used in
    game = games[0]
    # Generic 1st game
    new_csv = get_more_specific_df(csv, 'gameId', game)
    # A csv containing tracking data of all instances of the specific play used in a specific game
    save_string = get_play_description_from_number(plays_csv, play, game).iloc[0]
    # Generate the name of the html if you choose to save it
    create_new_folder(outputpath+'Tracking_' + year + '\\Play' + str(play))
    # Initialise a folder for an animation to be added to
    animation(new_csv, play, year, path=slugify(save_string), save_html=True, plotting=True)
    # Run the animation

run_anim('2020', 0)


import boto3
from botocore.exceptions import ClientError
import json
import os
import time
import datetime
from mako.template import Template

from antiope.aws_account import *
from antiope.vpc import *
from common import *

import logging
logger = logging.getLogger()
logger.setLevel(getattr(logging, os.getenv('LOG_LEVEL', default='INFO')))
logging.getLogger('botocore').setLevel(logging.WARNING)
logging.getLogger('boto3').setLevel(logging.WARNING)
logging.getLogger('urllib3').setLevel(logging.WARNING)

# Lambda main routine
def handler(event, context):
    set_debug(event, logger)
    logger.debug("Received event: " + json.dumps(event, sort_keys=True))

    # We will make a HTML Table and a Json file with this data
    json_data = {"vpcs": []}

    # Get and then sort the list of accounts by name, case insensitive.
    active_accounts = get_active_accounts()
    active_accounts.sort(key=lambda x: x.account_name.lower())

    for a in active_accounts:
        logger.debug(a.account_name)

        for v in a.get_vpcs():
            logger.debug(f"\tv.vpc_id")
            j = {}
            j['vpc'] = v.db_record.copy()
            j['account'] = a.db_record.copy()

            # Skip VPCs that have nothing in them
            if not hasattr(v, "instance_states"):
                continue
            if v.instance_states['running'] == 0 and v.instance_states['stopped'] == 0:
                continue

            j['instance_states'] = v.instance_states
            json_data['vpcs'].append(j)

    # Add some summary data for the Template
    json_data['timestamp'] = datetime.datetime.now()
    json_data['vpc_count'] = len(json_data['vpcs'])
    json_data['account_count'] = len(active_accounts)
    json_data['bucket'] = os.environ['INVENTORY_BUCKET']

    # Render the Webpage
    fh = open("html_templates/vpc_inventory.html", "r")
    mako_body = fh.read()
    result = Template(mako_body).render(**json_data)

    # Save HTML and json to S3
    s3_client = boto3.client('s3')
    try:
        response = s3_client.put_object(
            # ACL='public-read',
            Body=result,
            Bucket=os.environ['INVENTORY_BUCKET'],
            ContentType='text/html',
            Key='Reports/vpc_inventory.html',
        )

        # Save the JSON to S3
        response = s3_client.put_object(
            # ACL='public-read',
            Body=json.dumps(json_data, sort_keys=True, indent=2, default=str),
            Bucket=os.environ['INVENTORY_BUCKET'],
            ContentType='application/json',
            Key='Reports/vpc_inventory.json',
        )
    except ClientError as e:
        logger.error("ClientError saving report: {}".format(e))
        raise

    return(event)

if __name__ == '__main__':

    # Logging idea stolen from: https://docs.python.org/3/howto/logging.html#configuring-logging
    # create console handler and set level to debug
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)

    # create formatter
    # formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    formatter = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
    # add formatter to ch
    ch.setFormatter(formatter)
    # add ch to logger
    logger.addHandler(ch)

    os.environ['VPC_TABLE'] = "turner-antiope-dev-aws-inventory-vpc-inventory"
    os.environ['ACCOUNT_TABLE'] = "turner-antiope-dev-aws-inventory-accounts"
    os.environ['INVENTORY_BUCKET'] = "turner-antiope-dev"
    os.environ['ROLE_NAME'] = "GTO-ISO-Audit"
    os.environ['ROLE_SESSION_NAME'] = "Antiope"

    handler({}, {})


from django.shortcuts import render
from django.http import HttpResponse
from django.db.models import Q

from .models import FileUploadForm, FirmContacted
from django.db.models import Q
import json

from rest_framework.response import Response
from rest_framework.decorators import action
from rest_framework.pagination import LimitOffsetPagination
from rest_framework import viewsets
import operator
from functools import reduce

from .serializers import FirmContactedSerializer, FirmSerializer, EmailTemplateSerializer
from .models import Firm, EmailTemplate

from collections import OrderedDict

def to_boolean(string):
    return string == "True"

class EmailTemplateView(viewsets.ModelViewSet):
    pagination_class = None
    serializer_class = EmailTemplateSerializer
    queryset = EmailTemplate.objects.all()

class FirmContactedView(viewsets.ModelViewSet):
    serializer_class = FirmContactedSerializer
    queryset = FirmContacted.objects.all()

    @action(detail=False, methods=['POST'], name='/')
    def update_contacted(self, request):
        try:
            obj, created = FirmContacted.objects.update_or_create(**request.data, defaults={
                "user_id": request.data["user_id"],
                "orgnr": request.data["orgnr"],
                "contacted": not request.data["contacted"]
            })
        except Exception as e:
            return Response(f"Update or create failed: {e}")
        return Response("success")

class FirmView(viewsets.ModelViewSet):
    serializer_class = FirmSerializer
    pagination_class = LimitOffsetPagination
    queryset = Firm.objects.all()

    @action(detail=False, methods=['GET'], name='')
    def custom(self, request):

        queryset = Firm.objects.all().extra(select={'contacted': 'SELECT contacted FROM "app_firmcontacted" WHERE "app_firm".orgnr = "app_firmcontacted".orgnr'})

        if request.GET.get("email", None):
            queryset = queryset.exclude(email="[]")
        if request.GET.get("website", None):
            queryset = queryset.exclude(website="[]")
        if request.GET.get("telephone", None):
            queryset = queryset.exclude(telephone="[]")
        if request.GET.get("naering", None):
            nace_list = request.GET.get("naering").split("æsepæ")
            queryset = queryset.filter(nace__in=nace_list)
        if request.GET.get("employees", None):
            empl = json.loads(request.GET.get("employees"))
            queryset = queryset.filter(employees__gte=empl[0])
            queryset = queryset.filter(employees__lte=empl[1])
        if request.GET.get("municipality", None):
            print(request.GET.get("municipality"))
            municipalities = request.GET.get("municipality").split(",")
            print(municipalities)
            queryset = queryset.filter(municipality_nr__in=municipalities)
        print(queryset.query)
        count = queryset.count()
        queryset = LimitOffsetPagination().paginate_queryset(queryset=queryset, request=request)
        serializer = self.get_serializer(queryset, many=True)

        return Response(OrderedDict([
            ("results", serializer.data),
            ("count", count)
        ]))

def index(request):
    items = [f"doc{i}" for i in range(0)]
    if request.method == "POST":

        if request.FILES.get('file', False):

            form = FileUploadForm(request.POST, request.FILES)
            print(form)
            if form.is_valid():
                # Upload to S3 and get path
                path = "s3_path/document.csv"
                model = form.save(commit=False)
                print(model.__dict__)
                model.path = path
                model.save()

            file = request.FILES['file']
            items.append(file)
            return render(request, "app/index.html", {"upload_success": True, "documents": items})

    return render(request, "app/index.html", {"documents": items})


import pyautogui
import random
from random import uniform
from time import sleep, time

pyautogui.FAILSAFE = True

n = 4

for i in range(n):

 print("Starting..")
 print("You are killing Kraken: ", n, " times.")
 sleep(3)

#Top Right
 XtopRight = random.randint(1414, 1439)
 YtopRight = random.randint(453, 473)

 #Bot Right
 XbotRight= random.randint(1429, 1455)
 YbotRight = random.randint(579, 595)

 #Top Left
 XtopLeft = random.randint(1093, 1112)
 YtopLeft = random.randint(461, 477)

 #Bot Left
 XbotLeft = random.randint(1075, 1105)
 YbotLeft = random.randint(585, 605)

 #Center
 X = random.randint(1224, 1256)
 Y = random.randint(531, 557)

 KrakenWait = random.randint(55, 63)
 randomSec = random.uniform(1.9, 2.7)

 pyautogui.moveTo(XtopRight,YtopRight)
 print("X = ", XtopRight, "Y = ", YtopRight)
 pyautogui.click()
 print("click top right")
 sleep(randomSec)

 pyautogui.moveTo(XbotRight,YbotRight)
 print("X = ", XbotRight, "Y = ", YbotRight)
 pyautogui.click()
 print("click bot right")
 sleep(randomSec)

 pyautogui.moveTo(XtopLeft,YtopLeft)
 print("X = ", XtopLeft, "Y = ", YtopLeft)
 pyautogui.click()
 print("click top left")
 sleep(randomSec)

 pyautogui.moveTo(XbotLeft,YbotLeft)
 print("X = ", XbotLeft, "Y = ", YbotLeft)
 pyautogui.click()
 print("click bot left")
 sleep(randomSec)

 pyautogui.moveTo(X,Y)
 pyautogui.click()
 print("CENTER!")
 sleep(KrakenWait)


import json
import logging
import re

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def hello_endpoint(event, context):
  logger.info(event)

  body = {
    "message": "Hello world!"
  }

  response = {
    "statusCode": 200,
    "body": json.dumps(body)
  }

  return response

def sum_endpoint(event, context):
  logger.info(event)

  # Default response
  body = {
    "error": "Please provide at least one number e.g. numbers=1,2,3"
  }

  if 'body' in event and event['body'] is not None:
    # Regex that matches "numbers=1,2,33"
    r = re.compile("^numbers=([-+]?([1-9]\\d*|0),?)+$")
    # Get numbers from post data
    numbers = list(filter(r.match, event['body'].split('&')))
    if len(numbers) > 0:
      numbers = numbers[0].replace('numbers=', '')
      numbers = numbers.split(',')
      body = {
        "sum": sum(map(int, numbers))
      }

  response = {
    "statusCode": 200,
    "body": json.dumps(body)
  }

  return response


#!/usr/bin/env python3
"""Module with new authentication mechanism"""
from api.v1.auth.session_auth import SessionAuth
from os import getenv
from datetime import datetime, timedelta

class SessionExpAuth(SessionAuth):
    """A class that inherits from sessionAuth"""

    def __init__(self):
        """A function that initializes the instance of SessionExpAuth"""
        try:
            self.session_duration = int(getenv('SESSION_DURATION', 0))
        except ValueError:
            self.session_duration = 0

    def create_session(self, user_id=None):
        """A function that creates a Session ID for a user_id"""
        session_id = super().create_session(user_id)
        if session_id is None:
            return None

        SessionExpAuth.user_id_by_session_id[session_id] = {
            'user_id': user_id,
            'created_at': datetime.now()
        }

        return session_id

    def user_id_for_session_id(self, session_id=None):
        """A function that returns a User ID based on a Session ID"""
        if session_id is None:
            return None

        session_dict = SessionExpAuth.user_id_by_session_id.get(
            session_id, None)
        if session_dict is None:
            return None
        if 'created_at' not in session_dict:
            return None

        if self.session_duration <= 0:
            return session_dict.get('user_id')

        creation_time = session_dict.get('created_at')

        session_length = timedelta(seconds=self.session_duration)

        expiry_time = creation_time + session_length

        if expiry_time < datetime.now():
            return None
        return session_dict.get('user_id')


# Femto_Luci10.py, Femto Amplifier remote interface
# Joonas Govenius <joonas.govenius@aalto.fi>, 2013
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

from instrument import Instrument
import visa
import types
import logging
import time
import ctypes
import numpy as np

class Femto_Luci10(Instrument):
  '''
  Driver for Femto Luci-10 remote interface for amplifiers.

  Usage:
  Initialize with
  <name> = instruments.create('name', 'Femto_Luci10', address='<GPIB address>',
      device_type, reset=<bool>)

  device_type must be one of: ['DLPVA-100-B-D']

  Also note that the manual switches must be set to the correct positions
  for remote operation, as specified in the amplifier manual.
  '''

  def __init__(self, name, address, device_type, reset=False, dll_path=r'C:\Program Files (x86)\FEMTO\LUCI-10\Driver\LUCI_10.dll'):
    '''
    Initializes the Femto_Luci10.

    Input:
        name (string)    : name of the instrument
        address (int)    : interface ID (between 0 and 255, default: 0 for Luci-10)
        reset (bool)     : resets to default values, default=false
        device_type      : one of ['DLPVA-100-B-D']

    Also note that the manual switches must be set to the correct positions
    for remote operation, as specified in the amplifier manual.
    '''
    logging.info(__name__ + ' : Initializing instrument Femto_Luci10')
    Instrument.__init__(self, name, tags=['physical'])
    self._interface_id = address
    self._device_type = device_type

    if device_type == 'DLPVA-100-B-D':

      # (pin no, state that implies overload)
      self._overload_pin = (5,1)

      # (bit no, state that gives ac_mode), e.g. (3, 0) means that bit no 3 being 0 implies AC mode
      self._ac_coupling_bit = (3,0)

      # e.g. 1000: [ (2, 1), (1, 0) ] means that bit_2 == 1 and bit_1 == 0 --> gain of 1000.
      # (bits 0-7  == low byte)
      # (bits 8-15 == high byte)
      self._gains = { 10:    [ (2, 0) , (1, 0) ],
                      100:   [ (2, 0) , (1, 1) ],
                      1000:  [ (2, 1) , (1, 0) ],
                      10000: [ (2, 1) , (1, 1) ] }

      # same format as for gain.
      self._bandwidths = { 1000:   [ (4,0) ],
                           100000: [ (4,1) ] }
    else:
      raise Exception('Unknown device type: %s' % (device_type))

    self._last_communication_time = time.time()

    # Max communication rate is 300 Hz.
    self._min_time_between_commands = 0.010  # in second

    self._dll = ctypes.cdll.LoadLibrary(dll_path)

    self._find_device()

    self.add_parameter('overload', type=types.BooleanType, flags=Instrument.FLAG_GET)

    self.add_parameter('gain', type=types.IntType, flags=(Instrument.FLAG_SET|Instrument.FLAG_PERSIST),
                        minval=10, maxval=10000)

    self.add_parameter('bandwidth', type=types.IntType, flags=(Instrument.FLAG_SET|Instrument.FLAG_PERSIST),
                        minval=1, maxval=100000, units='Hz')

    self.add_parameter('ac_coupling', type=types.BooleanType, flags=(Instrument.FLAG_SET|Instrument.FLAG_PERSIST))

    self.add_function('reset')
    self.add_function('get_all')

    if reset: self.reset()
    self.get_all()

    # turn the LED off and on to signal success
    self._set_led(False)
    time.sleep(.5)
    self._set_led(True)

  def reset(self):
    '''
    Resets the instrument to default values

    Input:
        None

    Output:
        None
    '''
    logging.info(__name__ + ' : Resetting instrument')
    self.set_gain(10)

  def get_all(self):
    '''
    Reads all implemented parameters from the instrument,
    and updates the wrapper.

    Input:
        None

    Output:
        None
    '''
    logging.info(__name__ + ' : reading all settings from instrument')

    self.get_overload()

  def _find_device(self):
    t = time.time()
    t_to_sleep = self._min_time_between_commands - (t - self._last_communication_time)
    if t_to_sleep > 0: time.sleep(t_to_sleep)

    no_of_devs = self._dll.EnumerateUsbDevices()
    if no_of_devs == 0: raise Exception('No Femto LUCI interfaces found!')
    time.sleep(self._min_time_between_commands)

    #logging.debug('No of USB devices found: %s' % str(no_of_devs))
    for i in range(1,1+no_of_devs):
      adapter_id = self._dll.ReadAdapterID(i)
      #logging.debug('adapter_id returned by USB device #%d: %s' % (i,adapter_id))
      if adapter_id == self._interface_id:
        self._usb_device_id = i
        return

    raise Exception('Specified Femto LUCI interface (ID = %d) not found!' % (self._interface_id))

  def _read(self, pin_no):
    '''
    Read the status of an input pin.
    '''
    for attempt in range(3):
      try:
        t = time.time()
        t_to_sleep = self._min_time_between_commands - (t - self._last_communication_time)
        if t_to_sleep > 0: time.sleep(t_to_sleep)
        if t_to_sleep < -1.: self._find_device() # update USB id

        r = getattr(self._dll, 'GetStatusPin%d' % pin_no)(ctypes.c_int(self._usb_device_id))
        self._last_communication_time = time.time()

        if not (r == 0 or r == 1):
          raise Exception('Failed to read pin #%u to device. Got %s' % (pin_no, r))

        return bool(r)
      except Exception as e:
        logging.warn('Failed to communicate with the amp: %s' % str(e))
        self._last_communication_time = time.time()
        time.sleep( .2 )
        self._clear_mainframe_output_buffer()
        time.sleep( .2+attempt )

  def _write(self, lowbyte, highbyte):
    '''
    Write the low and high output bytes. See also set_parameters.
    '''
    for attempt in range(3):
      try:
        t = time.time()
        t_to_sleep = self._min_time_between_commands - (t - self._last_communication_time)
        if t_to_sleep > 0: time.sleep(t_to_sleep)
        if t_to_sleep < -1.: self._find_device() # update USB id

        r = self._dll.WriteData(ctypes.c_int(self._usb_device_id), ctypes.c_int(lowbyte), ctypes.c_int(highbyte))
        if r != 0: raise Exception('Failed to write %u,%u to device. Got "%s".' % (lowbyte, highbyte, r))
        self._last_communication_time = time.time()

        return

      except Exception as e:
        logging.warn('Failed to write to LUCI: %s' % str(e))
        self._last_communication_time = time.time()
        time.sleep( .2 )
        self._clear_mainframe_output_buffer()
        time.sleep( .2+attempt )

  def _set_outputs(self, gain=None, bandwidth=None, ac_coupling=None):
    '''
    Change outputs to the specified values. If None, the previous value is used.

    This is a more convenient wrapper for the lower level method _write().
    '''
    # get previous value if None
    if gain == None: gain = self._get_value('gain', query=False)
    if bandwidth == None: bandwidth = self._get_value('bandwidth', query=False)
    if ac_coupling == None: ac_coupling = self._get_value('ac_coupling', query=False)

    # If still None (i.e. no previous value) use a reasonable default.
    if gain == None:
      gain = sorted(self._gains.keys())[0]
      logging.warn('Previous gain unknown. Using %g' % gain)
    if bandwidth == None:
      bandwidth = sorted(self._bandwidths.keys())[-1]
      logging.warn('Previous bandwidth unknown. Using %g' % bandwidth)
    if ac_coupling == None:
      ac_coupling = False
      logging.warn('Previous AC coupling value unknown. Using %s' % str(ac_coupling))

    outputs = 0
    outputs |= int(ac_coupling == bool(self._ac_coupling_bit[1])) << self._ac_coupling_bit[0]

    assert gain in self._gains.keys(), 'Unknown gain: %s' % (gain)
    for bit,state in self._gains[gain]:
      outputs |= int(bool(state)) << bit

    assert bandwidth in self._bandwidths.keys(), 'Unknown bandwidth: %s' % (bandwidth)
    for bit,state in self._bandwidths[bandwidth]:
      outputs |= int(bool(state)) << bit

    self._write(outputs % 256, outputs >> 8)
    self.update_value('gain', gain)
    self.update_value('bandwidth', bandwidth)
    self.update_value('ac_coupling', ac_coupling)

  def _set_led(self, on):
    for attempt in range(3):
      try:
        t = time.time()
        t_to_sleep = self._min_time_between_commands - (t - self._last_communication_time)
        if t_to_sleep > 0: time.sleep(t_to_sleep)
        if t_to_sleep < -1.: self._find_device() # update USB id

        if on: self._dll.LedOn(ctypes.c_int(self._usb_device_id))
        else:  self._dll.LedOff(ctypes.c_int(self._usb_device_id))
        self._last_communication_time = time.time()

      except Exception as e:
        logging.warn('Failed to change LUCI led state to %s: %s' % (str(on), str(e)))
        self._last_communication_time = time.time()
        time.sleep( .2 )
        self._clear_mainframe_output_buffer()
        time.sleep( .2+attempt )

  def do_set_gain(self, gain):
    '''
    Sets the gain of the amplifier.
    NOTE: Assumes a certain position of the manual switches! (See device manual.)

    Input:
        gain (int) : allowed values are device dependent
    '''
    self._set_outputs(gain=gain)

  def do_set_bandwidth(self, bandwidth):
    '''
    Sets the bandwidth of the amplifier.
    NOTE: Assumes a certain position of the manual switches! (See device manual.)

    Input:
        bandwidth (int) : allowed values are device dependent
    '''
    self._set_outputs(bandwidth=bandwidth)

  def do_set_ac_coupling(self, ac_coupling):
    '''
    Sets AC coupling on/off (off --> DC coupling).
    NOTE: Assumes a certain position of the manual switches! (See device manual.)

    Input:
        ac_coupling (bool) : AC (True) or DC (False) coupling
    '''
    self._set_outputs(ac_coupling=ac_coupling)

  def do_get_overload(self):
    '''
    Gets the overload status of the amplifier.

    Output:
        overload (bool) : whether amplifier is overloaded
    '''
    return self._read(self._overload_pin[0]) == self._overload_pin[1]


from numpy import asarray
from scipy.spatial import Delaunay

from compas.datastructures.mesh import Mesh

__author__    = 'Tom Van Mele'
__copyright__ = 'Copyright 2016, Block Research Group - ETH Zurich'
__license__   = 'MIT license'
__email__     = 'vanmelet@ethz.ch'

__all__ = [
    'delaunay_from_mesh',
    'delaunay_from_points',
    'delaunay_from_boundary',
]

def delaunay_from_mesh(mesh):
    """Return a Delaunay triangulation from a given mesh.

    Parameters:
        mesh (compas.datastructures.mesh.Mesh) :
            The original mesh.

    Returns:
        mesh :
            ...

    >>> ...

    """
    d = Delaunay(mesh.xy)
    return Mesh.from_vertices_and_faces(mesh.xyz, d.simplices)

def delaunay_from_points(points):
    """"""
    xyz = asarray(points)
    assert 2 <= xyz.shape[1], "At least xy xoordinates required."
    d = Delaunay(xyz[:, 0:2])
    return Mesh.from_vertices_and_faces(points, d.simplices)

# @see: _scripts
def delaunay_from_boundary(boundary):
    """"""
    raise NotImplementedError

# ==============================================================================
# Debugging
# ==============================================================================

if __name__ == "__main__":
    pass


from flask import g
import re

'''
This is a helper class to parse
CloudWatch slow query log events
'''

regexPerformance = re.compile(
    r"^# Query_time:\s+(\d+\.\d+)\s+Lock_time:\s+(\d+\.\d+)\s+Rows_sent:\s+(\d+)\s+Rows_examined:\s+(\d+)"
)

regexUserInfo = re.compile(
    r"^# User@Host:\s+(\S+)\s+@\s+(.*)\s+Id:\s+(\d+)"
)

regexLinesToIgnore = [
    re.compile(r"^#"),
    re.compile(r"^use ", re.I),
    re.compile(r"^set ", re.I)
]

class CWEvent:
    """
    static regex patterns used in the parse_log_entry function
    """

    def __init__(self, event):
        self._event = event

    @staticmethod
    def skip_line(line):
        for regex in regexLinesToIgnore:
            if bool(regex.match(line)):
                g.logger.debug("IGNORE: {}".format(line))
                return True
        return False

    def parse(self):
        cw_event = self._event
        query = None
        query_time = None
        lock_time = None
        sent = None
        rows = None
        host = None
        user = None
        log_session = None
        for line in cw_event['message'].splitlines():
            g.logger.debug("LINE: {}".format(line))
            user_info = regexUserInfo.match(line)
            if user_info:
                query = ""
                user = user_info.group(1)
                host = user_info.group(2)
                log_session = user_info.group(3)
                continue

            if bool(re.match('^# Query_time:', line)):
                query = ""
                g.logger.debug("QT LIKELY: {}".format(line))
                m = regexPerformance.match(line)
                if m:
                    query_time = float(m.group(1))
                    lock_time = float(m.group(2))
                    sent = int(m.group(3))
                    rows = int(m.group(4))
                    g.logger.debug("QT OK: {} {}".format(query_time, rows))
                else:
                    g.logger.debug("QT ERROR: {}".format(line))
                continue

            if self.skip_line(line):
                continue

            query = query + line + "\t"

        # done with the entry... do we have a pending query to output
        if any(x is None for x in [rows, query_time, lock_time, user, host]):
            g.logger.info("PARSE_FAILED: {}".format(cw_event))
            g.logger.info("PARSE_FAILED: {} {} {} {} {}".format(
                rows,
                query_time,
                lock_time,
                user,
                host
            ))
        return {
            'event': cw_event,
            'qtime': query_time,
            'session': log_session,
            'rows': rows,
            'sent': sent,
            'ltime': lock_time,
            'query': query,
            'raw': cw_event['message'],
            'timestamp': cw_event['timestamp']
        }


import os
import json as json
from focalnet.focalnet import FocalNet
from focalnet.download_weights import download_checkpoint, FOLDER_WEIGHTS
from tensorflow.keras import Model
from tensorflow.keras.layers import Input
IMAGENET_DEFAULT_MEAN = (0.485, 0.456, 0.406)
IMAGENET_DEFAULT_STD = (0.229, 0.224, 0.225)

def imagenet_1k():
    root_dir = os.path.sep.join(os.path.abspath(__file__).split(os.path.sep)[:-1])
    data = json.load(open(os.path.join(root_dir, "imagenet-1k.json"), 'r'))
    idx2label = [data[str(k)][1] for k in range(len(data))]
    return idx2label

def imagenet_22k():
    root_dir = os.path.sep.join(os.path.abspath(__file__).split(os.path.sep)[:-1])
    data = json.load(open(os.path.join(root_dir, "imagenet-22k-reorder.json"), 'r'))
    idx2label = [data[str(k)]  for k in range(len(data))]
    return idx2label

imagenet1k = imagenet_1k()
imagenet22k = imagenet_22k()

def load_focalnet(model_name, input_shape=(224, 224, 3), pretrained=False, return_model=False, num_classes=None, **kwargs):
    #print(kwargs)
    focal_levels=[2,2,2,2]
    focal_windows = [3, 3, 3, 3]
    use_conv_embed = False
    use_postln = False
    use_layerscale = False
    normalize_modulator = False
    use_postln_in_modulation=False

    if model_name == "focalnet_tiny_srf":
        depths = [2, 2, 6, 2]
        embed_dim=96
        default_classes = 1000
    elif model_name == "focalnet_tiny_lrf":
        depths = [2, 2, 6, 2]
        embed_dim = 96
        focal_levels=[3, 3, 3, 3]
        default_classes = 1000
    elif model_name == "focalnet_small_srf":
        depths = [2, 2, 18, 2]
        embed_dim=96
        default_classes = 1000
    elif model_name == "focalnet_small_lrf":
        depths = [2, 2, 18, 2]
        embed_dim = 96
        focal_levels=[3, 3, 3, 3]
        default_classes = 1000
    elif model_name == "focalnet_base_srf":
        depths = [2, 2, 18, 2]
        embed_dim = 128
        default_classes = 1000
    elif model_name == "focalnet_base_lrf":
        depths = [2, 2, 18, 2]
        embed_dim = 128
        focal_levels=[3, 3, 3, 3]
        default_classes = 1000
    elif model_name == "focalnet_large_fl3":
        depths = [2, 2, 18, 2]
        embed_dim = 192
        focal_levels=[3, 3, 3, 3]
        focal_windows = [5, 5, 5, 5]
        use_conv_embed = True
        use_postln = True
        use_layerscale =   True
        default_classes = 21842
    elif model_name == "focalnet_large_fl4":
        depths = [2, 2, 18, 2]
        embed_dim = 192
        focal_levels = [4, 4, 4, 4]
        focal_windows =[3, 3, 3, 3]
        use_conv_embed = True
        use_postln = True
        use_layerscale = True
        normalize_modulator = True
        default_classes = 21842
    elif model_name == "focalnet_xlarge_fl3":
        depths = [2, 2, 18, 2]
        embed_dim = 256
        focal_levels=[3, 3, 3, 3]
        focal_windows = [5, 5, 5, 5]
        use_conv_embed = True
        use_postln = True
        use_layerscale = True
        default_classes = 21842
    elif model_name == "focalnet_xlarge_fl4":
        depths = [2, 2, 18, 2]
        embed_dim = 256
        focal_levels=[4, 4, 4, 4]
        focal_windows =[3, 3, 3, 3]
        use_conv_embed = True
        use_postln = True
        use_layerscale = True
        default_classes = 21842
    elif model_name == "focalnet_huge_fl3":
        depths = [2, 2, 18, 2]
        embed_dim = 352
        focal_levels=[3, 3, 3, 3]
        focal_windows =[3, 3, 3, 3]
        use_conv_embed = True
        use_postln = True
        use_layerscale = True
        use_postln_in_modulation= True
        default_classes = 21842
    elif model_name == "focalnet_huge_fl4":
        depths = [2, 2, 18, 2]
        embed_dim = 352
        focal_levels=[4, 4, 4, 4]
        focal_windows =[3, 3, 3, 3]
        use_conv_embed = True
        use_postln = True
        use_layerscale = True
        use_postln_in_modulation= True
        default_classes = 21842
    else:
        raise("model name not found")

    if "use_layerscale" in kwargs:
        use_layerscale = kwargs["use_layerscale"]
        del kwargs["use_layerscale"]

    if "use_conv_embed" in kwargs:
        use_conv_embed = kwargs["use_conv_embed"]
        del kwargs["use_conv_embed"]

    if "use_postln" in kwargs:
        use_postln = False
        del kwargs["use_postln"]

    if "normalize_modulator" in kwargs:
        normalize_modulator = kwargs["normalize_modulator"]
        del kwargs["normalize_modulator"]

    if "use_postln_in_modulation" in kwargs:
        use_postln_in_modulation= kwargs["use_postln_in_modulation"]
        del kwargs["use_postln_in_modulation"]

    if num_classes is None and pretrained:
        num_classes = default_classes
    elif num_classes is None:
        num_classes = 0

    backbone = FocalNet(depths=depths, embed_dim=embed_dim, focal_windows=focal_windows, focal_levels=focal_levels, use_conv_embed=use_conv_embed, use_postln=use_postln,
                        use_layerscale=use_layerscale, normalize_modulator=normalize_modulator, use_postln_in_modulation=use_postln_in_modulation, num_classes=num_classes, **kwargs)
    if pretrained:
        root_dir = os.path.sep.join(os.path.abspath(__file__).split(os.path.sep)[:-1])
        filename = f"{root_dir}/{FOLDER_WEIGHTS}/{model_name}.h5"
        #print(filename)
        if not os.path.exists(filename):
            # download
            download_checkpoint(model_name)
            #print("file not here")

        backbone.load_weights(filename, by_name=True, skip_mismatch=True)

    if return_model:
        inputs = Input(input_shape)
        outputs = backbone(inputs)
        model = Model(inputs=inputs, outputs=outputs)
        return model
    return backbone


import sys
import openai

SYSTEM_PROMPT = "You are an expert Python machine learning developer."

class MaxTokensExceeded(BaseException):
    pass

def set_openai_api_key(api_key):
    openai.api_key = api_key

def call_gpt(messages, *, temperature=0.5):
    if type(messages) == str:
        messages = [{"role": "user", "content": messages}]

    try:
        response = openai.ChatCompletion.create(
            model="gpt-4",  # gpt-4-32k
            messages=[
                {
                    "role": "system",
                    "content": SYSTEM_PROMPT,
                },
            ]
            + messages,
            n=1,
            stop=None,
            temperature=temperature,
            stream=True,
        )
    except openai.error.RateLimitError as e:
        time.sleep(10)
        print(
            "Exceeded OpenAI rate limit, sleeping for ten seconds and retrying...",
            file=sys.stderr,
        )
        return call_gpt(messages, temperature=temperature)
    except openai.error.InvalidRequestError as e:
        if "This model's maximum context length is" in str(e):
            raise MaxTokensExceeded()
        raise

    text = ""
    for chunk in response:
        if not chunk:
            continue
        chunk_text = chunk["choices"][0]["delta"].get("content", None)
        if chunk_text == None:
            continue
        text += chunk_text
        sys.stderr.write(chunk_text)
        sys.stderr.flush()

    sys.stderr.write("\n")

    return text


import os
import subprocess
import sys
import re
from collections import defaultdict

BWA = "bwa"
SAMTOOLS = "samtools"
CDHIT = "cd-hit"
BLASTN = "blastn"
TEMPDIR = "."

def checkDependencies():
    cmd = [BWA]
    try:
        p = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    except:
        sys.exit("Error: bwa not installed!")

    cmd = [SAMTOOLS, "--version"]
    try:
        p = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    except:
        sys.exit("Error: samtools not installed!")

    cmd = [CDHIT]
    try:
        p = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    except:
        sys.exit("Error: CD-HIT not installed!")

    cmd = [BLASTN]
    try:
        p = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    except:
        sys.exit("Error: Blastn not installed!")

def preprocess():
    os.chdir(TEMPDIR)

def readSoftClips(file):
    os.system("rm *.fa")
    # read softclip file
    f= open(file,'r')
    #leftDict stores the sequences that matched sequence is on right side and softclip is on left side
    leftDict_softclip=defaultdict(list)
    leftDict_virusSeq=defaultdict(list)
    #rightDict stores the sequences that matched sequence is on left side and softclip is on right side
    rightDict_softclip=defaultdict(list)
    rightDict_virusSeq=defaultdict(list)
    for line in open(file):
        line = f.readline()
        subStr= line.split('\t')
        match1 = re.search(r'^(\d+)M(\d+)S$', subStr[3])
        match2 = re.search(r'^(\d+)S(\d+)M$', subStr[3])
        if match1:
            pos1 = int(match1.group(1))
            pos2 = int(match1.group(2))
            if pos1>=15 and pos2>=15:
                softclip = subStr[4][pos1:]
                virusSeq = subStr[4][0:pos1]
                breakpoint = int(subStr[1])+pos1
                leftDict_softclip[breakpoint].append(softclip)
                if breakpoint in leftDict_virusSeq:
                    if len(virusSeq) > leftDict_virusSeq[breakpoint]:
                        leftDict_virusSeq[breakpoint] = virusSeq
                else:
                    leftDict_virusSeq[breakpoint].append(virusSeq)
        if match2:
            pos1 = int(match2.group(1))
            pos2 = int(match2.group(2))
            if pos1>=15 and pos2>=15:
                softclip = subStr[4][0:pos1]
                virusSeq = subStr[4][pos1:]
                breakpoint = int(subStr[1])
                rightDict_softclip[breakpoint].append(softclip)
                if breakpoint in rightDict_virusSeq:
                    if len(virusSeq) > rightDict_virusSeq[breakpoint]:
                        rightDict_virusSeq[breakpoint] = virusSeq
                else:
                    rightDict_virusSeq[breakpoint].append(virusSeq)
    f.close()

    # write breakpoints into fa files
    for keyname, seqList in rightDict_softclip.items():
        f2=open("right_breakpoint"+str(keyname)+".fa", 'w+')
        count2=1
        for seq in seqList:
            f2.writelines("> seq"+str(count2)+'\n')
            f2.writelines(seq+'\n')
            count2=count2+1
        f2.close()

    for keyname, seqList in leftDict_softclip.items():
        f2=open("left_breakpoint"+str(keyname)+".fa", 'w+')
        count2=1
        for seq in seqList:
            f2.writelines("> seq"+str(count2)+'\n')
            f2.writelines(seq+'\n')
            count2=count2+1
        f2.close()

def main():
    checkDependencies()
    preprocess()
    readSoftClips(file='HPV16.softclip.txt')

if __name__ == "__main__":
	main()


import os

import tenacity

def retry_check_function_return_value_condition(
        f, check_condition, error_msg=None, retry_interval=1,
        retry_attempts=20):
    """Check if function f returns value s.t check_condition(value) is True."""

    @tenacity.retry(stop=tenacity.stop_after_attempt(retry_attempts),
                    wait=tenacity.wait_fixed(retry_interval))
    def retried_function():
        r = f()
        if not check_condition(r):
            raise Exception(error_msg or
                            'Actual return value ({}) does not satisfy '
                            'provided condition'.format(r))
        return r

    return retried_function()

def retry_check_function_return_value(f, expected_value, error_msg=None):
    """Check if function f returns expected value."""
    if not error_msg:
        error_msg = 'Expected value "%s" not found' % expected_value
    retry_check_function_return_value_condition(
        f, lambda v: v == expected_value, error_msg)

def retry_on_exception(f):
    """Decorator to retry on an exception."""
    def wrapper():
        try:
            return f()
        except Exception:
            return False
    return wrapper

def root_path():
    """Return path to root of source code."""
    x = os.path.realpath(__file__)
    x, y = os.path.split(x)  # drop "helper.py"
    x, y = os.path.split(x)  # drop "scenario"
    x, y = os.path.split(x)  # drop "tests"
    x, y = os.path.split(x)  # drop "congress_tempest_plugin"
    return x


import time
import websocket
from datetime import datetime

from PySide6.QtCore import QRunnable

from globals import Globals

class Conditioner(QRunnable):
    """
    Conditioner thread
    """

    def run(self):

        while True:
            microTime = int(datetime.now().strftime('%S'))
            if microTime == 35:
                try:
                    """sessionTime = int(datetime.now().strftime('%H'))
                    if not (sessionTime >= Globals.INSTRUMENTS[Globals.PAIR]['SESSION'][0] and sessionTime <
                            Globals.INSTRUMENTS[Globals.PAIR]['SESSION'][1]):
                        Globals.instrumentAllowed = False
                        continue"""

                    Globals.availableAssets = Globals.iqoapi.get_all_open_time()
                    if not Globals.availableAssets['turbo']['EURUSD']['open']:
                        Globals.instrumentAllowed = False
                        continue

                    """availableLeverage = Globals.iqoapi.get_available_leverages(Globals.INSTRUMENTS[Globals.PAIR]['TYPE'], Globals.INSTRUMENTS[Globals.PAIR]['ID'])
                    if not availableLeverage[1]['leverages'][0]['regulated'].count(Globals.INSTRUMENTS[Globals.PAIR]['LEVERAGE']) > 0:
                        Globals.instrumentAllowed = False
                        continue"""

                    Globals.instrumentAllowed = True
                    continue

                except (TypeError, websocket.WebSocketException) as e:
                    Globals.isConnected = False
                except:
                    Globals.instrumentAllowed = False
                    pass
            time.sleep(Globals.HIGH_PRIORITY_MS)


#!/usr/bin/env python3
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import obspy.core.event.catalog, obspy.geodetics.base
from obspy.clients.fdsn import Client as fdsnClient
from numpy import mean,std
from sys import argv
golden = (1 + 5 ** 0.5) / 2

"""
Displaying WMTS tiled map data
------------------------------

This displays imagery from a web map tile service and seismic events from an FDSN web service. This result can also be interactively panned and zoomed.

"""

def plot_eq(ax,m,marker,color=None,**opts):

    o=m.origin_id.get_referred_object()
    desc='%.3g km deep %s%.2g\nat %s\nby %s (%s)'%(o.depth/1000,m.magnitude_type,m.mag,m.creation_info.creation_time,m.creation_info.author,m.creation_info.agency_id)
    ax.plot(o.longitude,o.latitude,marker,color='w',zorder=1,markeredgewidth=6,**opts)
    ax.plot(o.longitude,o.latitude,marker,color='k',zorder=2,markeredgewidth=1,**opts)
    if color is not None:
        opts['color']=color
    ax.plot(o.longitude,o.latitude,marker,zorder=3,markeredgewidth=0,**opts,label=desc)

def plot_wms(self,
             fdsnws_uri='ETH',
             wms = 'https://wms.geo.admin.ch',
             layers = ['ch.swisstopo.pixelkarte-farbe'],
             crs = ccrs.Orthographic,
             **kwargs):

    if self is not obspy.core.event.catalog.Catalog:
        self = fdsnClient(fdsnws_uri).get_events(**kwargs)

    longitude=[]
    latitude=[]
    for e in self:
        longitude+=[o.longitude for o in e.origins]
        latitude+=[o.latitude for o in e.origins]

    longitude+=[min(longitude)-std(longitude),
                   max(longitude)+std(longitude)]
    latitude+=[min(latitude)-std(latitude),
                   max(latitude)+std(latitude)]

    kmlo,az,baz=obspy.geodetics.base.gps2dist_azimuth(mean(latitude),mean(longitude),
                                                    mean(latitude),mean(longitude)+1)
    kmla,az,baz=obspy.geodetics.base.gps2dist_azimuth(mean(latitude),mean(longitude),
                                                    mean(latitude)+1,mean(longitude))
    y = latitude.copy()
    x = longitude.copy()
    if max(longitude)-min(longitude) > kmla/kmlo*golden*(max(latitude)-min(latitude)):
        # Too large
        m = mean(y)
        d = max(x)-min(x)
        latitude.append(m + d/(2*golden))
        latitude.append(m - d/(2*golden))
    else:
        # Too high
        m = mean(x)
        d = max(y)-min(y)
        longitude.append(m + kmla/kmlo*d*golden/2)
        longitude.append(m - kmla/kmlo*d*golden/2)

    # Create a Cartopy crs for plain and rotated lat-lon projections.
    projection = crs(central_longitude=mean(longitude),
                     central_latitude=mean(latitude))

    # Plot WMTS data in a specific region, over a plain lat-lon map.
    fig = plt.figure(figsize=(12*golden,12))
    ax = plt.axes([0, 0, 1, 1], projection=projection)
    ax.set_extent([min(longitude),
                   max(longitude),
                   min(latitude),
                   max(latitude)],
                  ccrs.PlateCarree())

    #ax.coastlines(resolution='50m', color='yellow')
    #ax.gridlines(color='lightgrey', linestyle='-')

    # Add WMS imaging.
    ax.add_wms(wms=wms,
               layers=layers,
               #wms_kwargs={'width':2160*2}
               )

    # Add earthquakes
    opts={'transform':ccrs.PlateCarree(),
          'solid_capstyle':'round',
          'markersize':16}
    # Breaks projection: cat.plot(fig=ax,method='cartopy',**opts)
    for e in self:
        m=e.preferred_magnitude()
        plot_eq(ax,m,'o',**opts)
        if len(self)==1:
            for m in e.magnitudes:
                if m is e.preferred_magnitude():
                    continue
                if m.magnitude_type != e.preferred_magnitude().magnitude_type :
                    continue
                plot_eq(ax,m,'P',**opts)

    if len(self)==1:
        ax.legend()

    fig.savefig('plot/map.png')
    plt.show()

## obspy integration should be:
#class Origin(...):
#
#    def delay(self, ...):
#        return utils._delay(self, ...)
## But the quick and dirty is:
obspy.core.event.catalog.Catalog.plot_wms = plot_wms
## Any instance of Catalog has the method plot_wms

if __name__ == '__main__':

    if '-h' in argv:
        print(' Try:\n%s "eventid=smi:ch.ethz.sed/sc20a/Event/2022rrcgvq" "includeallmagnitudes=1" "includeallorigins=1"'%argv[0])
    else:
        args={ arg.split('=')[0]:arg.split('=')[1] for arg in argv if "=" in arg}
        print('Arguments provided:')
        print(args)

        plot_wms(None,**args)


from __future__ import annotations
from typing import Dict, List, Any, Tuple, TYPE_CHECKING, Callable

from src.fleetctrl.pooling.immediate.insertion import simple_insert
from src.fleetctrl.planning.VehiclePlan import VehiclePlan, BoardingPlanStop, PlanStop
import src.fleetctrl.pooling.batch.AlonsoMora.AlonsoMoraAssignment as AlonsoMoraAssignment

if TYPE_CHECKING:
    from src.fleetctrl.pooling.batch.BatchAssignmentAlgorithmBase import SimulationVehicleStruct
    from src.routing.NetworkBase import NetworkBase
    from src.fleetctrl.planning.PlanRequest import PlanRequest
    from src.simulation.Legs import VehicleRouteLeg

import logging
LOG = logging.getLogger(__name__)

def remove_non_routing_planstops_and_copy(veh_plan : VehiclePlan, veh_obj : SimulationVehicleStruct,
                                          routing_engine : NetworkBase, sim_time : int) -> VehiclePlan:
    """this funtion removes all planstops that are empty (i.e. not locked, not end locked and not boarding/charging processes)"""
    return veh_plan.copy_and_remove_empty_planstops(veh_obj, sim_time, routing_engine)

class V2RB():
    """ this class is a collection of feasible vehicle plan for a specific vehicle serving the same requests"""
    def __init__(self, routing_engine : NetworkBase, rq_dict : Dict[Any, PlanRequest], sim_time : int, rtv_key : tuple,
                 veh_obj : SimulationVehicleStruct, std_bt : int, add_bt : int, obj_function : Callable,
                 orig_veh_plans : List[VehiclePlan] = None, new_prq_obj : PlanRequest = None):
        """ this method initializes a v2rb. depending on the input parameters different initialization are possible
        a) new_prq_obj is given, but no orig_veh_plans: -> the most basic v2rb with only one request is created
        b) new_prq_obj and orig_veh_plans is given: -> the new request will be inserted in the given vehicle plans
        c) new_prq_obj is not given, but orig_veh_plans is given: -> a v2rb based on thes plans is created, but it will be forced to be feasible (no deletion of infeasile plans)
        :param routing_engine: routing_engine ref
        :param rq_dict: dict rid -> prq of at least all requests part of the v2rb
        :param sim_time: simulation time
        :param rtv_key: key of the v2rb (tuple; see key creation function)
        :param veh_obj: corresponding simulationvehiclestruct ref
        :param std_bt: const boarding time
        :param add_bt: additional boarding time
        :param obj_function: objective funtion to rate vehicle plans
        :param orig_veh_plans: optional; list of vehicle plans as input
        :param new_prq_obj: optional; new plan request obj"""
        self.veh_plans : List[VehiclePlan] = []
        self.cost_function_value = None
        self.rtv_key = rtv_key
        self.veh = veh_obj
        if new_prq_obj is not None and orig_veh_plans is None:  # init v2rb with one request
            if veh_obj.has_locked_vehplan():
                # init = [ps.copy() for ps in veh_obj.locked_planstops]
                # empty_plan = VehiclePlan(veh_obj, sim_time, routing_engine, init)
                empty_plan = veh_obj.locked_vehplan.copy()
            else:
                empty_plan = VehiclePlan(veh_obj, sim_time, routing_engine, [])
            self.veh_plans = [new_plan for new_plan in simple_insert(routing_engine, sim_time, veh_obj, empty_plan, new_prq_obj, std_bt, add_bt)]
        elif new_prq_obj is not None and orig_veh_plans is not None: # insert into lower plans with new requests
            for veh_plan in orig_veh_plans:
                copy_plan = remove_non_routing_planstops_and_copy(veh_plan, veh_obj, routing_engine, sim_time)# veh_plan.copy()
                self.veh_plans += [new_plan for new_plan in simple_insert(routing_engine, sim_time, veh_obj, copy_plan, new_prq_obj, std_bt, add_bt)]
        if self.isFeasible(): # check feasibility
            self.computeCostFunctionValue(sim_time, obj_function, veh_obj, routing_engine, rq_dict)
        elif orig_veh_plans is not None and new_prq_obj is None: # force v2rb to exist even no longer feasible
            self.veh_plans = [remove_non_routing_planstops_and_copy(o_plan, veh_obj, routing_engine, sim_time) for o_plan in orig_veh_plans]# [o_plan.copy() for o_plan in orig_veh_plans]
            self.computeCostFunctionValue(sim_time, obj_function, veh_obj, routing_engine, rq_dict)
        # else:
        #     LOG.debug(f"V2RB infeasible: {self.rtv_key}")
        # LOG.debug(f"new V2RB {self.rtv_key}")
        # LOG.debug("\n".join([str(x) for x in self.veh_plans]))

    def __str__(self):
        l = ["V2RB {} wit cfv {}".format(self.rtv_key, self.cost_function_value)]
        for vp in self.veh_plans:
            l.append(str(vp))
        return "\n".join(l)

    def isFeasible(self) -> bool:
        """ checks feasibility of v2rb
        :return: bool"""
        if len(self.veh_plans) > 0:
            return True
        else:
            return False

    def addRequestAndCheckFeasibility(self, new_prq_obj : PlanRequest, new_rtv_key : tuple, routing_engine : NetworkBase,
                                      obj_function : Callable, rq_dict : Dict[Any, PlanRequest], sim_time : int, veh_obj : SimulationVehicleStruct,
                                      std_bt : int, add_bt : int) -> V2RB:
        """ insert a new request into the v2rb and create to next one"""
        newV2RB = V2RB(routing_engine, rq_dict, sim_time, new_rtv_key, veh_obj, std_bt, add_bt, obj_function, orig_veh_plans=self.veh_plans, new_prq_obj=new_prq_obj)
        if newV2RB.isFeasible():
            return newV2RB
        else:
            return None

    def updateAndCheckFeasibility(self, routing_engine : NetworkBase, obj_function : Callable, veh_obj : SimulationVehicleStruct,
                                  rq_dict : Dict[Any, PlanRequest], sim_time : int, list_passed_VRLs : List[VehicleRouteLeg]=None,
                                  is_assigned : bool=False):
        """ checks the feasibility of the v2rb after vehicle state updates from last simulation time step"""
        if list_passed_VRLs is None:
            list_passed_VRLs = []
        new_veh_plans = []
        self.veh = veh_obj
        if not is_assigned:
            for i, veh_plan in enumerate(self.veh_plans):
                veh_plan.update_plan(veh_obj, sim_time, routing_engine, list_passed_VRLs=list_passed_VRLs,
                                     keep_time_infeasible=False)
                if veh_plan.is_feasible():
                    new_veh_plans.append(veh_plan)
        else:
            struct_feasible_veh_plans = []
            for i, veh_plan in enumerate(self.veh_plans):
                if is_assigned and i == 0:
                    veh_plan.update_plan(veh_obj, sim_time, routing_engine, list_passed_VRLs=list_passed_VRLs,
                                         keep_time_infeasible=True)
                    if veh_plan.is_feasible():
                        new_veh_plans.append(veh_plan)
                    elif veh_plan.is_structural_feasible():
                        struct_feasible_veh_plans.append(veh_plan)
                    else:
                        LOG.warning("(assigned) vehicle plan became structural infeasible! {}".format(veh_plan))
                else:
                    veh_plan.update_plan(veh_obj, sim_time, routing_engine, list_passed_VRLs=list_passed_VRLs,
                                         keep_time_infeasible=False)
                    if veh_plan.is_feasible():
                        new_veh_plans.append(veh_plan)
            if len(new_veh_plans) == 0:
                new_veh_plans = struct_feasible_veh_plans
        self.veh_plans = new_veh_plans
        self.computeCostFunctionValue(sim_time, obj_function, veh_obj, routing_engine, rq_dict)

    def computeCostFunctionValue(self, sim_time : int, obj_function : Callable, veh_obj : SimulationVehicleStruct,
                                 routing_engine : NetworkBase, rq_dict : Dict[Any, PlanRequest]):
        """ computes the costfunction values of all plans and sorts the list self.veh_plans accordingly"""
        #simulation_time, veh_obj, veh_plan, rq_dict, routing_engine
        if len(self.veh_plans) > 0:
            #LOG.debug("compute CFV {}".format(self.rtv_key))
            for veh_plan in self.veh_plans:
                #LOG.debug(f"utility input : {veh_obj} | {veh_plan} | {[(rid, rq) for rid, rq in rq_dict.items()]}")
                veh_plan.set_utility(obj_function(sim_time, veh_obj, veh_plan, rq_dict, routing_engine))
                #LOG.debug(f" -> utility {veh_plan.utility}")
            self.veh_plans = sorted(self.veh_plans, key = lambda x:x.utility)
            self.cost_function_value = self.veh_plans[0].utility

    def getBestPlan(self) -> VehiclePlan:
        """ returns the best vehicleplan of the v2rb"""
        return self.veh_plans[0]

    def createLowerV2RB(self, lower_key : tuple, sim_time : int, routing_engine : NetworkBase, obj_function : Callable,
                        rq_dict : Dict[Any, PlanRequest], std_bt : int, add_bt : int) -> V2RB:
        keep_rids = AlonsoMoraAssignment.getRidsFromRTVKey(lower_key)
        #only keep best route
        base_plan = self.veh_plans[0]
        new_plan_list = []
        for ps in base_plan.list_plan_stops:
            if ps.is_locked_end():
                new_plan_list.append(ps.copy())
                continue
            new_boarding_dict = {}
            new_max_trip_time_dict = {}
            new_earliest_pickup_time_dict = {}
            new_latest_pickup_time_dict = {}
            change_nr_pax = 0
            ept, lpt, mtt, lat = ps.get_boarding_time_constraint_dicts()
            for rid in ps.get_list_boarding_rids():
                if rid in keep_rids:
                    try:
                        new_boarding_dict[1].append(rid)
                    except:
                        new_boarding_dict[1] = [rid]
                    new_earliest_pickup_time_dict[rid] = ept[rid]
                    new_latest_pickup_time_dict[rid] = lpt[rid]
            change_nr_pax += sum([rq_dict[rid].nr_pax for rid in new_boarding_dict.get(1, [])])
            for rid in ps.get_list_alighting_rids():
                if rid in keep_rids:
                    try:
                        new_boarding_dict[-1].append(rid)
                    except:
                        new_boarding_dict[-1] = [rid]
                    new_max_trip_time_dict[rid] = mtt[rid]
            change_nr_pax -= sum([rq_dict[rid].nr_pax for rid in new_boarding_dict.get(-1, [])])
            if len(new_boarding_dict.keys()) > 0 or ps.is_locked():
                #LOG.warning("not considering new time constraints!!!!") # TODO #
                # new_ps = BoardingPlanStop(ps.get_pos(), boarding_dict=new_boarding_dict, max_trip_time_dict=new_max_trip_time_dict,
                #                           earliest_pickup_time_dict=new_earliest_pickup_time_dict, latest_pickup_time_dict=new_latest_pickup_time_dict,
                #                           change_nr_pax=change_nr_pax, duration=ps.get_duration_and_earliest_departure()[0], locked=ps.is_locked())
                new_ps = PlanStop(ps.get_pos(), boarding_dict=new_boarding_dict, max_trip_time_dict=new_max_trip_time_dict,
                                          earliest_pickup_time_dict=new_earliest_pickup_time_dict, latest_pickup_time_dict=new_latest_pickup_time_dict,
                                          change_nr_pax=change_nr_pax, duration=ps.get_duration_and_earliest_departure()[0], locked=ps.is_locked(),
                                          charging_power=ps.get_charging_power(), planstop_state=ps.get_state(), charging_task_id=ps.get_charging_task_id(),
                                          change_nr_parcels=ps.get_change_nr_parcels())
                # new_ps = ps.copy()
                # new_ps.boarding_dict = new_boarding_dict
                new_plan_list.append(new_ps)
        new_veh_plan = VehiclePlan(self.veh, sim_time, routing_engine, new_plan_list, external_pax_info=base_plan.pax_info.copy())
        return V2RB(routing_engine, rq_dict, sim_time, lower_key, self.veh, std_bt, add_bt, obj_function, orig_veh_plans=[new_veh_plan])


# -*- coding: utf-8 -*-
import re
import numpy as np
#import gdal
from os.path import join,relpath
from glob import glob
import matplotlib.pyplot as plt
import seaborn as sns
import math
import networkx as nx
import csv
from PIL import Image
import shelve

#x, yの並び順はすべて(x, y)

def main():
    dem_shelve = 'dem_s_rough'
    with shelve.open(dem_shelve) as db:
        dem_rough_sl = db['dem']

    shelve_x_start = 2750
    shelve_y_start = 6000
    shelve_x_end = 3750
    shelve_y_end = 7000

    path_edge_shelve = 'path_edge'
    with shelve.open(path_edge_shelve) as db:
        path_edges = db['edge']
    len_edges = len(path_edges)
    path_nodes = np.empty((len_edges + 1, 2))
    i = 0
    for ed in path_edges:
        path_nodes[i] = np.array(ed[0])
        i += 1
    path_nodes[i] = np.array(path_edges[i - 1][1])
    #np.arrayの[[x0, y0], [x1, y1], .....]という形を想定

    seg_num = 10

    seg_path = split_path(path_nodes, seg_num)

    seg_fin_nodes = find_fin_node(seg_path)

    next_initial_pos = np.array(path_nodes[0][0])
    initial_pos = np.empty(seg_num, 2)
    target_pos = np.empty(seg_num, 2)
    final_pos = np.empty(seg_num, 2)
    estimate_pos = np.empty(seg_num, 2)
    next_initial_pos = np.empty(seg_num, 2)

    for i in range(seg_num):
        initial_pos[i] = next_initial_pos
        #実際の初期位置
        target_pos[i]= seg_fin_nodes[i]
        #実際の目標位置
        final_pos[i] = rover_run(initial_pos, seg_path[i], i)
        #実際に到着した位置
        final_node_in_dem_all = find_closest_node_in_dem_all(final_pos[i], shelve_x_start, shelve_y_start)
        #実際に到着した位置に最も近いノード
        real_skyline = make_real_skyline(final_node_in_dem_all)
        #実際に到着した位置に最も近いノードから見える実際のスカイライン
        estimate_pos[i] = position_estimate(target_pos, real_skyline, dem_rough_sl)
        #スカイラインから推定される位置
        next_initial_pos[i] = modify_error(estimate_pos, target_pos, final_pos, i)
        #位置推定をもとに修正後の実際の位置

    global grid_size
    grid_size = 5.05
    global max_len
    max_len = math.sqrt(2) * grid_size
    global max_ang
    max_ang = 15

def split_path(path_nodes, seg_num):
    num_edge = len(path_nodes)
    seg_len = num_edge // seg_num

    seg_path = np.empty(seg_num)

    for i in range(seg_num):
        if i != seg_num - 1:
            seg_path[i] = path_nodes[seg_len * i : seg_len * (i + 1)]
        else:
            seg_path[i] = path_nodes[seg_len * i:]

    return seg_path

def find_fin_node(seg_path):
    seg_num = len(seg_path)
    fin_nodes = np.empty((seg_num, 2))
    for i in range(seg_num):
        fin_nodes[i] = seg_path[i][len(seg_path[i])]

    return fin_nodes

def rover_run(initial_pos, nodes, seg_i):
    len_nodes = len(nodes)
    current_pos = initial_pos
    rover_trajectory = np.empty((len_nodes, 2))
    rover_trajectory[0] = current_pos

    sigma_len = 0.1
    sigma_ang = 1

    for i in range(len_nodes - 1):
        vector_move = nodes[i + 1] - nodes[i]
        len_error = 1 + np.random.normal(0, sigma_len)
        ang_error = math.radians(np.random.normal(0, sigma_ang))
        x_move = math.sqrt(len_error) * (vector_move[0] * math.cos(ang_error) - vector_move * math.sin(ang_error))
        y_move = math.sqrt(len_error) * (vector_move[1] * math.sin(ang_error) + vector_move * math.cos(ang_error))
        current_pos += np.array([x_move, y_move])
        rover_trajectory[i + 1] = current_pos

    shelvename = 'trajectory_' + str(seg_i)
    with shelve.open(shelvename) as db:
        db['trajectroy'] = rover_trajectory

    return current_pos

def find_closest_node_in_dem_all(pos, shelve_x_start, shelve_y_start):
    x = 0
    while x < pos[0]:
        x += 1
    if x - pos[0] > 1 / 2:
        x -= 1
    y = 0
    while y < pos[1]:
        y += 1
    if y - pos[1] > 1 / 2:
        y -= 1

    x += shelve_x_start
    y += shelve_y_start

    return np.array([x, y])

def make_real_skyline(node):
    sigma_azimuth = 1   #方位角の推定誤差
    sigma_photo = 0.001     #撮影時に生じるノイズ
    sigma_pixel = 0.001     #解像度による誤差

    x_center = node[0]
    y_center = node[1]

    real_skyline = skyline_with_error_azi(sigma_azimuth, x_center, y_center)
    real_skyline = add_noise(real_skyline, sigma_photo)
    real_skyline = add_noise(real_skyline, sigma_pixel)

    return real_skyline

def skyline_with_error_azi(sigma, x_center, y_center):
    dem = np.array(Image.open('\\Users\\Maenaka\\python\\20190204\\mars_spirit_landing_site\\dem.tif'))
    #dem = np.array(Image.open('/home/shuto/python/20190131/mars_spirit_landing_site/dem.tif'))

    delta_p = 1     #各方位角方向のインクリメント[m]
    max_k = 2000      #インクリメント回数
    radius_star = 3397200     #星の半径（ここでは火星）
    height_cam = 0.7    #カメラの高さ
    grid_size = 1.01
    k = 1
    azi = 0
    elevation_max = 0
    skyline = np.zeros(360)

    error = np.random.normal(0, sigma)

    while azi < 360:
        while k <= max_k:
            x_on_azi_line =  round(x_center + k * delta_p * math.cos((azi + error) / 360 * 2 * math.pi) / grid_size)
            y_on_azi_line =  round(y_center + k * delta_p * math.sin((azi + error) / 360 * 2 * math.pi) / grid_size)
            curv = (radius_star - math.sqrt(radius_star ** 2 - (k * delta_p) ** 2) ) / grid_size
            height_interest = (dem[y_on_azi_line][x_on_azi_line] - curv) / grid_size
            height_center = (dem[y_center][x_center] + height_cam) / grid_size
            elevation_interest = math.atan((height_interest - height_center) / (k * delta_p / grid_size))
            if elevation_max < elevation_interest:
                elevation_max = elevation_interest
            k += 1
        skyline[azi] = elevation_max
        elevation_max = 0
        azi += 1
        k = 0

    return skyline

def add_noise(skyline, sigma):
    real_skyline = np.zeros(360)
    azi = 0
    while azi < 360:
        noise = np.random.normal(0, sigma)
        real_skyline[azi] = skyline[azi] + noise
        azi += 1

    return real_skyline

def position_estimate(target_pos, real_skyline, dem):
    search_range = 10
    #探索する正方形領域の一辺の長さ（エッジの数）
    min_x = target_pos[0] - search_range // 2
    min_y = target_pos[1] - search_range // 2
    max_x = target_pos[0] + search_range // 2
    max_y = target_pos[1] + search_range // 2

    min_diff_skyline = 99999999

    for y in range(min_y, max_y):
        for x in range(min_x, max_x):
            rendered_skyline = dem[y][x][1:]
            diff_skyline = 0
            for azi in range(360):
                diff_skyline += (rendered_skyline[azi] - real_skyline[azi]) ** 2
            if min_diff_skyline > diff_skyline:
                min_diff_skyline = diff_skyline
                esitimate_pos = np.array([x, y])

    return esitimate_pos

def modify_error(estimate_pos, target_pos, final_pos, seg_i):
    sigma_len = 0.1
    sigma_ang = 1

    vector_move = target_pos - estimate_pos
    len_error = 1 + np.random.normal(0, sigma_len)
    ang_error = math.radians(np.random.normal(0, sigma_ang))
    x_move = math.sqrt(len_error) * (vector_move[0] * math.cos(ang_error) - vector_move * math.sin(ang_error))
    y_move = math.sqrt(len_error) * (vector_move[1] * math.sin(ang_error) + vector_move * math.cos(ang_error))

    vector_move += np.array([x_move, y_move])

    next_initial_pos = final_pos + vector_move

    return next_initial_pos

if __name__ == "__main__":
    main()