import sys
from multiprocessing import Process
from multiprocessing.managers import SyncManager
from typing import Any, Callable, List, Optional, Tuple

import boto3
import requests
from flask import Flask, render_template

from rgbserver.config import Config
from rgbserver.control import RGBController

class Webserver(Flask):
    def __init__(self, location: str) -> None:
        super().__init__(__name__)
        self.rgb_config = Config(location)
        self.rgb = RGBController(self.rgb_config)
        self.proc = Process()
        self.manager = SyncManager()
        self.manager.start()
        self.state: List[Tuple[int, int, int]] = self.manager.list()

        self.before_request(self.stop_process)
        self.add_url_rule('/', view_func=self.index)
        self.add_url_rule('/clear', view_func=self.clear)
        self.add_url_rule('/fire', view_func=self.fire)
        self.add_url_rule('/rainbow', view_func=self.rainbow)
        self.add_url_rule('/rainbow_color_wipe', view_func=self.rainbow_color_wipe)
        self.add_url_rule('/rainbow_fade', view_func=self.rainbow_fade)
        self.add_url_rule('/random_fade', view_func=self.random_fade)
        self.add_url_rule('/snake_color', view_func=self.snake_color)
        self.add_url_rule('/snake_fade', view_func=self.snake_fade)
        self.add_url_rule('/snake_rainbow', view_func=self.snake_rainbow)
        self.add_url_rule('/static_color/<int:red>/<int:green>/<int:blue>', view_func=self.static_color)
        self.add_url_rule('/static_color_name/<name>', view_func=self.static_color_name)
        self.add_url_rule('/static_gradient/<int:r1>/<int:g1>/<int:b1>/<int:r2>/<int:g2>/<int:b2>',
                          view_func=self.static_gradient)
        self.add_url_rule('/strobe', view_func=self.strobe)

    def run(self, host: str = None, port: int = None, debug: bool = None, load_dotenv: bool = True,
            **options: Optional[Any]) -> None:
        if self.rgb_config.sqs_url:
            reader = Process(target=self.sqs_reader, args=())
            reader.start()

        super().run('0.0.0.0', self.rgb_config.port, debug, load_dotenv, **options)

    @staticmethod
    def index() -> str:
        return render_template('index.html')

    def clear(self) -> str:
        self.start_process(self.rgb.clear)
        return 'clear'

    def fire(self) -> str:
        self.start_process(self.rgb.fire)
        return 'fire'

    def rainbow(self) -> str:
        self.start_process(self.rgb.rainbow)
        return 'rainbow'

    def rainbow_color_wipe(self) -> str:
        self.start_process(self.rgb.rainbow_color_wipe)
        return 'rainbow_color_wipe'

    def rainbow_fade(self) -> str:
        self.start_process(self.rgb.rainbow_fade)
        return 'rainbow_fade'

    def random_fade(self) -> str:
        self.start_process(self.rgb.random_fade)
        return 'random_fade'

    def snake_color(self) -> str:
        self.start_process(self.rgb.snake, ("color",))
        return 'snake_color'

    def snake_fade(self) -> str:
        self.start_process(self.rgb.snake, ("fade",))
        return 'snake_fade'

    def snake_rainbow(self) -> str:
        self.start_process(self.rgb.snake, ("rainbow",))
        return 'snake_rainbow'

    def static_color(self, red: int, green: int, blue: int) -> str:
        self.start_process(self.rgb.static_color, (red, green, blue))
        return 'static_color'

    def static_color_name(self, name: str) -> str:
        self.start_process(self.rgb.static_color_name, (name,))
        return 'static_color_name'

    def static_gradient(self, r1: int, g1: int, b1: int, r2: int, g2: int, b2: int) -> str:
        self.start_process(self.rgb.static_gradient, ((r1, g1, b1), (r2, g2, b2)))
        return 'static_gradient'

    def strobe(self) -> str:
        self.start_process(self.rgb.strobe)
        return 'strobe'

    def start_process(self, func: Callable, args: Tuple = ()) -> None:
        self.proc = Process(target=func, args=(self.state,) + args)
        self.proc.start()

    def stop_process(self) -> None:
        if self.proc.pid is not None:
            self.proc.terminate()
            self.proc.join()

    def sqs_reader(self) -> None:
        client = boto3.client('sqs', region_name=self.rgb_config.aws_region,
                              aws_access_key_id=self.rgb_config.aws_key,
                              aws_secret_access_key=self.rgb_config.aws_secret)
        while True:
            response = client.receive_message(QueueUrl=self.rgb_config.sqs_url, AttributeNames=[],
                                              MessageAttributeNames=[],
                                              MaxNumberOfMessages=1, VisibilityTimeout=30, WaitTimeSeconds=20)
            if 'Messages' in response:
                message = response['Messages'][0]
                requests.get("http://localhost:" + str(self.rgb_config.port) + "/" + message['Body'])
                client.delete_message(QueueUrl=self.rgb_config.sqs_url, ReceiptHandle=message['ReceiptHandle'])

def main() -> None:
    if len(sys.argv) != 2:
        exit("The only parameter needed is the json config file's absolute path!")
    Webserver(sys.argv[1]).run()

if __name__ == "__main__":
    main()


#!/usr/bin/env python3
# Auther: sunjb
import  sys,random,copy

#归并排序
# 将列表分成两边，两个都是有序的集合，然后把这两边归并在一起。
def merge(li,low,mid,heigh):
    '''
     data=[1,4,5,6,2,3,7,8,9]
     merge(data,0,3,8)
     '''
    i=low
    j=mid+1
    ltmp=[]
    while i<=mid and j<=heigh:
        if li[i] < li[j]:
            ltmp.append(li[i])
            i += 1
        else:
            ltmp.append(li[j])
            j += 1
    while i<=mid:
        ltmp.append(li[i])
        i += 1
    while j<=heigh:
        ltmp.append(li[j])
        j += 1
    li[low:heigh+1]=ltmp
    # print(li)

def mergsort(li,low,high):
    '''
    先分解再合并
    :param li:
    :param low:
    :param high:
    :return:
    '''
    if low<high:
        mid=(low+high)//2
        mergsort(li,low,mid)    #分解左边的
        mergsort(li,mid+1,high) #分解右边的
        merge(li,low,mid,high)  #合并分解的
    return li
data=list(range(5000))
random.shuffle(data)
data1=copy.deepcopy(data)
# data=[5,9,3,1,4,8,6,7,2]
# data=[1,4,5,6,2,3,7,8,9]
# merge(data,0,3,8)
print(mergsort(data,0,len(data)-1))

#运行速度： 快排>归并>堆排

# python自带了堆排序的函数heapq，利用这个函数就可以直接进行堆排序
import heapq

heap=[]
for num in data1:
    heapq.heappush(heap,num)        #将数组变成一个堆，得到的数组将是一个小根堆（顶层是0）
print(heap)
heap_sort=[]
for i in range(len(heap)):
    num=heapq.heappop(heap)         #对堆进行排序，会按照序列从小到大依次输出
    heap_sort.append(num)
print(heap_sort)                    #得到一个排列好的有序数组

print(data1)
print(heapq.nsmallest(10,data1))    #得到无序数组里面前十个最小的元素
print(heapq.nlargest(10,data1))     #得到最大的十个元素

#找出列表里面相同连续元素的下标
#二分查找法
def bin_search(data_set,val):
    low=0
    high=len(data_set)-1
    while low<=high:
        mid=(low+high)//2
        if data_set[mid]==val:
            left=mid
            right=mid
            while left>=0 and data_set[left]==val:
                left -=1
            while right<len(data_set) and data_set[right] == val:
                right +=1
            return (left+1,right-1)
        elif data_set[mid]<val:
            low = mid+1
        else:
            high=mid-1
li=[1,2,2,3,3,3,4,4,5]
print(bin_search(li,3))


from deidentify.base import Annotation
from deidentify.methods.deduce.deduce_labeler import DeduceAnnotator

TEST_TEXT = u"Dit is stukje tekst met daarin de naam Jan Jansen. De patient J. Jansen (e: j.jnsen@email.com, t: 06-12345678) is 64 jaar oud en woonachtig in Utrecht. Hij werd op 10 oktober door arts Peter de Visser ontslagen van de kliniek van het UMCU."

ANNOTATOR = DeduceAnnotator(text=TEST_TEXT)

def test_annotation_content():
    assert ANNOTATOR.annotation_content('<LOCATIE Laverhof>') == 'Laverhof'

def test_annotation_tag():
    assert ANNOTATOR.annotation_tag('<LOCATIE Laverhof>') == 'LOCATIE'

def test_is_annotation():
    assert ANNOTATOR.is_annotation('<LOCATIE Laverhof>')
    assert not ANNOTATOR.is_annotation('This is not an annotation')
    assert not ANNOTATOR.is_annotation('This is also not an annotation <LOCATIE Laverhof>')

def test_flatten_tag_content():
    fac = ANNOTATOR.flatten_annotation_content
    assert fac('<PERSOON <LOCATIE Laverhof >Ondersteuning Thuis>') == 'Laverhof Ondersteuning Thuis'
    assert fac('Ondersteuning Thuis') == 'Ondersteuning Thuis'
    assert fac('<LOCATIE Laverhof> Ondersteuning <LOCATIE Thuis>') == 'Laverhof Ondersteuning Thuis'
    assert fac('<LOCATIE Laverhof>') == 'Laverhof'

def test_annotate_text():
    assert ANNOTATOR.annotated_text == "Dit is stukje tekst met daarin de naam <PERSOON Jan Jansen>. De <PERSOON patient J. Jansen> (e: <URL j.jnsen@email.com>, t: <TELEFOONNUMMER 06-12345678>) is <LEEFTIJD 64> jaar oud en woonachtig in <LOCATIE Utrecht>. Hij werd op <DATUM 10 oktober> door arts <PERSOON Peter de Visser> ontslagen van de kliniek van het <INSTELLING umcu>."

def test_annotations():
    actual = ANNOTATOR.annotations()

    assert actual == [
        Annotation('Jan Jansen', 39, 49, 'PERSOON'),
        Annotation('patient J. Jansen', 54, 71, 'PERSOON'),
        Annotation('j.jnsen@email.com', 76, 93, 'URL'),
        Annotation('06-12345678', 98, 109, 'TELEFOONNUMMER'),
        Annotation('64', 114, 116, 'LEEFTIJD'),
        Annotation('Utrecht', 143, 150, 'LOCATIE'),
        Annotation('10 oktober', 164, 174, 'DATUM'),
        Annotation('Peter de Visser', 185, 200, 'PERSOON'),
        # We explicitly check that the following annotation is included in it's correct form.
        # Deduce annotates UMCU as umcu. During annotation, we attempt to recover the original text.
        Annotation('UMCU', 234, 238, 'INSTELLING')
    ]


import inspect
from dataclasses import dataclass

class MagicList(list):
    def __init__(self, cls_type):
        if not inspect.isclass(cls_type):
            raise NotImplementedError('Need to provide type')
        super().__init__()
        self._cls_type = cls_type
        #self._list = list()

    def __getitem__(self, ii):
        if ii < super().__len__():
            return super().__getitem__(ii)
        elif ii == super().__len__():
            new_el = self._cls_type()
            super().append(new_el)
            return super().__getitem__(ii)
        else:
            raise IndexError('List index out of range')

    def __setitem__(self, ii, val):
        if ii < super().__len__():
            super().__setitem__(ii, val)
        elif ii == super().__len__():
            new_el = self._cls_type()
            super().append(new_el)
        else:
            raise IndexError('List index out of range')

    # def __len__(self):
    #     """List length"""
    #     return len(self._list)

    # def __iter__(self):
    #     for elem in self._list:
    #         yield elem

    # def __repr__(self):
    #     return f"{type(self).__name__}({super().__repr__()})"

@dataclass
class Person:
    age: int = 1

# new_element_class = globals()[self._cls_type]
#             new_el = new_element_class()
#             self._list.append(new_el)
#             return new_el


def print2(str1):
    print("This is " + str1)

print2("Sourav") # output This is Sourav

#########################################################
# if we do like this we will get an error ---> RecursionError: maximum recursion depth exceeded
# we got this error because we use here function inside function & dont stop it
"""
def print2(str1):
    print2(str1)
    print("This is " + str1)

print2("Sourav")
"""

#######################################################
# 5! = 5*4*3*2*1
# how to calculate factorial using Recursions
# n! = n*n-1 * n-2 * n-3................1
# n! = n * (n-1)!

def factorial_iterative(n):
    """

        :param n: Integer
        :return: n*n-1 * n-2 * n-3................1
        """
    fac = 1
    for i in range(n):
        fac = fac * (i + 1)
    return fac

number = int(input("Enter the  number "))

print("Factorial using Iterative Methode",factorial_iterative(number))

########################################################################
def factorial_recursive(n):
    """

        :param n: Integer
        :return: n*n-1 * n-2 * n-3................1
        """
    if n == 1 or n == 0:
        return 1
    else:
        return n * factorial_recursive(n-1)

    # how it works
    # for example user give ab input 5

    # 5 * factorial_recursive(4)
    # 5 * 4 * factorial_recursive(3)
    # 5 * 4 * 3 * factorial_recursive(2)
    # 5 * 4 * 3 * 2 * factorial_recursive(1)    # in this condiction --> factorial_recursive(1)  it will be run the if statement
    # 5 * 4 * 3 * 2 * 1 = 120

number = int(input("Enter the  number "))

print("Factorial using recursive Methode",factorial_recursive(number))

# quiz - fibonacci sequence calculate function
# example of fibonacci sequence --> 0 1 1 2 3 5 8 13
def fibonacci(n):
    if n == 1:
        return 0
    elif n == 2:
        return 1
    else:
        return fibonacci(n-1) + fibonacci(n-2)

number = int(input("Enter the  number "))

print(fibonacci(number))

31 (Recursions Recursive Vs Iterative Approch - Python Tutorials For absolute Beginners # 34).py


n = int(input())
s = input()

down = 0
up = 0
valleys = 0
landscape = ''
for i in range(n):
    if s[i] == 'U':
        up += 1
    else:
        down += 1
    landscape += s[i]
    if up == down:
        if landscape.startswith('D'):
            valleys += 1
        up = 0
        down = 0
        landscape = ''
print(valleys)


n = int(input())
array = list(map(int, input().split()))

index = {}
for i, num in enumerate(array, start=1):
    index[num] = i

m = int(input())
queries = list(map(int, input().split()))

Vasya = 0
Petya = 0
for query in queries:
    Vasya += index[query]
    Petya += (n + 1 - index[query])

print(Vasya, Petya)


import pygame as pg
from abc import ABC, abstractmethod

class Drawable(pg.sprite.Sprite, ABC):
    """ The abstract class Drawable represents every object which can be scaled
    and drawn on the map on a specific position. """

    def __init__(self):
        pg.sprite.Sprite.__init__(self)

    @abstractmethod
    def draw(self, surface, scale, pos_offset):
        """ Draws the object on the surface. The object is scaled
        and translated according to the scale and pos_offset parameters. """
        pass

    def _draw_filled_aacircle(self, surface, center, radius, color):
        """ Draws a filled anti-aliased circle. """

        # draw anti-aliasing circle
        pg.gfxdraw.aacircle(
            surface,
            int(center.x), int(center.y),
            radius, color
        )

        # draw filled circle
        pg.gfxdraw.filled_circle(
            surface,
            int(center.x), int(center.y),
            radius, color
        )

    def _draw_filled_aatriangle(self, surface, p1, p2, p3, color):
        """ Draws a filled anti-aliased triangle. """

        pg.gfxdraw.filled_trigon(
            surface,
            int(p1.x), int(p1.y),
            int(p2.x), int(p2.y),
            int(p3.x), int(p3.y),
            color,
        )

        pg.gfxdraw.aatrigon(
            surface,
            int(p1.x), int(p1.y),
            int(p2.x), int(p2.y),
            int(p3.x), int(p3.y),
            color,
        )


#!/usr/bin/env python
# encoding: utf-8
"""
@author: HuRuiFeng
@file: 013_event-push.py
@time: 2023/7/26 19:44
@project: huawei-od-python
@desc: 013 事件推送
"""

def solve_method(A, B, R):
    result = []
    index = 0
    for a in A:
        while index < len(B):
            if a <= B[index] and B[index] - a <= R:
                result.append([a, B[index]])
                break
            index += 1

    return result

if __name__ == '__main__':
    A = [1, 5, 5, 10]
    B = [1, 3, 8, 8, 20]
    assert solve_method(A, B, 5) == [[1, 1], [5, 8], [5, 8]]


import random, sys, time, math, pygame
from pygame.locals import *
import pytmx
from pytmx.util_pygame import load_pygame

GRASSCOLOR = (24, 255, 0)

def initMap():
    tiled_map = load_pygame('Map/maptn5.tmx', pixelalpha=True)
    tilewidth = tiled_map.tilewidth
    tileheight = tiled_map.tileheight

    return tiled_map,tilewidth,tileheight

def renderMap(tiled_map, tilewidth, tileheight, DISPLAYSURF, camerax, cameray):
    for layer in tiled_map.layers:
        if isinstance(layer, pytmx.TiledTileLayer):

            for x, y, tile in layer.tiles():
                if (tile):
                    DISPLAYSURF.blit(tile, [( x + camerax )*tilewidth,( y + cameray )*tileheight])

def drawRectTerrain(tilewidth, tileheight, WHITE, DISPLAYSURF, camerax, cameray, SET_ALPHA):

    tiledGrass1_size = (51*tilewidth,3*tileheight)
    tiledGrass1_rect =  pygame.Surface(tiledGrass1_size)
    tiledGrass1_rect.set_alpha(SET_ALPHA)
    tiledGrass1_rect.fill(WHITE)
    tiledGrass1 = DISPLAYSURF.blit(tiledGrass1_rect, (0*tilewidth + camerax*tilewidth,13*tileheight + cameray*tileheight))

    tiledStone1_size = (11*tilewidth,1*tileheight)
    tiledStone1_rect =  pygame.Surface(tiledStone1_size)
    tiledStone1_rect.set_alpha(SET_ALPHA)
    tiledStone1_rect.fill(WHITE)
    tiledStone1 = DISPLAYSURF.blit(tiledStone1_rect, (12*tilewidth + camerax*tilewidth,12*tileheight + cameray*tileheight))

    return tiledGrass1, tiledStone1

def drawRectTerrainList(tilewidth, tileheight, WHITE, DISPLAYSURF, camerax, cameray, SET_ALPHA):

    tiledColisions = []
    tiledColisions2 = []
    tiledColisions3 = []
    tiledColisions4 = []
    tiledColisions5 = []
    tiledColisions6 = []

    # Area 1

    tileStart1 = { 'area': 1, 'type': 'ground', 'X': 0,'Y': 0, 'sizeX': 1,'sizeY': 16 }
    tileStart1_size = (tileStart1['sizeX']*tilewidth,tileStart1['sizeY']*tileheight)
    tileStart1_rect =  pygame.Surface(tileStart1_size)
    tileStart1_rect.set_alpha(SET_ALPHA)
    tileStart1_rect.fill(WHITE)
    tileStart1['rect'] = DISPLAYSURF.blit(tileStart1_rect, (tileStart1['X']*tilewidth + camerax*tilewidth,tileStart1['Y']*tileheight + cameray*tileheight))

    tiledGrass1 = { 'area':1, 'type': 'ground', 'X': 0,'Y': 13, 'sizeX': 51,'sizeY': 3   }
    tiledGrass1_size = (tiledGrass1['sizeX']*tilewidth,tiledGrass1['sizeY']*tileheight)
    tiledGrass1_rect =  pygame.Surface(tiledGrass1_size)
    tiledGrass1_rect.set_alpha(SET_ALPHA)
    tiledGrass1_rect.fill(WHITE)
    tiledGrass1['rect'] = DISPLAYSURF.blit(tiledGrass1_rect, (tiledGrass1['X']*tilewidth + camerax*tilewidth,tiledGrass1['Y']*tileheight + cameray*tileheight))

    tiledStone1={ 'area':1, 'type': 'ground', 'X': 12,'Y': 12, 'sizeX': 11,'sizeY': 1  }
    tiledStone1_size = (tiledStone1['sizeX']*tilewidth,tiledStone1['sizeY']*tileheight)
    tiledStone1_rect =  pygame.Surface(tiledStone1_size)
    tiledStone1_rect.set_alpha(SET_ALPHA)
    tiledStone1_rect.fill(WHITE)
    tiledStone1['rect'] = DISPLAYSURF.blit(tiledStone1_rect, (tiledStone1['X']*tilewidth + camerax*tilewidth,tiledStone1['Y']*tileheight + cameray*tileheight))

    tiledStone2={ 'area':1, 'type': 'ground', 'X': 13,'Y': 11, 'sizeX': 9,'sizeY': 1   }
    tiledStone2_size = (tiledStone2['sizeX']*tilewidth,tiledStone2['sizeY']*tileheight)
    tiledStone2_rect =  pygame.Surface(tiledStone2_size)
    tiledStone2_rect.set_alpha(SET_ALPHA)
    tiledStone2_rect.fill(WHITE)
    tiledStone2['rect'] = DISPLAYSURF.blit(tiledStone2_rect, (tiledStone2['X']*tilewidth + camerax*tilewidth,tiledStone2['Y']*tileheight + cameray*tileheight))

    tiledStone3={ 'area':1, 'type': 'ground', 'X': 14,'Y': 10, 'sizeX': 7,'sizeY': 1   }
    tiledStone3_size = (tiledStone3['sizeX']*tilewidth,tiledStone3['sizeY']*tileheight)
    tiledStone3_rect =  pygame.Surface(tiledStone3_size)
    tiledStone3_rect.set_alpha(SET_ALPHA)
    tiledStone3_rect.fill(WHITE)
    tiledStone3['rect'] = DISPLAYSURF.blit(tiledStone3_rect, (tiledStone3['X']*tilewidth + camerax*tilewidth,tiledStone3['Y']*tileheight + cameray*tileheight))

    tiledStone4={ 'area':1, 'type': 'ground', 'X': 15,'Y': 9, 'sizeX': 5,'sizeY': 1   }
    tiledStone4_size = (tiledStone4['sizeX']*tilewidth,tiledStone4['sizeY']*tileheight)
    tiledStone4_rect =  pygame.Surface(tiledStone4_size)
    tiledStone4_rect.set_alpha(SET_ALPHA)
    tiledStone4_rect.fill(WHITE)
    tiledStone4['rect'] = DISPLAYSURF.blit(tiledStone4_rect, (tiledStone4['X']*tilewidth + camerax*tilewidth,tiledStone4['Y']*tileheight + cameray*tileheight))

    tiledStone5={ 'area':1, 'type': 'ground', 'X': 16,'Y': 8, 'sizeX': 3,'sizeY': 1   }
    tiledStone5_size = (tiledStone5['sizeX']*tilewidth,tiledStone5['sizeY']*tileheight)
    tiledStone5_rect =  pygame.Surface(tiledStone5_size)
    tiledStone5_rect.set_alpha(SET_ALPHA)
    tiledStone5_rect.fill(WHITE)
    tiledStone5['rect'] = DISPLAYSURF.blit(tiledStone5_rect, (tiledStone5['X']*tilewidth + camerax*tilewidth,tiledStone5['Y']*tileheight + cameray*tileheight))

    tiledSnow1={ 'area':1, 'type': 'ground', 'X': 25,'Y': 8, 'sizeX': 5,'sizeY': 2   }
    tiledSnow1_size = (tiledSnow1['sizeX']*tilewidth,tiledSnow1['sizeY']*tileheight)
    tiledSnow1_rect =  pygame.Surface(tiledSnow1_size)
    tiledSnow1_rect.set_alpha(SET_ALPHA)
    tiledSnow1_rect.fill(WHITE)
    tiledSnow1['rect'] = DISPLAYSURF.blit(tiledSnow1_rect, (tiledSnow1['X']*tilewidth + camerax*tilewidth,tiledSnow1['Y']*tileheight + cameray*tileheight))

    tiledSnow2={ 'area':1, 'type': 'ground', 'X': 33,'Y': 6, 'sizeX': 6,'sizeY': 2   }
    tiledSnow2_size = (tiledSnow2['sizeX']*tilewidth,tiledSnow2['sizeY']*tileheight)
    tiledSnow2_rect =  pygame.Surface(tiledSnow2_size)
    tiledSnow2_rect.set_alpha(SET_ALPHA)
    tiledSnow2_rect.fill(WHITE)
    tiledSnow2['rect'] = DISPLAYSURF.blit(tiledSnow2_rect, (tiledSnow2['X']*tilewidth + camerax*tilewidth,tiledSnow2['Y']*tileheight + cameray*tileheight))

    tiledSnow3={ 'area':1, 'type': 'ground', 'X': 38,'Y': 12, 'sizeX': 6,'sizeY': 1   }
    tiledSnow3_size = (tiledSnow3['sizeX']*tilewidth,tiledSnow3['sizeY']*tileheight)
    tiledSnow3_rect =  pygame.Surface(tiledSnow3_size)
    tiledSnow3_rect.set_alpha(SET_ALPHA)
    tiledSnow3_rect.fill(WHITE)
    tiledSnow3['rect'] = DISPLAYSURF.blit(tiledSnow3_rect, (tiledSnow3['X']*tilewidth + camerax*tilewidth,tiledSnow3['Y']*tileheight + cameray*tileheight))

    tiledTyp1={ 'area':1, 'type': 'ground', 'X': 44,'Y': 9, 'sizeX': 3,'sizeY': 4   }
    tiledTyp1_size = (tiledTyp1['sizeX']*tilewidth,tiledTyp1['sizeY']*tileheight)
    tiledTyp1_rect =  pygame.Surface(tiledTyp1_size)
    tiledTyp1_rect.set_alpha(SET_ALPHA)
    tiledTyp1_rect.fill(WHITE)
    tiledTyp1['rect'] = DISPLAYSURF.blit(tiledTyp1_rect, (tiledTyp1['X']*tilewidth + camerax*tilewidth,tiledTyp1['Y']*tileheight + cameray*tileheight))

    # Area 2

    tiledGrass2 = { 'area':2, 'type': 'ground', 'X': 53,'Y': 10, 'sizeX': 6,'sizeY': 2   }
    tiledGrass2_size = (tiledGrass2['sizeX']*tilewidth,tiledGrass2['sizeY']*tileheight)
    tiledGrass2_rect =  pygame.Surface(tiledGrass2_size)
    tiledGrass2_rect.set_alpha(SET_ALPHA)
    tiledGrass2_rect.fill(WHITE)
    tiledGrass2['rect'] = DISPLAYSURF.blit(tiledGrass2_rect, (tiledGrass2['X']*tilewidth + camerax*tilewidth,tiledGrass2['Y']*tileheight + cameray*tileheight))

    tiledGrass3 = { 'area':2, 'type': 'ground', 'X': 61,'Y': 8, 'sizeX': 7,'sizeY': 2   }
    tiledGrass3_size = (tiledGrass3['sizeX']*tilewidth,tiledGrass3['sizeY']*tileheight)
    tiledGrass3_rect =  pygame.Surface(tiledGrass3_size)
    tiledGrass3_rect.set_alpha(SET_ALPHA)
    tiledGrass3_rect.fill(WHITE)
    tiledGrass3['rect'] = DISPLAYSURF.blit(tiledGrass3_rect, (tiledGrass3['X']*tilewidth + camerax*tilewidth,tiledGrass3['Y']*tileheight + cameray*tileheight))

    tiledSea1 = { 'area':2, 'type': 'sea', 'X': 51,'Y': 14, 'sizeX': 19,'sizeY': 2   }
    tiledSea1_size = (tiledSea1['sizeX']*tilewidth,tiledSea1['sizeY']*tileheight)
    tiledSea1_rect =  pygame.Surface(tiledSea1_size)
    tiledSea1_rect.set_alpha(SET_ALPHA)
    tiledSea1_rect.fill(WHITE)
    tiledSea1['rect'] = DISPLAYSURF.blit(tiledSea1_rect, (tiledSea1['X']*tilewidth + camerax*tilewidth,tiledSea1['Y']*tileheight + cameray*tileheight))

    tiledSand1 = { 'area':2, 'type': 'ground', 'X': 70,'Y': 13, 'sizeX': 52,'sizeY': 3   }
    tiledSand1_size = (tiledSand1['sizeX']*tilewidth,tiledSand1['sizeY']*tileheight)
    tiledSand1_rect =  pygame.Surface(tiledSand1_size)
    tiledSand1_rect.set_alpha(SET_ALPHA)
    tiledSand1_rect.fill(WHITE)
    tiledSand1['rect'] = DISPLAYSURF.blit(tiledSand1_rect, (tiledSand1['X']*tilewidth + camerax*tilewidth,tiledSand1['Y']*tileheight + cameray*tileheight))

    tiledGrass4 = { 'area':2, 'type': 'ground', 'X': 72,'Y': 5, 'sizeX': 6,'sizeY': 2   }
    tiledGrass4_size = (tiledGrass4['sizeX']*tilewidth,tiledGrass4['sizeY']*tileheight)
    tiledGrass4_rect =  pygame.Surface(tiledGrass4_size)
    tiledGrass4_rect.set_alpha(SET_ALPHA)
    tiledGrass4_rect.fill(WHITE)
    tiledGrass4['rect'] = DISPLAYSURF.blit(tiledGrass4_rect, (tiledGrass4['X']*tilewidth + camerax*tilewidth,tiledGrass4['Y']*tileheight + cameray*tileheight))

    tiledStone6={ 'area':2, 'type': 'ground', 'X': 85,'Y': 10, 'sizeX': 4,'sizeY': 1   }
    tiledStone6_size = (tiledStone6['sizeX']*tilewidth,tiledStone6['sizeY']*tileheight)
    tiledStone6_rect =  pygame.Surface(tiledStone6_size)
    tiledStone6_rect.set_alpha(SET_ALPHA)
    tiledStone6_rect.fill(WHITE)
    tiledStone6['rect'] = DISPLAYSURF.blit(tiledStone6_rect, (tiledStone6['X']*tilewidth + camerax*tilewidth,tiledStone6['Y']*tileheight + cameray*tileheight))

    tiledStone7={ 'area':2, 'type': 'ground', 'X': 85,'Y': 11, 'sizeX': 8,'sizeY': 2   }
    tiledStone7_size = (tiledStone7['sizeX']*tilewidth,tiledStone7['sizeY']*tileheight)
    tiledStone7_rect =  pygame.Surface(tiledStone7_size)
    tiledStone7_rect.set_alpha(SET_ALPHA)
    tiledStone7_rect.fill(WHITE)
    tiledStone7['rect'] = DISPLAYSURF.blit(tiledStone7_rect, (tiledStone7['X']*tilewidth + camerax*tilewidth,tiledStone7['Y']*tileheight + cameray*tileheight))

    tiledStone8={ 'area':2, 'type': 'ground', 'X': 101,'Y': 12, 'sizeX': 1,'sizeY': 1   }
    tiledStone8_size = (tiledStone8['sizeX']*tilewidth,tiledStone8['sizeY']*tileheight)
    tiledStone8_rect =  pygame.Surface(tiledStone8_size)
    tiledStone8_rect.set_alpha(SET_ALPHA)
    tiledStone8_rect.fill(WHITE)
    tiledStone8['rect'] = DISPLAYSURF.blit(tiledStone8_rect, (tiledStone8['X']*tilewidth + camerax*tilewidth,tiledStone8['Y']*tileheight + cameray*tileheight))

    tiledStone9={ 'area':2, 'type': 'ground', 'X': 104,'Y': 11, 'sizeX': 1,'sizeY': 2   }
    tiledStone9_size = (tiledStone9['sizeX']*tilewidth,tiledStone9['sizeY']*tileheight)
    tiledStone9_rect =  pygame.Surface(tiledStone9_size)
    tiledStone9_rect.set_alpha(SET_ALPHA)
    tiledStone9_rect.fill(WHITE)
    tiledStone9['rect'] = DISPLAYSURF.blit(tiledStone9_rect, (tiledStone9['X']*tilewidth + camerax*tilewidth,tiledStone9['Y']*tileheight + cameray*tileheight))

    tiledStone10={ 'area':2, 'type': 'ground', 'X': 107,'Y': 10, 'sizeX': 1,'sizeY': 3   }
    tiledStone10_size = (tiledStone10['sizeX']*tilewidth,tiledStone10['sizeY']*tileheight)
    tiledStone10_rect =  pygame.Surface(tiledStone10_size)
    tiledStone10_rect.set_alpha(SET_ALPHA)
    tiledStone10_rect.fill(WHITE)
    tiledStone10['rect'] = DISPLAYSURF.blit(tiledStone10_rect, (tiledStone10['X']*tilewidth + camerax*tilewidth,tiledStone10['Y']*tileheight + cameray*tileheight))

    tiledStone11={ 'area':2, 'type': 'ground', 'X': 110,'Y': 9, 'sizeX': 1,'sizeY': 4   }
    tiledStone11_size = (tiledStone11['sizeX']*tilewidth,tiledStone11['sizeY']*tileheight)
    tiledStone11_rect =  pygame.Surface(tiledStone11_size)
    tiledStone11_rect.set_alpha(SET_ALPHA)
    tiledStone11_rect.fill(WHITE)
    tiledStone11['rect'] = DISPLAYSURF.blit(tiledStone11_rect, (tiledStone11['X']*tilewidth + camerax*tilewidth,tiledStone11['Y']*tileheight + cameray*tileheight))

    tiledStone12={ 'area':2, 'type': 'ground', 'X': 113,'Y': 10, 'sizeX': 1,'sizeY': 3   }
    tiledStone12_size = (tiledStone12['sizeX']*tilewidth,tiledStone12['sizeY']*tileheight)
    tiledStone12_rect =  pygame.Surface(tiledStone12_size)
    tiledStone12_rect.set_alpha(SET_ALPHA)
    tiledStone12_rect.fill(WHITE)
    tiledStone12['rect'] = DISPLAYSURF.blit(tiledStone12_rect, (tiledStone12['X']*tilewidth + camerax*tilewidth,tiledStone12['Y']*tileheight + cameray*tileheight))

    tiledStone13={ 'area':2, 'type': 'ground', 'X': 116,'Y': 11, 'sizeX': 1,'sizeY': 2   }
    tiledStone13_size = (tiledStone13['sizeX']*tilewidth,tiledStone13['sizeY']*tileheight)
    tiledStone13_rect =  pygame.Surface(tiledStone13_size)
    tiledStone13_rect.set_alpha(SET_ALPHA)
    tiledStone13_rect.fill(WHITE)
    tiledStone13['rect'] = DISPLAYSURF.blit(tiledStone13_rect, (tiledStone13['X']*tilewidth + camerax*tilewidth,tiledStone13['Y']*tileheight + cameray*tileheight))

    tiledStone14={ 'area':2, 'type': 'ground', 'X': 118,'Y': 12, 'sizeX': 1,'sizeY': 1   }
    tiledStone14_size = (tiledStone14['sizeX']*tilewidth,tiledStone14['sizeY']*tileheight)
    tiledStone14_rect =  pygame.Surface(tiledStone14_size)
    tiledStone14_rect.set_alpha(SET_ALPHA)
    tiledStone14_rect.fill(WHITE)
    tiledStone14['rect'] = DISPLAYSURF.blit(tiledStone14_rect, (tiledStone14['X']*tilewidth + camerax*tilewidth,tiledStone14['Y']*tileheight + cameray*tileheight))

    # Area 3

    tiledSea2 = { 'area':3, 'type': 'sea', 'X': 122,'Y': 14, 'sizeX': 48,'sizeY': 2   }
    tiledSea2_size = (tiledSea2['sizeX']*tilewidth,tiledSea2['sizeY']*tileheight)
    tiledSea2_rect =  pygame.Surface(tiledSea2_size)
    tiledSea2_rect.set_alpha(SET_ALPHA)
    tiledSea2_rect.fill(WHITE)
    tiledSea2['rect'] = DISPLAYSURF.blit(tiledSea2_rect, (tiledSea2['X']*tilewidth + camerax*tilewidth,tiledSea2['Y']*tileheight + cameray*tileheight))

    tiledSnow4={ 'area':3, 'type': 'ground', 'X': 124,'Y': 10, 'sizeX': 5,'sizeY': 2   }
    tiledSnow4_size = (tiledSnow4['sizeX']*tilewidth,tiledSnow4['sizeY']*tileheight)
    tiledSnow4_rect =  pygame.Surface(tiledSnow4_size)
    tiledSnow4_rect.set_alpha(SET_ALPHA)
    tiledSnow4_rect.fill(WHITE)
    tiledSnow4['rect'] = DISPLAYSURF.blit(tiledSnow4_rect, (tiledSnow4['X']*tilewidth + camerax*tilewidth,tiledSnow4['Y']*tileheight + cameray*tileheight))

    tiledSnow5={ 'area':3, 'type': 'ground', 'X': 131,'Y': 7, 'sizeX': 5,'sizeY': 2   }
    tiledSnow5_size = (tiledSnow5['sizeX']*tilewidth,tiledSnow5['sizeY']*tileheight)
    tiledSnow5_rect =  pygame.Surface(tiledSnow5_size)
    tiledSnow5_rect.set_alpha(SET_ALPHA)
    tiledSnow5_rect.fill(WHITE)
    tiledSnow5['rect'] = DISPLAYSURF.blit(tiledSnow5_rect, (tiledSnow5['X']*tilewidth + camerax*tilewidth,tiledSnow5['Y']*tileheight + cameray*tileheight))

    tiledSnow6={ 'area':3, 'type': 'ground', 'X': 139,'Y': 5, 'sizeX': 6,'sizeY': 2   }
    tiledSnow6_size = (tiledSnow6['sizeX']*tilewidth,tiledSnow6['sizeY']*tileheight)
    tiledSnow6_rect =  pygame.Surface(tiledSnow6_size)
    tiledSnow6_rect.set_alpha(SET_ALPHA)
    tiledSnow6_rect.fill(WHITE)
    tiledSnow6['rect'] = DISPLAYSURF.blit(tiledSnow6_rect, (tiledSnow6['X']*tilewidth + camerax*tilewidth,tiledSnow6['Y']*tileheight + cameray*tileheight))

    tiledSnow7={ 'area':3, 'type': 'ground', 'X': 148,'Y': 11, 'sizeX': 6,'sizeY': 2   }
    tiledSnow7_size = (tiledSnow7['sizeX']*tilewidth,tiledSnow7['sizeY']*tileheight)
    tiledSnow7_rect =  pygame.Surface(tiledSnow7_size)
    tiledSnow7_rect.set_alpha(SET_ALPHA)
    tiledSnow7_rect.fill(WHITE)
    tiledSnow7['rect'] = DISPLAYSURF.blit(tiledSnow7_rect, (tiledSnow7['X']*tilewidth + camerax*tilewidth,tiledSnow7['Y']*tileheight + cameray*tileheight))

    tiledSnow8={ 'area':3, 'type': 'ground', 'X': 155,'Y': 8, 'sizeX': 6,'sizeY': 2   }
    tiledSnow8_size = (tiledSnow8['sizeX']*tilewidth,tiledSnow8['sizeY']*tileheight)
    tiledSnow8_rect =  pygame.Surface(tiledSnow8_size)
    tiledSnow8_rect.set_alpha(SET_ALPHA)
    tiledSnow8_rect.fill(WHITE)
    tiledSnow8['rect'] = DISPLAYSURF.blit(tiledSnow8_rect, (tiledSnow8['X']*tilewidth + camerax*tilewidth,tiledSnow8['Y']*tileheight + cameray*tileheight))

    tiledSnow9={ 'area':3, 'type': 'ground', 'X': 163,'Y': 6, 'sizeX': 2,'sizeY': 2   }
    tiledSnow9_size = (tiledSnow9['sizeX']*tilewidth,tiledSnow9['sizeY']*tileheight)
    tiledSnow9_rect =  pygame.Surface(tiledSnow9_size)
    tiledSnow9_rect.set_alpha(SET_ALPHA)
    tiledSnow9_rect.fill(WHITE)
    tiledSnow9['rect'] = DISPLAYSURF.blit(tiledSnow9_rect, (tiledSnow9['X']*tilewidth + camerax*tilewidth,tiledSnow9['Y']*tileheight + cameray*tileheight))

    tiledSnow10={ 'area':3, 'type': 'ground', 'X': 167,'Y': 4, 'sizeX': 2,'sizeY': 2   }
    tiledSnow10_size = (tiledSnow10['sizeX']*tilewidth,tiledSnow10['sizeY']*tileheight)
    tiledSnow10_rect =  pygame.Surface(tiledSnow10_size)
    tiledSnow10_rect.set_alpha(SET_ALPHA)
    tiledSnow10_rect.fill(WHITE)
    tiledSnow10['rect'] = DISPLAYSURF.blit(tiledSnow10_rect, (tiledSnow10['X']*tilewidth + camerax*tilewidth,tiledSnow10['Y']*tileheight + cameray*tileheight))

    # ----------------------------------------------------------

    # Area 1
    tiledColisions.append(tileStart1)
    tiledColisions.append(tiledGrass1)
    tiledColisions.append(tiledStone1)
    tiledColisions.append(tiledStone2)
    tiledColisions.append(tiledStone3)
    tiledColisions.append(tiledStone4)
    tiledColisions.append(tiledStone5)
    tiledColisions.append(tiledSnow1)
    tiledColisions.append(tiledSnow2)
    tiledColisions.append(tiledSnow3)
    tiledColisions.append(tiledTyp1)

    # Area 2
    tiledColisions2.append(tiledGrass2)
    tiledColisions2.append(tiledGrass3)
    tiledColisions2.append(tiledSea1)
    tiledColisions2.append(tiledSand1)
    tiledColisions2.append(tiledGrass4)
    tiledColisions2.append(tiledStone6)
    tiledColisions2.append(tiledStone7)
    tiledColisions2.append(tiledStone8)
    tiledColisions2.append(tiledStone9)
    tiledColisions2.append(tiledStone10)
    tiledColisions2.append(tiledStone11)
    tiledColisions2.append(tiledStone12)
    tiledColisions2.append(tiledStone13)
    tiledColisions2.append(tiledStone14)

    # Area 3

    tiledColisions3.append(tiledSea2)
    tiledColisions3.append(tiledSnow4)
    tiledColisions3.append(tiledSnow5)
    tiledColisions3.append(tiledSnow6)
    tiledColisions3.append(tiledSnow7)
    tiledColisions3.append(tiledSnow8)
    tiledColisions3.append(tiledSnow9)
    tiledColisions3.append(tiledSnow10)

    return tiledColisions, tiledColisions2, tiledColisions3

# def drawRectCrystal(crystalObj, DISPLAYSURF, SET_ALPHA, camerax, cameray, tilewidth, tileheight):
#
#     # Area 1
#
#     crystal={ 'area':1, 'type': 'crytal' }
#     crystal_size = (30,30)
#     crystal_rect =  pygame.Surface(crystal_size)
#     crystal_rect.set_alpha(SET_ALPHA)
#     crystal_rect.fill(GRASSCOLOR)
#     crystal['rect'] = DISPLAYSURF.blit(crystal_rect, (crystalObj['x']*tilewidth + camerax*tilewidth,crystalObj['y']*tileheight + cameray*tileheight))
#
#
# #         print(crystalList)
#     return crystal


import cv2 as cv
import progressbar
import numpy as np

import file_module

'''
def nothing(x):
    pass
'''

img_dir = "E:/data/Item-Image"
save_dir = "E:/data/masked-Image"

img_list = file_module.loadImage(img_dir)

bar = progressbar.ProgressBar(maxval=len(img_list)).start()
for index, row in img_list.iterrows():

    img_path = img_dir +'/'+ row['file_name']
    save_path = save_dir +'/'+ row['file_name']

    '''
    cv.namedWindow('binary')
    cv.createTrackbar('threshold', 'binary', 0, 255, nothing)
    cv.setTrackbarPos('threshold', 'binary', 230)
    '''

    img_color = cv.imread(img_path)
    img_gray = cv.cvtColor(img_color, cv.COLOR_BGR2GRAY)

    while(True):

        #low = cv.getTrackbarPos('threshold', 'binary')

        ret,img_binary = cv.threshold(img_gray, 230, 255, cv.THRESH_BINARY_INV)

        #cv2.threshold( grayscale image, threshold_value, value, flag{cv2.THRESH_BINARY_INV : pixle 값이 threshold_value 보다 크면 0, 작으면 value로} )

        #cv.imshow('binary', img_binary)
        #cv.imshow("color", img_color)
        cv.imwrite(save_path, img_binary)

        #if cv.waitKey(1)&0xFF == 27: # esc 누르면 닫음
        break
    bar.update(index)

print("process complete")


def solution(numbers):
    answer = []
    numbers.sort()
    for i in range(len(numbers) + 1):
        for j in range(i + 1, len(numbers) + 1):
            try:
                answer.append(numbers[i] + numbers[j])
            except:
                break

    return sorted(list(set(answer)))


import csv
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import datetime as dt
from collections import OrderedDict
plt.style.use('seaborn')
import json
import os

def loadData(names=["Deutschland"], altersgruppen=['A80+']):
    if not os.path.isfile('full-data.csv'):
        print("### Please download the data from https://pavelmayer.de/covid/risks/data.csv")
        break
    for name in names:
        for altersgruppe in altersgruppen:
            with open('full-data.csv', newline='') as csvfile:
                spamreader = csv.reader(csvfile, delimiter=',', quotechar='|')
                csv_headers = next(spamreader)
                i=[]
                idate={}
                ideaths={}
                for row in spamreader:
                    datestringrow = int(row[8])/1000
                    if name in ['Sachsen', 'Baden-Württemberg', 'Rheinland-Pfalz', 'Thüringen', 'Hamburg' , 'Niedersachsen', 'Bayern', 'Brandenburg', 'Berlin', 'Schleswig-Holstein', 'Saarland', 'Sachsen-Anhalt', 'Mecklenburg-Vorpommern', 'Nordrhein-Westfalen', 'Bremen', 'Hessen']:
                        # print(row[1], row[1].find(name) > 0)
                        if row[1] == name:
                            if row[3] == altersgruppe:
                                i.append(row)
                                if not datestringrow in idate:
                                     idate[datestringrow] = 0
                                idate[datestringrow] = idate[datestringrow] + int(row[5])

                                if not datestringrow in ideaths:
                                     ideaths[datestringrow] = 0
                                ideaths[datestringrow] = ideaths[datestringrow] + int(row[6])
                    elif name != "Deutschland":
                        if row[2].find(name) > 0:
                            # i.append(row)
                            if row[3] == altersgruppe:
                                i.append(row)
                                if not datestringrow in idate:
                                     idate[datestringrow] = 0
                                idate[datestringrow] = idate[datestringrow] + int(row[5])

                                if not datestringrow in ideaths:
                                     ideaths[datestringrow] = 0
                                ideaths[datestringrow] = ideaths[datestringrow] + int(row[6])
                    else:
                        # Gesamt
                        if row[3] == altersgruppe:
                            # i.append(row)
                            if not datestringrow in idate:
                                 idate[datestringrow] = 0
                            idate[datestringrow] = idate[datestringrow] + int(row[5])

                            if not datestringrow in ideaths:
                                 ideaths[datestringrow] = 0
                            ideaths[datestringrow] = ideaths[datestringrow] + int(row[6])
                data = {'date':idate, 'deaths': ideaths, 'raw': i}
                with open('data/data_'+name+'_'+altersgruppe+'.txt', 'w') as fobj:
                    json.dump(data, fobj)

def calc7Tage(input80date, einwohneranzahl, raum=-7):
    output7Tage = {}
    for keyO, valueO in input80date.items():
        anzahlSUM = 0
        for key, value in input80date.items():
            delta = keyO - key
            if (delta > dt.timedelta(days = raum)) and (delta <= dt.timedelta(days = 0)):
                anzahlSUM = anzahlSUM + value
        output7Tage[keyO] = anzahlSUM/einwohneranzahl * 100000
    output7Tage = OrderedDict(sorted(output7Tage.items(), key=lambda t: t[0]))
    return output7Tage

def calcNormalized(input80date, einwohneranzahl, raum=-7):
    ret = {}
    for key, value in input80date.items():
        ret[key] = value/einwohneranzahl * 100000
    ret = OrderedDict(sorted(ret.items(), key=lambda t: t[0]))
    return ret

def savePlot(in7, in14, in80deaths, name, color, startdate, altersgruppe, einwohneranzahl, max1=60, max2=6):
    fig, host = plt.subplots(figsize=(15,4),sharex=True)
    fig.suptitle('Corona bei Altersgruppe '+altersgruppe, fontsize=16)
    ax2 = host.twinx()
    lns = []

    host.set_ylabel("Inzidenz pro 100k")
    p11, = host.plot_date(in7.keys(),in7.values(),linestyle='solid',color =color,label=name+' 7 Tages Inzidenz', marker=",")
    lns.append(p11)

    ax2.set_ylabel("Gemeldete Tote pro 100k")
    p21, = ax2.plot_date(in80deaths.keys(),in80deaths.values(),linestyle='dashed',color =color,label=name+' Todeszahlen Normalisiert', marker=",")
    lns.append(p21)

    # p12, = host.plot_date(in14.keys(),in14.values(),linestyle="dashdot",color=color,label=name+' 14 Tages Inzidenz', marker=",")
    # lns.append(p12)

    if max1 > 0:
        host.set_ylim(0, max1)
    if max2 > 0:
        ax2.set_ylim(0, max2)

    # lns = [p11, p21, p12]
    host.legend(handles=lns, bbox_to_anchor=(0, 1, 1, 0), loc="lower left", mode="expand", ncol=2)
    fig.autofmt_xdate()
    # fig.fmt_xdata = mdates.DateFormatter('%d.%m.%Y')
    datexticks = [startdate]
    today = dt.datetime.today()
    while startdate < today:
        startdate = startdate + dt.timedelta(days=7)
        datexticks.append(startdate)

    date_formatter = mdates.DateFormatter('%d.%m.%Y')
    # Set the major tick formatter to use your date formatter.
    host.set_xticks(datexticks)
    host.xaxis.set_major_formatter(date_formatter)
    host.tick_params(axis="x",labelrotation=30)
    # estring = f'{600:,}'
    host.text(0,-0.285,
        'Einwohneranzahl: '+'{:,}'.format(einwohneranzahl)+' | Letzter Datenpunkt: '+list(in7.keys())[-1].strftime('%d.%m.%Y')+' | Erstellt am: '+today.strftime('%d.%m.%Y'),
        size=9, ha="left",
        transform=host.transAxes)
    # plt.show()
    fig.tight_layout()
    fig.savefig('graphs/'+name+'_'+altersgruppe+'.png', orientation='landscape')

def createPlots(names, altersgruppen, color="black", startdate=dt.datetime(2020,10,1), maxYInzidenz=60, maxYTodeszahlen=6):
    for name, einwohneranzahl in names.items():
        for altersgruppe in altersgruppen:
            i80date = {}
            i80deaths = {}
            if not os.path.isfile('data/data_'+name+'_'+altersgruppe+'.txt'):
                loadData([name], [altersgruppe])
            with open('data/data_'+name+'_'+altersgruppe+'.txt') as fobj:
                data = json.load(fobj)
                i80dateRAW = data["date"]
                i80deathsRAW = data["deaths"]
                i80RAW = data["raw"]
            for key, value in i80dateRAW.items():
                if dt.datetime.fromtimestamp(float(key)) > startdate:
                    i80date[dt.datetime.fromtimestamp(float(key))]=value
            for key, value in i80deathsRAW.items():
                if dt.datetime.fromtimestamp(float(key)) > startdate:
                    i80deaths[dt.datetime.fromtimestamp(float(key))]=value

            i80date = OrderedDict(sorted(i80date.items(), key=lambda t: t[0]))
            i80deaths = OrderedDict(sorted(i80deaths.items(), key=lambda t: t[0]))
            i80deathsN = calcNormalized(i80deaths, einwohneranzahl)
            i7 = calc7Tage(i80date, einwohneranzahl)
            i14 = calc7Tage(i80date, einwohneranzahl, -14)
            savePlot(i7, i14, i80deathsN, name, color, startdate, altersgruppe, einwohneranzahl, maxYInzidenz, maxYTodeszahlen)

# HERE
createPlots(
    {"Deutschland": 83166711, "Bayern": 13124737, "Tirschenreuth": 72046}, ["A80+", "A60-A79", "A35-A59"], "black", dt.datetime(2020,9,1), 0, 0)
# createPlots(
#     ['Sachsen', 'Baden-Württemberg', 'Rheinland-Pfalz', 'Thüringen', 'Hamburg' , 'Niedersachsen', 'Bayern', 'Brandenburg', 'Berlin', 'Schleswig-Holstein', 'Saarland', 'Sachsen-Anhalt', 'Mecklenburg-Vorpommern', 'Nordrhein-Westfalen', 'Bremen', 'Hessen'],
#     ["A80+", "A60-A79", "A35-A59"],, "A60-A79", "A35-A59", "A15-A34", "A05-A14", "A00-A04" , "Schweinfurt": 115445, "Tirschenreuth": 72046
#     [83166711],
#     "black", dt.datetime(2020,9,1), 0, 0)


import os

import psycopg2
import pytest

from ddtrace.contrib.psycopg.patch import patch
from ddtrace.contrib.psycopg.patch import unpatch
from ddtrace.vendor import wrapt
from tests.contrib.config import POSTGRES_CONFIG
from tests.utils import override_config

@pytest.fixture(autouse=True)
def patch_psycopg():
    patch()
    assert isinstance(psycopg2.connect, wrapt.ObjectProxy)
    yield
    unpatch()

@pytest.mark.snapshot()
def test_connect_default():
    """By default we do not trace psycopg2.connect method"""
    conn = psycopg2.connect(**POSTGRES_CONFIG)
    assert conn

@pytest.mark.snapshot(wait_for_num_traces=1)
def test_connect_traced():
    """When explicitly enabled, we trace psycopg2.connect method"""
    with override_config("psycopg", {"trace_connect": True}):
        conn = psycopg2.connect(**POSTGRES_CONFIG)
        assert conn

@pytest.mark.snapshot(token="tests.contrib.psycopg2.test_psycopg_snapshot.test_connect_traced", wait_for_num_traces=1)
def test_connect_traced_via_env(run_python_code_in_subprocess):
    """When explicitly enabled, we trace psycopg2.connect method"""

    code = """
import psycopg2

import ddtrace
from tests.contrib.config import POSTGRES_CONFIG

ddtrace.patch_all()

conn = psycopg2.connect(**POSTGRES_CONFIG)
assert conn
    """

    env = os.environ.copy()
    env["DD_PSYCOPG2_TRACE_CONNECT"] = "true"
    out, err, status, pid = run_python_code_in_subprocess(code, env=env)
    assert status == 0, err
    assert out == b"", err
    assert err == b""


# 1323. Maximum 69 Number
class Solution:
    def maximum69Number (self, num: int) -> int:
        res = list(str(num))
        for i in range(len(res)):
            if res[i] == '6':
                res[i] = '9'
                return int(''.join(res))
        return num

# 1331. Rank Transform of an Array
class Solution:
    def arrayRankTransform(self, arr: List[int]) -> List[int]:
        if len(arr) == 0:
            return []

        arr_sort = sorted(arr)
        store = {}
        curr = 1
        store[arr_sort[0]] = curr
        for i in range(1, len(arr_sort)):
            if arr_sort[i] == arr_sort[i-1]:
                continue
            else:
                curr += 1
                store[arr_sort[i]] = curr

        return [store[val] for val in arr]

# 1337. The K Weakest Rows in a Matrix
class Solution:
    def kWeakestRows(self, mat: List[List[int]], k: int) -> List[int]:
        res = []
        for i in range(len(mat)):
            res.append(((sum(mat[i])), i))

        res.sort(key=lambda x: (x[0], [1]))
        return [res[i][1] for i in range(k)]

class Solution: # vertical search
    def kWeakestRows(self, mat: List[List[int]], k: int) -> List[int]:
        row = len(mat)
        col = len(mat[0])

        res = []
        for j in range(col):
            for i in range(row):
                if mat[i][j] == 0 and i not in res:
                    res.append(i)
                if len(res) == k:
                    return res

        l = 0
        while len(res) < k:
            if mat[l][-1] == 1:
                res.append(l)
            l += 1
        return res

# 1342. Number of Steps to Reduce a Number to Zero
class Solution:
    def numberOfSteps (self, num: int) -> int:
        count = 0
        while num > 0:
            if num % 2 == 0:
                num = num >> 1
            else:
                num -= 1
            count += 1
        return count

class Solution:
    def numberOfSteps (self, num: int) -> int:
        bitnum = bin(num)[2:]
        return bitnum.count('1')*2+bitnum.count('0')-1

# 1346. Check If N and Its Double Exist
class Solution: #caution: 0
    def checkIfExist(self, arr: List[int]) -> bool:
        store = {}
        for i in range(len(arr)):
            if arr[i] not in store:
                store[arr[i]] = [i]
            else:
                store[arr[i]].append(i)
        for i in range(len(arr)):
            val = arr[i] * 2
            if val in store:
                for idx in store[val]:
                    if i != idx:
                        return True
        return False


import pandas as pd
import matplotlib.pyplot as plt
import sys
import numpy as np
import sklearn as sk
import seaborn as sns
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import GridSearchCV
from joblib import dump
from joblib import load
from sklearn.feature_selection import RFE
from sklearn.metrics import f1_score
import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)

def build_pipeline(classifier, isScaled, selectFeatures):
    """
    This function takes a scikit-learn classifier and builds a ML
    pipeline that applies a series of transformations.

    Parameters:
    - classifier: The machine learning classifer of interest ex. KNN
    - isScaled(bool): Should we scale data? True or False
    - selectFeatures(bool): Should we perform RFE? True or False

    Returns:
    - pipe(Pipeline): A ML pipeline capable of transforming data

    """
    try:
        if selectFeatures:
            if isScaled:
                pipe = Pipeline(steps=[("imputer", SimpleImputer()),
                                       ("scale", StandardScaler()),
                                       ("rfe", RFE(estimator=classifier)),
                                       ("clf", classifier)])
            else:
                pipe = Pipeline(steps=[("imputer", SimpleImputer()),
                                       ("rfe", RFE(estimator=classifier)),
                                       ("clf", classifier)])
        else:
            if isScaled:
                pipe = Pipeline(steps=[("imputer", SimpleImputer()),
                                       ("scale", StandardScaler()),
                                       ("clf", classifier)])
            else:
                pipe = Pipeline(steps=[("imputer", SimpleImputer()),
                                       ("clf", classifier)])
        return pipe

    except Exception as inst:
        print("Run-Time Error:", type(inst))
        sys.exit(1)

def run_gridsearch(pipe, param_grid, num_folds, metric,
                   X_train, y_train, output_model):
    """
    This function runs a grid search over a combination of
    hyperparameters using k-fold cross validation to select the best
    estimator

    Parameters:
    - pipe(Pipeline): A ML pipeline capable of transforming data
    - param_grid(dict): The desired hyperparameters and ranges to tune
    - num_folds(int): The number of folds for cross validation
    - metric(str): The evaluation metric  ex. "f1"
    - X_train(ndarray): A numpy array containing 1-test_size fraction of
                        the original dataset
    - y_train(ndarray): A numpy array containing class labels for X_train
    - output_model: The name of the output file containing the best model

    Returns:
    - best_params_(dict): The best performing hyperparameters
    - best_score_(float): The average validation score over k-folds
    - best_estimator_: The actual best performing model

    """

    try:
        search = GridSearchCV(pipe, param_grid, cv=num_folds,
                              scoring=metric, n_jobs=-1,
                              return_train_score=True)
        search.fit(X_train, y_train)
        dump(search.best_estimator_, output_model+".pkl")
        return search.best_params_, search.best_score_, search.best_estimator_, search.cv_results_  # noqa: E501

    except Exception as inst:
        print("Run-Time Error:", type(inst))
        sys.exit(1)

def import_data(csv_file):
    """
    This function imports data from a .csv file as a pandas dataframe

    Parameters:
    - csv_file(str): A .csv file path

    Returns:
    - df(DataFrame): A pandas DataFrame containing features and class labels

    """
    try:
        df = pd.read_csv(csv_file)
        return df

    except FileNotFoundError as inst:
        print("Run-Time Error:", type(inst))
        sys.exit(1)

def make_correlation_heatmap(df, title, outfile):
    """
    This function creates a correlation heatmap for a dataframe
    of features and saves it to a user-defined file.

    Parameters:
    - df(DataFrame): A dataframe of X features and y label
    - title: The title of the correlation heat map
    - outfile(str): The file where the heat map will be saved

    Returns:
    - None, but a .png file is created

    """

    try:
        df_corr = df.corr()
        plt.figure(figsize=(10, 10))
        plt.title(title)
        mask = np.zeros_like(df_corr)
        mask[np.triu_indices_from(mask)] = True
        with sns.axes_style("white"):
            ax = sns.heatmap(df_corr, fmt=".2f", mask=mask, annot=True)
        bottom, top = ax.get_ylim()
        ax.set_ylim(bottom + 0.5, top - 0.5)
        plt.savefig(outfile)

    except Exception as inst:
        print("Run-Time Error:", type(inst))
        sys.exit(1)

def one_hot_encode(df, col_label):
    """
    This function one-hot encodes a single categorical feature in a DataFrame
    and drops the original feature column from the DataFrame

    Parameters:
    - df(DataFrame): A pandas DataFrame containing features and class labels
    - col_label(str): The column label of categorical feature

    Returns:
    - df(DataFrame): A pandas DataFrame after one-hot encoding

    """
    try:
        df_enc = pd.get_dummies(df[col_label])
        df = pd.concat([df_enc, df], axis=1)
        df.drop([col_label], axis=1, inplace=True)

    except KeyError as inst:
        print("Run-Time Error:", type(inst))
        sys.exit(1)

    return df

def split_data(df, test_size, label_col):
    """
    This function splits a pandas DataFrame into X_train, X_test, y_train, and
    y_test sets according to user-defined percentage.

    Parameters:
    - df(DataFrame): A pandas DataFrame containing features and class labels
    - test_size(float): The fraction of original DataFrame held out for testing
                        Ex. 0.2
    - label_col(str): The column of the DataFrame that contains the class label

    Returns:
    - X_train(ndarray): A numpy array containing 1-test_size fraction of
                        the original dataset
    - y_train(ndarray): A numpy array containing the class labels for X_train
    - X_test(ndarray): A numpy array containing test_size fraction of
                       the original dataset
    - y_test(ndarray): A numpy array containing the class labels for X_test

    """
    try:
        train, test = train_test_split(df, test_size=test_size)
        X_train = train.loc[:, train.columns != label_col].values
        y_train = train[label_col].values
        X_test = test.loc[:, train.columns != label_col].values
        y_test = test[label_col].values

        return X_train, y_train, X_test, y_test

    except Exception as inst:
        print("Run-Time Error:", type(inst))
        sys.exit(1)

def make_confusion_matrix(y_true, y_pred, output_file):
    """
    This function creates a confusion matrix in the form of a heat map

    Parameters:
    - y_true(list): The true class labels for X_test
    - y_pred(list): The predicted class labels for X_test
    - output_file(str): The file path for saving the confusion matrix

    Returns:
    - None; a .png file of the confusion matrix is created

    """
    try:
        data = confusion_matrix(y_true, y_pred)
        df_cm = pd.DataFrame(data, columns=np.unique(y_true),
                             index=np.unique(y_true))
        df_cm.index.name = "Actual"
        df_cm.columns.name = "Predicted"
        plt.figure(figsize=(10, 10))
        plt.title("Confusion matrix")
        cm = sns.heatmap(df_cm, annot=True)
        plt.savefig(output_file)

    except Exception as inst:
        print("Run-Time Error:", type(inst))
        sys.exit(1)

def evaluate_test_set(y_test, y_pred, output_file):
    """
    This function creates a confusion matrix of the actual
    vs. predicted class labels and returns the f1_score

    Parameters:
    - y_test(ndarray): A numpy array containing the class labels for X_test
    - y_test(ndarray): A numpy array containing the predicted
                       class labels for X_test
    - output_file(str): The file path for saving the confusion matrix

    Returns:
    - score(float): The f1_score for the model's predictions on the test set

    """
    try:
        make_confusion_matrix(y_test, y_pred, output_file)
        return f1_score(y_test, y_pred)

    except Exception as inst:
        print("Run-Time Error:", type(inst))
        sys.exit(1)


import torch
import torch.nn as nn
import torch.nn.functional as F

class UpSampleBN(nn.Module):
    def __init__(self, skip_input, output_features):
        super(UpSampleBN, self).__init__()

        self._net = nn.Sequential(nn.Conv2d(skip_input, output_features, kernel_size=3, stride=1, padding=1),
                                  nn.BatchNorm2d(output_features),
                                  nn.LeakyReLU(),
                                  nn.Conv2d(output_features, output_features, kernel_size=3, stride=1, padding=1),
                                  nn.BatchNorm2d(output_features),
                                  nn.LeakyReLU())

    def forward(self, x, concat_with):
        up_x = F.interpolate(x, size=[concat_with.size(2), concat_with.size(3)], mode='bilinear', align_corners=True)
        f = torch.cat([up_x, concat_with], dim=1)
        return self._net(f)

class DecoderBN(nn.Module):
    def __init__(self, num_features=2048, num_classes=1, bottleneck_features=2048):
        super(DecoderBN, self).__init__()
        features = int(num_features)

        self.conv2 = nn.Conv2d(bottleneck_features, features, kernel_size=1, stride=1, padding=1)

        self.up1 = UpSampleBN(skip_input=features // 1 + 112 + 64, output_features=features // 2)
        self.up2 = UpSampleBN(skip_input=features // 2 + 40 + 24, output_features=features // 4)
        self.up3 = UpSampleBN(skip_input=features // 4 + 24 + 16, output_features=features // 8)
        self.up4 = UpSampleBN(skip_input=features // 8 + 16 + 8, output_features=features // 16)

        #         self.up5 = UpSample(skip_input=features // 16 + 3, output_features=features//16)
        self.conv3 = nn.Conv2d(features // 16, num_classes, kernel_size=3, stride=1, padding=1)
        # self.act_out = nn.Softmax(dim=1) if output_activation == 'softmax' else nn.Identity()

    def forward(self, features):
        x_block0, x_block1, x_block2, x_block3, x_block4 = features[4], features[5], features[6], features[8], features[
            11]

        x_d0 = self.conv2(x_block4)

        x_d1 = self.up1(x_d0, x_block3)
        x_d2 = self.up2(x_d1, x_block2)
        x_d3 = self.up3(x_d2, x_block1)
        x_d4 = self.up4(x_d3, x_block0)
        x_d5 = self.up5(x_d4, features[0])
        out = self.conv3(x_d5)
        # out = self.act_out(out)
        # if with_features:
        #     return out, features[-1]
        # elif with_intermediate:
        #     return out, [x_block0, x_block1, x_block2, x_block3, x_block4, x_d1, x_d2, x_d3, x_d4]
        return out

class Encoder(nn.Module):
    def __init__(self, backend):
        super(Encoder, self).__init__()
        self.original_model = backend

    def forward(self, x):
        features = [x]
        for k, v in self.original_model._modules.items():
            if (k == 'blocks'):
                for ki, vi in v._modules.items():
                    features.append(vi(features[-1]))
            else:
                features.append(v(features[-1]))
        return features

class UEfficientNetEncoder(nn.Module):
    def __init__(self, backend):
        super(UEfficientNetEncoder, self).__init__()
        self.encoder = Encoder(backend)
        self.decoder = DecoderBN(num_classes=128)

    def forward(self, x, **kwargs):
        unet_out = self.decoder(self.encoder(x), **kwargs)
        return unet_out

    def get_1x_lr_params(self):  # lr/10 learning rate
        return self.encoder.parameters()

    def get_10x_lr_params(self):  # lr learning rate
        modules = [self.decoder]
        for m in modules:
            yield from m.parameters()

    @classmethod
    def build(cls, n_bins, **kwargs):
        basemodel_name = 'tf_efficientnet_b5_ap'

        print('Loading base model ()...'.format(basemodel_name), end='')
        basemodel = torch.hub.load('rwightman/gen-efficientnet-pytorch', basemodel_name, pretrained=True)
        print('Done.')

        # Remove last layer
        print('Removing last two layers (global_pool & classifier).')
        basemodel.global_pool = nn.Identity()
        basemodel.classifier = nn.Identity()

        # Building Encoder-Decoder model
        print('Building Encoder-Decoder model..', end='')
        m = cls(basemodel, **kwargs)
        print('Done.')
        return m

if __name__ == '__main__':
    model = UEfficientNetEncoder.build(100)
    x = torch.rand(2, 3, 480, 640)
    pred = model(x)
    print(pred.shape)


'''
Created on 20 mar. 2019

@author: julio
'''
import socketserver
import threading
import django
from queue import Queue, Empty

django.setup()

from fgserver.models import Airport, Order
from fgserver.messages import PosMsg
from fgserver import llogger, settings, setInterval
from fgserver.server.fgmpie import pie_msg, PacketData
from fgserver.signals import message_received, signal_server_started
from fgserver.server.utils import get_pos_msg, process_msg

class FGServer(socketserver.ThreadingMixIn, socketserver.UDPServer):
    incoming = Queue()
    outgoing = Queue()
    _thread = None

    def init(self):
        self._thread = threading.Thread(target=self.serve_forever)
        self._thread.daemon = True
        server_thread.start()

    def put(self,msg):
        self.outgoing.put(msg)

    def get(self,msg):
        self.incoming.get(msg)

class FGHandler(socketserver.BaseRequestHandler):

    def handle(self):
        data = self.request[0]
        try:
            unp = PacketData(data)
            pos = PosMsg()
            pos.receive_pie(unp)
            pos.header.reply_addr=self.client_address[0]
            pos.header.reply_port=self.client_address[1]
            #print("R",pos)
            #process_msg(pos)
            self.server.incoming.put(pos)
        except:
            llogger.exception("While receiving message")

def startup_tasks():
    Order.objects.all().update(expired=True)

@setInterval(0.5)
def send_msg():
    for airport in Airport.objects.filter(active=True):
        msg = get_pos_msg(airport)
        #llogger.debug("Sending pos for AI ATC   %s" % msg)
        server.outgoing.put(msg)

#     from fgserver.ai.models import FlightPlan
#     for plan in FlightPlan.objects.filter(enabled=True):
#         try:
#             pos = plan.aircraft.status.get_position_message()
#             server.outgoing.put(pos)
#         except AircraftStatus.DoesNotExist:
#             AircraftStatus(aircraft=plan.aircraft, date=timezone.now()).save()
#             pos = plan.aircraft.status.get_position_message()
#             server.outgoing.put(pos)
#         except:
#             llogger.exception("In loop")

#     else:
#         diff =(timezone.now() - (aircraft.updated or timezone.now())).total_seconds()
#             if diff < 2:
#                 #print("saving",aircraft.__dict__)
#                 aircraft.save()

if __name__ == "__main__":
    HOST, PORT = "0.0.0.0", 5100

    server = FGServer((HOST, PORT), FGHandler)
    server_thread = threading.Thread(target=server.serve_forever)
    server_thread.daemon = True

    startup_tasks()

    try:
        server_thread.start()
        #signal_server_started.send_robust(None)
        print("Server started at {} port {}".format(HOST, PORT))
        send_msg()
        while True:
            try:
                pos = server.incoming.get(True, .1)
                #llogger.debug("Received %s" % pos )
                message_received.send_robust(sender=server,msg=pos)
                process_msg(pos)

            except Empty:
                pass
            try:
                msg = server.outgoing.get(False)
                #llogger.debug("Sending message %s" % msg )
                buff = pie_msg(msg)
                server.socket.sendto(buff,settings.FGATC_RELAY_SERVER)
            except Empty:
                pass

    except (KeyboardInterrupt, SystemExit):
        server.shutdown()
        server.server_close()
        exit()


"""
You come across an old JS Basics teamwork game. It is about bunnies that multiply extremely fast.
There's also a player that should escape from their lair.
You like the game, so you decide to port it to Python because that's your language of choice.
The last thing left is the algorithm that determines if the player will escape the lair or not.
First, you will receive a line holding integers N and M, representing the lair's rows and columns.
Next, you receive N strings that can consist only of ".", "B", "P". They represent the initial state of the lair.
There will be only one player. The bunnies are marked with "B", the player is marked with "P", and everything else is
free space, marked with a dot ".".
Then you will receive a string with commands (e.g., LRRULUD) - each letter represents the next move of the player:
•	L - the player should move one position to the left
•	R - the player should move one position to the right
•	U - the player should move one position up
•	D - the player should move one position down
After every step made, each bunny spreads one position up, down, left, and right. If the player moves to a bunny cell or
a bunny reaches the player, the player dies.
If the player goes out of the lair without encountering a bunny, the player wins.
When the player dies or wins, the game ends.
All the activities for this turn continue (e.g., all the bunnies spread normally), but there are no more turns.
There will be no cases where the moves of the player end before he dies or escapes.
In the end, print the final state of the lair with every row on a separate line.
On the last line, print either "dead: {row} {col}" or "won: {row} {col}".
"Row" and "col" are the cell coordinates where the player has died or the last cell he has been in before escaping the
lair.
Input
•	On the first line of input, the numbers N and M are received - the number of rows and columns in the lair
•	On the following N lines, each row is received in the form of a string. The string will contain only ".", "B", "P".
All strings will be the same length. There will be only one "P" for all the input
•	On the last line, the directions are received in the form of a string, containing "R", "L", "U", "D"
Output
•	On the first N lines, print the final state of the bunny lair
•	On the last line, print:
o	If the player won - "won: {row} {col}"
o	If the player dies - "dead: {row} {col}"
Constraints
•	The dimensions of the lair are in the range [3…20]
•	The directions string length is in the range [1…20]
"""

from collections import deque

def player_position(matrix, rows_number, columns_number):
    player_coordinates = ()
    for row in range(rows_number):
        for column in range(columns_number):
            if matrix[row][column] == "P":
                player_coordinates = (row, column)
                break
    return player_coordinates

def bunnies_position(matrix, rows_number, columns_number):
    bunnies_coordinates = []
    for row in range(rows_number):
        for column in range(columns_number):
            if matrix[row][column] == "B":
                bunnies_coordinates.append([row, column])
    return bunnies_coordinates

def not_in_matrix(row, column, rows_number, columns_number):
    return row < 0 or column < 0 or row >= rows_number or column >= columns_number

def get_children(row, column, rows_number, columns_number):
    children = []
    possible_children = [
        [row - 1, column],
        [row, column - 1],
        [row, column + 1],
        [row + 1, column]
    ]
    for child_row, child_column in possible_children:
        if not_in_matrix(child_row, child_column, rows_number, columns_number):
            continue
        else:
            children.append([child_row, child_column])
    return children

def move(direction: str, row, column):
    if direction == "L":
        column -= 1
    elif direction == "R":
        column += 1
    elif direction == "U":
        row -= 1
    elif direction == "D":
        row += 1
    return (row, column)

def spawn_bunnies(bunnies):
    new_bunnies = []
    for bunnie_row, bunnie_column in bunnies:
        children = get_children(bunnie_row, bunnie_column, row_count, column_count)
        for child in children:
            new_bunnies.append(child)
    return new_bunnies

row_count, column_count = [int(i) for i in input().split()]
matrix = [list(input()) for row in range(row_count)]
commands = deque(input())
won = False
dead = False
player_row, player_column = player_position(matrix, row_count, column_count)
bunnies = bunnies_position(matrix, row_count, column_count)

while not won and not dead:
    command = commands.popleft()

    new_player_row, new_player_column = move(command, player_row, player_column)
    matrix[player_row][player_column] = "."
    won = not_in_matrix(new_player_row, new_player_column, row_count, column_count)

    if not won:
        player_row, player_column = new_player_row, new_player_column
        if matrix[player_row][player_column] == "B":
            dead = True
        else:
            matrix[player_row][player_column] = "P"

    bunnies = spawn_bunnies(bunnies)
    for bunnie_row, bunnie_column in bunnies:
        matrix[bunnie_row][bunnie_column] = "B"

    if matrix[player_row][player_column] == "B" and not won:
        dead = True

for row in matrix:
    print(*row, sep="")

if won:
    print(f"won: {player_row} {player_column}")
elif dead:
    print(f"dead: {player_row} {player_column}")


#hc1941
#Problem 1
"""
runtime of example1 is O(n)
runtime of example2 is O(n2)
runtime of example3 is O(n^2)
runtime of example4 is O(n)
runtime of example5 is O(n^3)
"""

#Problem 2
def merge(l1, l2):
    #output=[]
    if len(l1)>=len(l2):
        longer=l1
        shorter=l2
    else:
        longer=l2
        shorter=l1
    for i in range(len(shorter)):
        yield l1[i]
        yield l2[i]
    for j in range(len(shorter), len(longer)):
        yield longer[j]
print([i for i in merge( range(5),range(100,105))])
print([i for i in merge( range(5),range(100,101))])
print([i for i in merge( range(1),range(100,105))])

#Problem 3
class polynomial():
    def __init__(self, constants):
        self.constants=constants
        self.poly=''
        self.sum=0
    def evaluate(self, input):
        self.input=input
        self.sum=0
        for k in range(len(self.constants)):
            self.sum+=self.constants[k]*(self.input**(len(self.constants)-k-1))
        return self.sum
    def __str__(self):
        for j in range(len(self.constants)-1):
            self.poly+=str(self.constants[j])+'x^'+str(len(self.constants)-1-j)+'+'
        self.poly+=str(self.constants[j+1])
        return str(self.poly)

P=polynomial((6,2,1,8))
print(str(P))
print([P.evaluate(i) for i in range(10)])

#Problem 4
def sigma(f, first, last):
    sum=0
    for i in range(first, last+1):
        sum+=f(i)
    return sum
def f(n):
    return 1/pow(2,n)
print(sigma(f,2,10))


'''
Tools for the computation of
Horton-Strahler stream order.
'''

import matplotlib.pyplot as plt
import numpy as np
import copy

def ReadTree(ccoFile):
    print("Reading", ccoFile)

    with open(ccoFile, 'r') as f:
        # Unused '*Tree' information
        row = f.readline()
        row = f.readline()
        row = f.readline()

        # Vessels data
        f.readline().strip()
        nVessels = int(f.readline())

        treeData = []
        for i in range(nVessels):
            row = (f.readline()).split() # Split all columns in a list
            Id, xProx, xDist, r, q, stage = int(row[0]), row[1:4], row[4:7], float(row[12]), float(row[13]), int(row[-1])
            l = sum([(float(a)-float(b))**2 for a,b in zip(xProx, xDist)])**.5
            treeData.append([Id, r*10, l*10, q, stage]) # Convert to mm

        row = f.readline()
        f.readline().strip()

        treeConnectivity = []
        for i in range(nVessels):
            row = (f.readline()).split()
            if (len(row)==2):
                Id, parentId = int(row[0]), int(row[1])
                treeConnectivity.append([Id, parentId, []])
            else:
                Id, parentId, children = int(row[0]), int(row[1]), [int(i) for i in row[2:]]
                treeConnectivity.append([Id, parentId, children])

        print("\tNumber of vessels in the tree:", nVessels, "\n")

    return treeData, treeConnectivity

def BifurcationOrder(treeData, treeConnectivity, orderMax=1e6):

    treeConnectivity.sort()
    treeData.sort()
    orders = np.zeros((len(treeConnectivity),))+1

    def updateTree(vessel, currentOrder=0):
        # Go up the tree and update all orders
        parentId = int(vessel[1])

        orders[vessel[0]] = max(currentOrder, orders[vessel[0]])
        if parentId:
            parent = treeConnectivity[parentId]
            if len(parent[-1])==2:
                updateTree(parent, min(currentOrder+1,orderMax))
            else:
                updateTree(parent, min(currentOrder, orderMax))
        else:
            orders[parentId] = min(currentOrder, orderMax)
            return

    for v in treeConnectivity:
        if len(v[-1])==0:       # if terminal segment
            updateTree(v, currentOrder=0)

    # Add stream order to vessel data
    treeDataNoRoot = []
    count = 0
    for vessel in treeData:
        Id = int(vessel[0])
        order = orders[Id]
        treeData[Id].append(order)

        if treeData[Id][-2]>=-1:
            Id, radius, length, flow, stage, order = treeData[Id]
            treeDataNoRoot.append([count, radius, length, flow, stage, order])
            count+=1

    return treeDataNoRoot

def StrahlerOrder(treeData, treeConnectivity):

    treeConnectivity.sort()
    currentOrder = 0
    vessel = treeConnectivity[0]
    vesselDict = {vessel[0]: [vessel[1], vessel[2], currentOrder]}
    for vessel in treeConnectivity[1:]:
        if len(vessel)>2:
            IdVessel, IdParent, ChildrenList = vessel
        else:
            IdVessel, IdParent = vessel
            ChildrenList = []
        vesselDict[IdVessel] = [IdParent, ChildrenList, currentOrder]
    prunedTree = copy.deepcopy(vesselDict)

    def CurrentLeaves(prunedTree):
        leavesList = []
        for Id, vessel in prunedTree.items():
            if vessel[-1] == 0 and len(vessel[-2])==0:
                leavesList.append(Id)
        return leavesList

    def UpdateAndPrune(prunedTree, leaves):
        # Assign an order to the current leaves
        copyTree = copy.deepcopy(prunedTree)
        increment= False

        for leaf in leaves:
            Children = treeConnectivity[leaf][-1]
            if len(Children)==2 and copyTree[Children[0]][-1]==currentOrder and copyTree[Children[1]][-1]==currentOrder:
                copyTree[leaf][-1] = currentOrder+1
                increment = True

            else:
                childrenOrders = [0]
                for child in Children:
                    childrenOrders.append(copyTree[child][-1])
                '''
                Two different rules, the max rule is the one from Wikipedia and gives fewer orders.
                Both give the right results for the test tree.
                '''
                copyTree[leaf][-1] = currentOrder # max(1,max(childrenOrders))

        # Prune
        for leaf in leaves:
            parentId = copyTree[leaf][0]
            if parentId>=0:
                copyTree[parentId][1].remove(leaf)
        return copyTree, increment

    currentOrder = 1
    computeForTheRoot = iter([True, False]) # Just used to run one more time once the root is reached
    while prunedTree[0][-1]==0 or next(computeForTheRoot):
        leafList = CurrentLeaves(prunedTree)
        prunedTree, increment = UpdateAndPrune(prunedTree, leafList)
        if increment: currentOrder+=1

        if 0 in leafList:
            break

    # Add stream order to vessel data
    treeDataNoRoot = []
    count = 0
    for vessel in treeData:
        Id = int(vessel[0])
        order = prunedTree[Id][-1]
        treeData[Id].append(order)

        if treeData[Id][-2]>=-1:
            Id, radius, length, flow, stage, order = treeData[Id]
            treeDataNoRoot.append([count, radius, length, flow, stage, order])
            count+=1
    return treeDataNoRoot

def TreeStatistics(orderedTree, treeData):
    return #stats

def PlotTreeStatistics(orderedTree, outputImageFile=None):

    maxOrder = np.array(orderedTree)[:,-1].astype(int).max()
    data = np.array(orderedTree)

    dataRadius = np.zeros((maxOrder, len(orderedTree)))
    dataLength = np.zeros((maxOrder, len(orderedTree)))
    dataVolume = np.zeros((maxOrder, len(orderedTree)))
    dataFlow   = np.zeros((maxOrder, len(orderedTree)))
    dataAspectRatio   = np.zeros((maxOrder, len(orderedTree)))
    orderDistribution = np.zeros((maxOrder,))

    for Id, radius, length, flow, stage, order in orderedTree:
        r,l = radius*1e5, length*1e5 # Convert to microns
        i,j = int(order)-1, int(Id)
        dataRadius[i, j] = radius
        dataLength[i, j] = length
        dataFlow[i,j]    = flow
        dataVolume[i, j] = radius*radius*length*np.pi
        dataAspectRatio[i, j] = length/radius
        orderDistribution[i] += 1

    meanRadius = np.mean(dataRadius, axis = 1, where=dataRadius>0)
    stdRadius  = np.std(dataRadius, axis = 1, where=dataRadius>0)
    meanLength = np.mean(dataLength, axis = 1, where=dataRadius>0)
    stdLength  = np.std(dataLength, axis = 1, where=dataRadius>0)
    meanFlow   = np.mean(dataFlow, axis = 1, where=dataRadius>0)
    stdFlow    = np.std(dataFlow, axis = 1, where=dataRadius>0)
    meanVolume = np.mean(dataVolume, axis = 1, where=dataRadius>0)
    stdVolume  = np.std(dataVolume, axis = 1, where=dataRadius>0)
    meanAspectRatio = np.mean(dataAspectRatio, axis = 1, where=dataRadius>0)
    stdAspectRatio  = np.std(dataAspectRatio, axis = 1, where=dataRadius>0)

    x = np.flip(np.arange(maxOrder) + 1)

    fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, sharex='col')
    fig.set_figheight(7.2)
    fig.set_figwidth(8.8)
    scale='linear'
    ax1.errorbar(x, 2*meanRadius, stdRadius*2, marker='s', fillstyle='full')
    ax1.set_yscale('log')
    ax1.set_title('Diameter vs. Strahler order')
    ax2.errorbar(x, meanLength, stdLength, marker='s')
    ax2.set_yscale(scale)
    ax2.set_title('Length vs. Strahler order')
    ax3.errorbar(x, meanFlow, stdFlow, marker='s')
    ax3.set_yscale(scale)
    ax3.set_title('Flow vs. Strahler order')
    ax4.errorbar(x, meanAspectRatio, stdAspectRatio, marker='s')
    ax4.set_yscale(scale)
    ax4.set_title('Aspect ratio vs. Strahler order')

    fig2, axes = plt.subplots(2,2, sharex='col')
    fig2.set_figheight(7.2)
    fig2.set_figwidth(8.8)
    scale = 'log'
    axes[0,0].boxplot(dataRadius.transpose())
    axes[0,0].set_yscale(scale)
    axes[0,0].set_title('Radius vs. Strahler order')
    axes[0,1].boxplot(dataLength.transpose())
    axes[0,1].set_yscale(scale)
    axes[0,1].set_title('Length vs. Strahler order')
    axes[1,0].boxplot(dataFlow.transpose())
    axes[1,0].set_yscale(scale)
    axes[1,0].set_title('Flow vs. Strahler order')
    axes[1,1].boxplot(dataAspectRatio.transpose())
    axes[1,1].set_yscale(scale)
    axes[1,1].set_title('Aspect ratio vs. Strahler order')

    if outputImageFile:
        print('\nWriting outputs (image+data) in', outputImageFile[:-4] + '.png/.dat')
        data = np.vstack((x, meanRadius, stdRadius, meanLength, stdLength, meanVolume, stdVolume, meanAspectRatio, stdAspectRatio, orderDistribution))
        np.savetxt(outputImageFile[:-4] + '.dat', data)
        plt.savefig(outputImageFile)
    plt.show()

    return

def BifurcationDiameterRatio(treeData, treeConnectivity, plot=False):
    '''
    Return the ratio of the smaller daughter vessel to the larger (dsdl)
    against the ratio of the larger daughter to the parent vessel (dldp)
    '''

    copyData = copy.deepcopy(treeData)
    copyData.sort()
    data = []
    for Id, parentId, children in treeConnectivity:
        if parentId>0 and len(children)==2: # parentId=-1 if its root

            dp = copyData[Id][1]
            dchildren = [copyData[children[0]][1], copyData[children[1]][1]]
            ds = min(dchildren)
            dl = max(dchildren)

            # dsdl.append(ds/dl)
            # dldp.append(dl/dp)
            data.append([ds/dl, dl/dp, parentId])

    data.sort()
    data = np.array(data)
    dsdl, dldp, Ind = data[:,0], data[:,1], data[:,2]

    if plot:
        aggregatedData = []
        # x = np.linspace(data[:,0].min(),1, 10)
        x = [0, 0.2, 0.4, 0.6, 0.8, 1.0]
        for i,xi in enumerate(x[1:]):
            xim = x[i]
            mask = (dsdl>xim) & (dsdl<xi)
            aggregatedData.append(dldp[mask])

        plt.boxplot(aggregatedData, positions=x[1:])
        # plt.scatter(dsdl, dldp, label='This work')

        m = 2.85
        x = np.linspace(0.2,1,500)
        y = np.linspace(0.2,1,500)
        X,Y = np.meshgrid(x,y)

        f,g = Y**(-m), 1+X**m
        z = f-g
        cs1 = plt.contour(X,Y, z, [0], linestyles='--', linewidths=1.)
        m = 3
        f,g = Y**(-m), 1+X**m
        cs2 = plt.contour(X,Y,(f-g), [0], linestyles='-.', linewidths=1.)

        cs1.collections[0].set_label('m=2.85')
        cs2.collections[0].set_label('m=3')

        plt.xlim(0,1.2)
        # plt.ylim(0,1.2)
        # plt.yscale('log')

        plt.legend()
        plt.show()

    return [a for a in dsdl], [a for a in dldp]

def VBC(treeData, treeConnectivity, plot=False):

    # Copy the radii, sorted by vessel ID
    radii = np.zeros((len(treeData),))
    for v in treeData:
        radii[v[0]] = v[1]

    VBC = []
    for v in treeConnectivity:
        if len(v[-1])==2:
            p, d1, d2 = radii[v[0]], radii[v[-1][0]], radii[v[-1][1]]
            VBC.append( (d1**2 + d2**2)/(p**2) )

    VBC = np.array(VBC)

    if plot:
        split = 10
        x = np.linspace(VBC.min(), VBC.max(), split+1)
        y = np.zeros((split+1,))
        sortedVBC = np.sort(VBC)

        j = 0
        for i in range(split):
            count = 0
            xi = x[i]
            while xi >= sortedVBC[j]:
                count+=1
                j+=1
            y[i] = count
        y[-1] = VBC.size-j

        plt.bar(x[:-1],y[:-1], width=(x[1]-x[0])/2.0)
        plt.xticks(x[:-1], rotation=20)
        plt.xlabel('Vessel branching coefficient')
        plt.ylabel('Number of vessels')
        plt.show()

    return VBC


# Unit tests
#%%
import unittest
from name_function import get_formatted_name

class NameTestCase(unittest.TestCase):
    """Tests names.py"""
    def test_first_last_name(self):
        """Do names work?"""
        formatted_name = get_formatted_name('Daisy','Went')
        self.assertEqual(formatted_name, 'Daisy Went')

    def test_first_middle_last_name(self):
        """Do full names work?"""
        formatted_name = get_formatted_name('Daisy', 'Went', 'Jones')
        self.assertEqual(formatted_name, 'Daisy Jones Went')

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

## IF A TEST PASSES
## When a Unit test is run and it passes, we get the following output:
#  .
#  ----------------------------------------------------------------------
#  Ran 1 test in 0.000s
#
#  OK
## The " . " means that the test that we have made hase passed

## IF A TEST FAILS
## When a unit test fails, we get the following output
# E
# ======================================================================
# ERROR: test_first_last_name (__main__.NameTestCase)
# Do names work?
# ----------------------------------------------------------------------
# Traceback (most recent call last):
#   File "test_name_functions.py", line 10, in test_first_last_name
#     formatted_name = get_formatted_name('Daisy','Went')
# TypeError: get_formatted_name() missing 1 required positional argument: 'last'

# ----------------------------------------------------------------------
# Ran 1 test in 0.000s

# FAILED (errors=1)


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

import gspread
from oauth2client.service_account import ServiceAccountCredentials
import pandas as pd
import requests
import time

class FreelancerBot():
    token = ''
    url = 'https://www.freelancer.com/api/projects/0.1/projects/active/'
    headers = ''

    def __init__(self, token):
        self.token = token
        self.headers = {'freelancer-oauth-v1': self.token}

    def get_projects(self, query, count=10):
        epoch_time = int(time.time()) - 86400
        url = self.url + '?query={}'.format(query)
        projects = requests.get(url, headers=self.headers).json()['result']['projects']

        return projects

class TelegramBot():
    token = ''
    url = 'https://api.telegram.org/bot'
    update_id = None
    keywords = []

    def __init__(self, token):
        self.token = token
        self.url = self.url + token

    def get_updates(self, timeout=None):
        url = self.url + '/getUpdates?offset={}&timeout={}'.format(self.update_id, timeout)
        print(requests.get(url).json())

        return requests.get(url).json()

    def parse(self, updates, fl_bot):
        for update in updates['result']:
            self.update_id = update['update_id'] + 1
            in_message = update['edited_message']['text'] if 'edited_message' in update.keys() else update['message']['text']
            if '/' == in_message[0]:
                continue

            self.keywords.append(in_message)
        print(self.keywords)

        for keyword in self.keywords:
            projects = fl_bot.get_projects(keyword)
            for project in projects:
                yield {
                    'Project Id': project['id'],
                    'Title': project['title'],
                    'Description': project['preview_description'] if project['preview_description'] else '',
                    'Minimum Budget': str(project['budget']['minimum']) + ' ' + project['currency']['code'] ,
                    'Maximum Budget': str(project['budget']['maximum']) + ' ' + project['currency']['code'],
                    'Average Bid': str(project['bid_stats']['bid_avg']) + ' ' + project['currency']['code'],
                    'Bid Count': project['bid_stats']['bid_count'],
                    'Featured': 'Yes' if project['featured'] else 'No',
                    'Owner Id': project['owner_id'],
                    'Project Url': 'https://www.freelancer.com/projects/' + str(project['id'])
                }

def to_sheets():
    scope = ['https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive']
    creds = ServiceAccountCredentials.from_json_keyfile_name('Creds.json', scope)
    client = gspread.authorize(creds)
    client.import_csv(client.open('Freelancer').id, open('freelancer.csv', 'r', encoding='latin1').read())

    return

def main():
    fl_token = ''
    fl_bot = FreelancerBot(fl_token)

    tg_token = ''
    tg_bot = TelegramBot(tg_token)

    output = pd.DataFrame(columns=[
        'Project Id',
        'Title',
        'Description',
        'Minimum Budget',
        'Maximum Budget',
        'Average Bid',
        'Bid Count',
        'Featured',
        'Owner Id',
        'Project Url'
    ])

    while True:
        for i in ['true']:
            updates = tg_bot.get_updates(60)
            projects = tg_bot.parse(updates, fl_bot)
            for project in projects:
                x = len(output)
                output.loc[x] = project
                print(output.loc[x])
                output = output.drop_duplicates()
            output.to_csv('freelancer.csv', index=None)
            to_sheets()

if __name__ == '__main__':
    main()


# -*- coding: utf-8 -*-
"""
Created on Sat Jan  6 13:06:12 2018

@author: zhang
"""

import numpy as np
import pandas as pd

train = 5642
test = 1000
#http://data.weather.gov.hk/gts/time/calendar/text/T2017c.txt
#带月是初一
nongli = pd.read_excel('C:\\Users\\zhang\\Desktop\\date.xlsx')
nongli = nongli[0]
date = np.genfromtxt('C:\\Users\\zhang\\Desktop\\date.csv',delimiter=',')
dic = np.genfromtxt('C:\\Users\\zhang\\Desktop\\datedic.csv',delimiter=',')

l = []
for i in range(12):
    i+=1
    ltemp = []
    for j in range(len(dic)):
        if dic[j,1] == i:
            ltemp.append(j)
    l.append(ltemp)

e = np.zeros(len(date))
for i in range(len(date)):
    ll = l[int(date[i,1])-1]
    e[i] = ll[int(date[i,0])-1]

datee = []
for i in range(len(date)):
    datee.append(nongli[int(e[i])])
#双数日是-1 单数日是1
e = np.zeros(len(date))
count = 0
for i in datee:
    if i[1] == '二':
        e[count] = -1
    elif i[1] == '四':
        e[count] = -1
    elif i[1] == '六':
        e[count] = -1
    elif i[1] == '八':
        e[count] = -1
    elif i[1] == '十':
        e[count] = -1
    else:
        e[count] = 1
    count+=1

tr = e[0:train]
te = e[train:]

np.savetxt('C:\\Users\\zhang\\Desktop\\file.csv',tr,delimiter=',')
np.savetxt('C:\\Users\\zhang\\Desktop\\file.csv',te,delimiter=',')


# Write a Python function to find the Max of three numbers.
# The function receives 3 floats as parameters and returns a float.

def max_num(num1: float, num2: float, num3: float) -> float:
    if num1 > num2 and num1 > num3:
        maxi = num1
    elif num2 > num1 and num2 > num3:
        maxi = num2
    else:
        maxi = num3
    return maxi

print(max_num(5.1, 4.9, 0.8))


#!/usr/bin/python
# -*- coding: utf-8 -*-
#用于访问OKCOIN 期货REST API
from httpsha256Util import buildMySign,httpGet,httpPost

class IXquot:

    def __init__(self,url,apikey,secretkey):
        self.__url = url
        self.__apikey = apikey
        self.__secretkey = secretkey

    #期货全仓持仓信息
    def account(self,symbol,contractType):
        FUTURE_POSITION = "/api/v1/future_position.do?"
        params = {
            'api_key':self.__apikey,
            'symbol':symbol,
            'contract_type':contractType
        }
        params['sign'] = buildMySign(params,self.__secretkey)
        return httpPost(self.__url,FUTURE_POSITION,params)


import numpy as np
from mnist import MNIST
from rlscore.learner import GreedyRLS
from rlscore.measure import ova_accuracy

def ova(Y):
    #maps range 0,...,classcount -1 to one-vs-all encoding
    Y_ova = -1. * np.ones((len(Y), np.max(Y)+1))
    for i in range(len(Y)):
        Y_ova[i, Y[i]] = 1
    return Y_ova

class Callback(object):

    def __init__(self, X_test, Y_test):
        self.X_test = X_test
        self.Y_test = Y_test
        self.iteration = 0

    def callback(self, learner):
        self.iteration += 1
        P = learner.predict(self.X_test)
        acc = ova_accuracy(self.Y_test, P)
        print("Features selected %d, accuracy %f" %(self.iteration, acc))

    def finished(self, learner):
        pass

def train_rls():
    mndata = MNIST("./data")
    X_train, Y_train = mndata.load_training()
    X_test, Y_test = mndata.load_testing()
    X_train, X_test = np.array(X_train), np.array(X_test)
    #One-vs-all mapping
    Y_train = ova(Y_train)
    Y_test = ova(Y_test)
    #Train greedy RLS, select 50 features
    cb = Callback(X_test, Y_test)
    learner = GreedyRLS(X_train, Y_train, 50, callbackfun=cb)
    print("Selected features " +str(learner.selected))

if __name__=="__main__":
    train_rls()


#!/usr/bin/env python3
# encoding: utf-8

"""Choices are enumeration values you can choose, by selecting index number.
It is a special TabStop, its content are taken literally, thus said, they will not be parsed recursively.
"""

from UltiSnips import vim_helper
from UltiSnips.position import Position
from UltiSnips.text_objects.tabstop import TabStop
from UltiSnips.snippet.parsing.lexer import ChoicesToken

class Choices(TabStop):
    """See module docstring."""

    def __init__(self, parent, token: ChoicesToken):
        self._number = token.number  # for TabStop property 'number'
        self._initial_text = token.initial_text

        # empty choice will be discarded
        self._choice_list = [s for s in token.choice_list if len(s) > 0]
        self._done = False
        self._input_chars = list(self._initial_text)
        self._has_been_updated = False

        TabStop.__init__(self, parent, token)

    def _get_choices_placeholder(self) -> str:
        # prefix choices with index number
        # e.g. 'a,b,c' -> '1.a|2.b|3.c'
        text_segs = []
        index = 1
        for choice in self._choice_list:
            text_segs.append("%s.%s" % (index, choice))
            index += 1
        text = "|".join(text_segs)
        return text

    def _update(self, done, buf):
        if self._done:
            return True

        # expand initial text with select prefix number, only once
        if not self._has_been_updated:
            # '${1:||}' is not valid choice, should be downgraded to plain tabstop
            are_choices_valid = len(self._choice_list) > 0
            if are_choices_valid:
                text = self._get_choices_placeholder()
                self.overwrite(buf, text)
            else:
                self._done = True
            self._has_been_updated = True
        return True

    def _do_edit(self, cmd, ctab=None):
        if self._done:
            # do as what parent class do
            TabStop._do_edit(self, cmd, ctab)
            return

        ctype, line, col, cmd_text = cmd

        cursor = vim_helper.get_cursor_pos()
        [buf_num, cursor_line] = map(int, cursor[0:2])

        # trying to get what user inputted in current buffer
        if ctype == "I":
            self._input_chars.append(cmd_text)
        elif ctype == "D":
            line_text = vim_helper.buf[cursor_line - 1]
            self._input_chars = list(line_text[self._start.col : col])

        inputted_text = "".join(self._input_chars)

        if not self._input_chars:
            return

        # if there are more than 9 selection candidates,
        # may need to wait for 2 inputs to determine selection number
        is_all_digits = True
        has_selection_terminator = False

        # input string sub string of pure digits
        inputted_text_for_num = inputted_text
        for [i, s] in enumerate(self._input_chars):
            if s == " ":  # treat space as a terminator for selection
                has_selection_terminator = True
                inputted_text_for_num = inputted_text[0:i]
            elif not s.isdigit():
                is_all_digits = False

        should_continue_input = False
        if is_all_digits or has_selection_terminator:
            index_strs = [
                str(index) for index in list(range(1, len(self._choice_list) + 1))
            ]
            matched_index_strs = list(
                filter(lambda s: s.startswith(inputted_text_for_num), index_strs)
            )
            remained_choice_list = []
            if len(matched_index_strs) == 0:
                remained_choice_list = []
            elif has_selection_terminator:
                if inputted_text_for_num:
                    num = int(inputted_text_for_num)
                    remained_choice_list = list(self._choice_list)[num - 1 : num]
            elif len(matched_index_strs) == 1:
                num = int(inputted_text_for_num)
                remained_choice_list = list(self._choice_list)[num - 1 : num]
            else:
                should_continue_input = True
        else:
            remained_choice_list = []

        if should_continue_input:
            # will wait for further input
            return

        buf = vim_helper.buf
        if len(remained_choice_list) == 0:
            # no matched choice, should quit selection and go on with inputted text
            overwrite_text = inputted_text_for_num
            self._done = True
        elif len(remained_choice_list) == 1:
            # only one match
            matched_choice = remained_choice_list[0]
            overwrite_text = matched_choice
            self._done = True

        if overwrite_text is not None:
            old_end_col = self._end.col

            # change _end.col, thus `overwrite` won't alter texts after this tabstop
            displayed_text_end_col = self._start.col + len(inputted_text)
            self._end.col = displayed_text_end_col
            self.overwrite(buf, overwrite_text)

            # notify all tabstops those in the same line and after this to adjust their positions
            pivot = Position(line, old_end_col)
            diff_col = displayed_text_end_col - old_end_col
            self._parent._child_has_moved(
                self._parent.children.index(self), pivot, Position(0, diff_col)
            )

            vim_helper.set_cursor_from_pos([buf_num, cursor_line, self._end.col + 1])

    def __repr__(self):
        return "Choices(%s,%r->%r,%r)" % (
            self._number,
            self._start,
            self._end,
            self._initial_text,
        )