#!../../../env/bin/python
'''
Related to Ticket #2189
https://trac.tools.ietf.org/tools/ietfdb/ticket/2189

Locate messages that should have been matched to an existing thread from the
subject line but weren't

'''
# Standalone broilerplate -------------------------------------------------------------
from django_setup import do_setup
do_setup()
# -------------------------------------------------------------------------------------

import argparse
import datetime
import re

from mlarchive.archive.models import Message, Thread
from mlarchive.archive.mail import subject_is_reply

MSGID_PATTERN = re.compile(r'<([^>]+)>')
date = datetime.datetime(2016,11,1)
query = Message.objects.filter(date__gte=date,email_list__name='sipcore')
#threads = Thread.objects.filter(date__gte=date,first__email_list__name='sipcore')
threads = Thread.objects.filter(date__gte=date).order_by('date')

def get_thread(msg):
    # try References
    if msg.references:
        msgids = re.findall(MSGID_PATTERN,msg.references)
        for msgid in msgids:
            try:
                message = Message.objects.get(email_list=msg.email_list,msgid=msgid)
                return message.thread
            except (Message.DoesNotExist, Message.MultipleObjectsReturned):
                pass

    # try In-Reply-to.  Use first msgid found, typically only one
    if msg.in_reply_to_value:
        msgids = re.findall(MSGID_PATTERN,msg.in_reply_to_value)
        if msgids:
            try:
                message = Message.objects.get(email_list=msg.email_list,msgid=msgids[0])
                return message.thread
            except (Message.DoesNotExist, Message.MultipleObjectsReturned):
                pass

    # check subject
    if msg.subject != msg.base_subject:
        messages = Message.objects.filter(email_list=msg.email_list,
                                          date__lt=msg.date,
                                          subject=msg.base_subject).order_by('-date')
        if messages:
            return messages[0].thread

def get_ascii(value):
    '''Returns ascii of value'''
    return value.encode('ascii',errors='replace')

def main():
    parser = argparse.ArgumentParser(description="Scan for broken threads")
    parser.add_argument('-v', '--verbose', action='store_true', help='verbose mode')
    args = parser.parse_args()
    total = 0
    monthly_total = 0
    previous_date = date
    for thread in threads:
        if thread.date.month != previous_date.month:
            print('{}:{}'.format(previous_date.strftime("%Y-%m"),monthly_total))
            previous_date = thread.date
            monthly_total = 0
        msg = thread.first
        if subject_is_reply(msg.subject):
            messages = Message.objects.filter(email_list=msg.email_list,
                                              date__lt=msg.date,
                                              base_subject=msg.base_subject).order_by('-date')
            if messages:
                total = total + 1
                monthly_total = monthly_total + 1
                if args.verbose:
                    print("Found {},{},{} should be {}".format(
                        msg.pk,
                        get_ascii(msg.subject),
                        msg.date,
                        messages.first().thread.pk))

    print('Total: {}'.format(total))

if __name__ == "__main__":
    main()


import cv2
import numpy as np

imagen=cv2.imread('Captura.png')
hsv= cv2.cvtColor(imagen, cv2.COLOR_BGR2HSV)

"""
Rango de colores detectados
verdes
"""

verdes_bajos= np.array([49,50,50])
verdes_altos= np.array([107,255,255])

#Ahora los azules
azul_bajos = np.array([100,65,75], dtype=np.uint8)
azul_altos = np.array([130,255,255], dtype=np.uint8)

#Rojos
rojos_bajos1 = np.array([0,65,75], dtype=np.uint8)
rojos_altos1 = np.array([12,255,255], dtype=np.uint8)
rojos_bajos2 = np.array([240,65,75], dtype=np.uint8)
rojos_altos2 = np.array([256,255,255], dtype=np.uint8)
#Crear las mascaras
mascara_verde = cv2.inRange(hsv, verdes_bajos, verdes_altos)
mascara_rojo1 = cv2.inRange(hsv, rojos_bajos1, rojos_altos1)
mascara_rojo2 = cv2.inRange(hsv, rojos_bajos2, rojos_altos2)
mascara_azul = cv2.inRange(hsv, azul_bajos, azul_altos)

#Juntar las  mascaras para crear la matrix
mask = cv2.add(mascara_rojo1, mascara_rojo2)
mask = cv2.add(mask, mascara_verde)
mask = cv2.add(mask, mascara_azul)

#Mostrar la imagen inicial y pulsar esc
cv2.imshow('finale', mask)
cv2.imshow('imagen', imagen)
#Para abortar mission
while (1):
	tecla = cv2.waitKey(5) &  0xFF
	if tecla == 27:
		break
cv2.destroyAllWindows()


from datetime import datetime
from sklearn.feature_extraction.text import CountVectorizer

from tweepy.streaming import StreamListener
from tweepy import OAuthHandler
from tweepy import Stream
import pymongo
import pandas as pd

import config
from time import sleep
import json

# CRIANDO A AUTENTICAÇÃO
auth = OAuthHandler(config.API_Key, config.API_Secret_Key)
auth.set_access_token(config.Access_Token, config.Access_Token_Secret)

# CLASS PARA CAPTURAR OS DADOS
class MyListener(StreamListener):
    def on_data(self, raw_data):
        tweet = json.loads(raw_data)
        created_at = tweet['created_at']
        id_str = tweet['id_str']
        text = tweet['text']
        obj = {'created_at': created_at,
               'id_str': id_str,
               'text': text}
        tweetind = col.insert_one(obj).inserted_id
        print(obj)
        return True

mylistener = MyListener()

mystream = Stream(auth, listener=mylistener)

client = pymongo.MongoClient()

db = client.twitterdb
col = db.tweets

# VARIAL COM AS PALAVRAS CHAVES DE BUSCA NO TWITTER
keywords = ['Big Data', 'Python', 'Data Mining', 'Data Science']

# COLETANDO OS DADOS
# mystream.filter(track=keywords, encoding='UTF-8')
# sleep(30)
# mystream.disconnect()

# CRIANDO DATASET COM O RETORNO DO MONGO
dataset = [{'created_at': item['created_at'], 'text': item['text'], } for item in col.find()]
df = pd.DataFrame(dataset)

#print(df)

cv = CountVectorizer()
count_matrix = cv.fit_transform(df.text)

# CONTANDO O NÚMERO DE OCORRÊNCIAS DAS PRICIPAIS PALAVRAS DO DATASET
word_count = pd.DataFrame(cv.get_feature_names(), columns=['Word'])
word_count['count'] = count_matrix.sum(axis=0).tolist()[0]
word_count = word_count.sort_values('count', ascending=False).reset_index(drop=True)
print(word_count[:50])


# -*- coding: utf-8 -*-
"""
Created on Tue Apr  6 20:39:00 2021
@author: sara-
Description: simple csv to json converter
"""
import csv
import json
import pandas as pd

df_text = pd.read_csv('Data/text_apple.csv')
df_text.to_json (r'Data/text_apple.json')

csvFilePath = r'Data/text_apple.csv'
jsonFilePath = r'Data/text_apple.json'

data = {}
ids = 0

#Csv reader
with open(csvFilePath, encoding='utf-8') as csvf:
    csvReader = csv.DictReader(csvf)

    for rows in csvReader:
        key = ids
        data[key] = rows
        ids +=1

# Json writer
with open(jsonFilePath, 'w', encoding='utf-8') as jsonf:
    jsonf.write(json.dumps(data, indent=4))

print("Json saved sucesfully")


# -*- coding: UTF-8 -*-
import json
import cv2
import matplotlib.pyplot as plt # plt 用于显示图片
import matplotlib.image as mpimg # mpimg 用于读取图片
import numpy as np
import os
from scipy import optimize

# test_path 是处理后结果
gt_path="24gt" # 标准结果
testpath="24area" #处理结果
imgpath= "edistance"  #图片存储路径

# gt_path="valid" # 标准结果 shuru
# testpath="tmp_1" #处理结果
# imgpath="tmp1_img"  #图片存储路径

def data_reader(gtjson,prejson,x_data,r_data):
	imgfilename=os.path.join(imgpath,gtjson.split(".")[0]+"_c.jpg")
	gtjson=os.path.join(gt_path,gtjson)
	prejson=os.path.join(testpath,prejson)
	with open(gtjson,"r+") as f:
		gtjson = json.load(f)
		gtframe = gtjson["frame_data"]
		gtnum = len(gtframe)

	with open(prejson,"r+") as f:
		testjson = json.load(f)
		testframe = testjson["frame_data"]
		testnum = len(testframe)

	if testnum != gtnum:
		return
	data = np.zeros((4,testnum),dtype=float)
	for i in range(testnum):
		data[0][i]=gtframe[i]['vx']
		data[1][i]=gtframe[i]['x']
		data[2][i]=testframe[i]['vx']
		data[3][i]=testframe[i]['x']
	process_data=np.zeros((2,testnum),dtype=float)
	process_data[0]=data[1] # diff v
	process_data[1]=(data[1]-data[3]) # diff x

	print("mean_err[v,x]:", np.mean(np.abs(process_data), axis=1))
	plt.figure()
	plt.subplot(211)
	plt.title('pos_err(abs)')
	# plt.legend(process_data[1])
	plt.plot(process_data[1],'g-',label='diffx',markersize=20)
	plt.subplot(212)
	plt.title('pos_value')
	# plt.legend(process_data[0])
	plt.plot(data[3],'y-',label='pos_value',markersize=20)
	plt.savefig(imgfilename)
	# np.append(rdata,process_data[0])
	x_data+=list(process_data[0])
	r_data+=list(process_data[1])
	# print("diffx:")
	# print(np.argmax((process_data[1])))
	# print(process_data[1])

	# print("diffv:")
	# print(np.argmax((process_data[0])))
	# print(process_data[0])

if __name__ == '__main__':
	files_gt= os.listdir(gt_path)
	#print(files_gt)

	isExists=os.path.exists(imgpath)
	if not isExists:
		os.makedirs(imgpath)
	# all_data=np.zeros((1,0),dtype=float)
	x_data=[]

	err_data=[]
	for i in files_gt:
		if i.find(".avi")<0:
			continue
		if i.find("效果")>-1:
			continue
		prejson=i.split(".")[0]+"_pre.json"
		injson=i.split(".")[0]+"_gt.json"
		print(prejson)
		# np.append(all_data,data_reader(i,prejson))
		data_reader(injson,prejson,x_data,err_data)
	print(len(x_data))
	#fit curve
	# k,b=optimize.curve.fit()
	all_flag=True
	if all_flag:
		alldata=[err_data,x_data]
		alldata=np.array(alldata)
		print("shape:",alldata.shape)
		alldata=alldata.T[alldata.T[:,1].argsort()].T
		# print(alldata[1][:10])
		pre=5000
		tail=len(alldata[0])
		xdata=alldata[1][pre:tail]
		edata=alldata[0][pre:tail]
		for j in range(len(xdata)):
			if xdata[j]>10:
				print("pos10:",j)
				break
		for j in range(len(xdata)):
			if xdata[j]>18:
				print("pos18:",j)
				break

		print("min:",min(xdata))
		fitline=np.polyfit(xdata,edata,1)
		print("fitline_all:",fitline)
		x=np.arange(min(xdata),max(xdata)+20,0.01)
		y=np.polyval(fitline,x)

		# other
		lineparam=[0.14728058, -2.30329372]
		y1=np.polyval(lineparam,x)

		plt.figure()
		plt.title('distance_error')
		plt.plot(xdata,edata,'go',label='diffx',markersize=5)
		plt.plot(x,y,'r-',label='fitline')
		plt.plot(x,y1,'y-',label='fitline1')
		imgfilename=os.path.join(imgpath,"final.jpg")
		plt.savefig(imgfilename)
		plt.show()
	else:
		N=1500
		alldata=[x_data,err_data]
		# alldata.sort(key=lamda x:x[1])
		zipdata=zip(x_data,err_data)
		sorted(zipdata)
		[xdata,edata]=zip(*zipdata)
		print(xdata[:10])
		fitline=np.polyfit(xdata,edata,1)
		print("fitline_short:",fitline)
		x1=np.arange(min(xdata),max(xdata),0.01)
		y1=np.polyval(fitline,x1)
		fitline=np.polyfit(xdata,edata,1)
		print("fitline_long:",fitline)
		x2=np.arange(min(alldata[1][N:]),max(alldata[1][N:]),0.01)
		y2=np.polyval(fitline,x2)
		plt.figure()
		plt.title('distance_error')
		plt.plot(x_data,err_data,'go',label='diffx',markersize=5)
		plt.plot(x1,y1,'r-',label='fitline')
		plt.plot(x2,y2,'b-',label='fitline')
		imgfilename=os.path.join(imgpath,"final.jpg")
		plt.savefig(imgfilename)
		# plt.show()


import ctypes, sys, time, random
import shutil
import itertools

def get_terminal_dimensions():
    dimensions = shutil.get_terminal_size()
    width = dimensions.columns
    height = dimensions.lines
    return (width, height)

def print_at(line, column, text):
    sys.stdout.write("\x1b7\x1b[%d;%df%s\x1b8" % (line, column, text))
    sys.stdout.flush()

def clear_terminal(width, height, first=False):
    if first:
        print(chr(27) + "[2J")
    for i in range(height):
        print_at(i+1, 1, ''.ljust(width))

class Renderer:

    # orientation = 'horizontal'
    term_width = None
    term_height = None
    line_length = None
    line_amount = None
    middle_line = None
    guy_side_amount = 0
    counter_current_left = 0
    counter_current_right = 0
    pixels_to_lose = 0
    moved_left = 0
    moved_right = 0
    rope_length = 0

    def clear_terminal_at_for(self, at_x, at_y, width, lines):
        for i in range(lines):
            print_at(at_y+i, at_x, ''.ljust(width))

    def clear_terminal_right(self, width, height, first=False):
        if first:
            print(chr(27) + "[2J")
        for i in range(height):
            print_at(i+1, self.middle_line + 1, ''.ljust(width))

    def init(self):
        # essentially the same as colorama, but without shortcuts
        # enables ansi escape sequences (some of them anyway)
        if sys.platform is 'win32':
            kernel32 = ctypes.windll.kernel32
            kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)

        # get terminal dimensions
        self.term_width, self.term_height = get_terminal_dimensions()
        self.middle_line = round(self.term_width / 2)
        clear_terminal(self.term_width, self.term_height, first=True)
        if self.term_width < 36 or self.term_height < 17:
            print('The terminal window is too small. Shutting down.')
            print('The terminal should be at least 36x17.')
            print('Current dimensions are: ', self.term_width, 'columns by', self.term_height, 'lines.')
            sys.exit(1)

        # draw some basic terminal parts
        self.outline()
        self.draw_rope()

        self.guy_side_amount = self.calculate_guys_number()
        self.draw_guys_left()
        self.draw_guys_right()

        # 39 long max (80x24)
        # 15 lines max (80x24)
        self.line_length = self.middle_line - 2
        self.line_amount = self.term_height - 11
        if self.line_amount > self.line_length:
            self.line_amount = self.line_length

        return self.line_amount, self.line_length

    def calculate_guys_number(self):
        amount = 0
        length_left = self.middle_line
        while length_left > round((self.middle_line - 1) / 1.5) and length_left > 17:
            length_left -= 8
            amount += 1
        self.pixels_to_lose = length_left - round(self.middle_line / 3)
        # self.moved_left = self.pixels_to_lose
        # self.moved_right = self.pixels_to_lose
        # print_at(self.term_height-1, 0, self.pixels_to_lose)
        return amount

    def outline(self):
        middle_line = round(self.term_width / 2)
        for i in range(self.term_height-8):
            print_at(i, middle_line, '|')
        for i in range(self.term_width+1):
            print_at(self.term_height-9, i, '-')
        print_at(self.term_height-9, middle_line, '^')
        print_at(self.term_height-1, middle_line, '^')

    def name_left(self, name):
        print_at(self.term_height-10, 1, name.center(self.middle_line - 1))

    def name_right(self, name):
        print_at(self.term_height-10, self.middle_line + 1, name.center(self.middle_line - 1))

    def clean_counters(self):
        print_at(self.term_height-8, 1, '    ')
        print_at(self.term_height-8, self.term_width-3, '    ')

    def sort_both(self, array1, pointers1, array2, pointers2):
        self.clean_counters()
        counter = 0
        for entry1, focus1, entry2, focus2 in itertools.zip_longest(array1, pointers1, array2, pointers2, fillvalue=[]):

            if len(entry1) > 0:
                clear_terminal(self.line_length, self.line_amount)
                # counter for left one
                print_at(self.term_height-8, 1, str(counter).rjust(4))
                self.counter_current_left = counter
            if len(entry2) > 0:
                self.clear_terminal_right(self.line_length, self.line_amount)
                # counter for right one
                print_at(self.term_height-8, self.term_width-3, str(counter).ljust(4))
                self.counter_current_right = counter

            for index, packed in enumerate(itertools.zip_longest(entry1, entry2)):
                element1, element2 = packed
                if element1 is not None:
                    if index is focus1:
                        print_at(1+index, 0, ''.ljust(element1, '#'))
                    else:
                        print_at(1+index, 0, ''.ljust(element1, ':'))

                if element2 is not None:
                    if index is focus2:
                        print_at(1+index, self.middle_line + 1, ''.ljust(element2, '#'))
                    else:
                        print_at(1+index, self.middle_line + 1, ''.ljust(element2, ':'))

            counter += 1
            time.sleep(0.05)
        return self.counter_current_left, self.counter_current_right

    def draw_rope(self, length=0):
        if length is 0:
            self.rope_length = round(self.term_width/6*4+1)
        else:
            self.rope_length -= abs(length)
        print_at(self.term_height - 4, length + round(self.term_width/6), ''.center(self.rope_length, '='))

    # each guy is 8x8 characters
    def draw_guy_left(self, y_offset='default'):
        if y_offset is 'default':
            y_offset = round(self.term_width/6) + 1 + self.moved_left
        else:
            y_offset += round(self.term_width/6) + 1 + self.moved_left
        x = self.term_height - 8
        print_at(x  , y_offset, ' __     ')
        print_at(x+1, y_offset, '/><\    ')
        print_at(x+2, y_offset, '\__/    ')
        print_at(x+3, y_offset, '|\ |\   ')
        print_at(x+4, y_offset, '==\/0\/0')
        print_at(x+5, y_offset, '|__|    ')
        print_at(x+6, y_offset, ' \  \   ')
        print_at(x+7, y_offset, ' /_  \_ ')

    def draw_guys_left(self):
        for i in range(self.guy_side_amount):
            self.draw_guy_left(i*8)

    def draw_guy_right(self, y_offset='default'):
            if y_offset is 'default':
                y_offset = round(self.term_width/6*5) - 8 - self.moved_right
            else:
                y_offset = round(self.term_width/6*5) - 8 - y_offset - self.moved_right
            x = self.term_height - 8
            print_at(x  , y_offset, '     __ ')
            print_at(x+1, y_offset, '    /><\\')
            print_at(x+2, y_offset, '    \__/')
            print_at(x+3, y_offset, '   /| /|')
            print_at(x+4, y_offset, '0\/0\/==')
            print_at(x+5, y_offset, '    |__|')
            print_at(x+6, y_offset, '    / / ')
            print_at(x+7, y_offset, '  _/ _\ ')

    def draw_guys_right(self):
        for i in range(self.guy_side_amount):
            self.draw_guy_right(i*8)

    def update_tug(self, winner):
        move = random.randint(1, 3)
        self.clear_terminal_at_for(1, self.term_height-8, self.term_width, 8)
        if winner is 'left':
            self.moved_left += move
            self.draw_rope(move)
        elif winner is 'right':
            self.moved_right += move
            self.draw_rope(move)
        print_at(self.term_height-1, self.middle_line, '^')
        self.draw_guys_left()
        self.draw_guys_right()

        self.check_win_condition()

    def check_win_condition(self):
        if self.moved_left >= self.pixels_to_lose:
            print_at(self.term_height-7, self.middle_line-6, '+----------+')
            print_at(self.term_height-6, self.middle_line-6, '|RIGHT WON!|')
            print_at(self.term_height-5, self.middle_line-6, '+----------+')
            sys.exit(0)
        if self.moved_right >= self.pixels_to_lose:
            print_at(self.term_height-7, self.middle_line-6, '+----------+')
            print_at(self.term_height-6, self.middle_line-6, '|LEFT WON! |')
            print_at(self.term_height-5, self.middle_line-6, '+----------+')
            sys.exit(0)


import requests
import json

class Stack:
    def __init__(self):
        self.stack = []

    def push(self, item):
        self.stack.append(item)

    def pop(self):
        if not self.is_empty():
            return self.stack.pop()
        else:
            return None

    def peek(self):
        if not self.is_empty():
            return self.stack[-1]
        else:
            return None

    def is_empty(self):
        return len(self.stack) == 0

    def size(self):
        return len(self.stack)

def remove_from_end(url, length):
    return url[:len(url) - length].rstrip()

def show_web_content(url):
    print(url)
    web_content = fetch_web_content(url)
    if web_content:
        for key in web_content.keys():
            print(key, web_content[key])

stack = Stack()
url = 'http://swds.kasi.re.kr/swpipeline/api/search.php?table'
flag = True

def fetch_web_content(url):
    try:
        response = requests.get(url)
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        print("Error occurred:", e)
        return None

show_web_content(url)

while flag:
    input_str = input("Enter the path: ")
    if input_str == 'exit':
        flag = False
    elif input_str == 'undo':
        url = remove_from_end(url, len(stack.pop()))
        show_web_content(url)
    elif input_str == 'download':
        json_data = fetch_web_content(url)
        stack.push(input_str)
        url = url.replace('search', 'download')
        if len(json_data['data_list']) == 1:
            file_name = json_data['data_list'][0]['name']
            with open(file_name, 'wb') as file:
                file.write(requests.get(url).content)
        else:
            url_data_line = url.split('?')[-1]
            url_data_list = url_data_line.split('&')
            url_dict = {}
            for url_data in url_data_list:
                key, value = url_data.split('=')
                url_dict[key] = value
            file_name = url_dict['table'] + '_' + url_dict['data_id'] + '_' + json_data['data_start_time'] + '_' + json_data['data_end_time'] + '.zip'
            with open(file_name, 'wb') as file:
                file.write(requests.get(url).content)
        url = url.replace('download', 'search')
        stack.pop()
        show_web_content(url)
    else:
        stack.push(input_str)
        url = url + stack.peek()
        show_web_content(url)

# 종료하기 전까지 경로 입력 반복
# 스택 사용하여 url 접근 혹은 취소
# exit 입력 시 종료
# undo 입력 시 이전 명령 취소
# download 입력 시 search -> download 변환하여 파일 다운로드 후 다시 download -> search 변환


from django.urls import path

from . import views

urlpatterns = [
    path('bots', views.bots, name='bots'),
    path('bots/<int:botId>', views.bot, name='bot'),
    path('start', views.start, name='start'),
    path('stop', views.stop, name='stop')
]


"""Test the WSGI intercept code."""

from twill import commands

from wsgi_intercept import (
    requests_intercept, add_wsgi_intercept, remove_wsgi_intercept)

def setup_module():
    requests_intercept.install()

def teardown_module():
    requests_intercept.uninstall()

app_was_hit = set()

def simple_app(_environ, start_response):
    """Simplest possible application object"""
    status = '200 OK'
    response_headers = [('Content-type', 'text/plain')]
    start_response(status, response_headers)
    app_was_hit.add('simple_app')
    return [b'WSGI intercept successful!\n']

def write_app(_environ, start_response):
    """Test the 'write_fn' legacy stuff."""
    status = '200 OK'
    response_headers = [('Content-type', 'text/plain')]
    write_fn = start_response(status, response_headers)
    app_was_hit.add('write_app')
    write_fn(b'WSGI intercept successful!\n')
    return []

class IteratorApp:
    """Test some tricky iterator stuff in wsgi_intercept."""

    content = [b'Hello, world']

    def __call__(self, environ, start_response):
        status = '200 OK'
        response_headers = [('Content-type', 'text/plain')]
        start_response(status, response_headers)
        return self

    def __iter__(self):
        self._iter = iter(self.content)
        return self

    def __next__(self):
        return next(self._iter)

def test_intercept():
    app_was_hit.clear()
    add_wsgi_intercept('localhost', 8080, lambda: simple_app)
    assert not app_was_hit
    commands.go('http://localhost:8080/')
    commands.show()
    commands.find("WSGI intercept successful")
    assert 'simple_app' in app_was_hit
    remove_wsgi_intercept('localhost', 8080)

def test_write_intercept():
    app_was_hit.clear()
    add_wsgi_intercept('localhost', 8080, lambda: write_app)
    assert not app_was_hit
    commands.go('http://localhost:8080/')
    commands.show()
    commands.find("WSGI intercept successful")
    assert 'write_app' in app_was_hit
    remove_wsgi_intercept('localhost', 8080)

def test_iter_stuff():
    add_wsgi_intercept('localhost', 80, IteratorApp)
    commands.go('http://localhost:80/')
    commands.show()
    commands.find("Hello, world")
    commands.notfind("Hello, worldHello, world")
    remove_wsgi_intercept('localhost', 80)


"""
떡볶이 떡의 길이가 일정하지 않다. 대신 한 봉지 안에 들어가는 떡의 총 길이는 절단기로 잘라 맞춰준다.
절단기에 높이(H)를 지정하면 줄지어진 떡을 한번에 절단한다.
높이가 H보다 긴 떡은 H 위의 부분이 잘리고, 낮은 떡은 잘리지 않는다.

예를 들어 높이가 19, 14, 10, 17cm인 떡이 나란히 있고 절단기 높이를 15cm로 지정하면
자른 뒤 떡의 높이는 15, 14, 10, 15cm가 된다. 잘린 떡의 길이는 차례대로 4,0,0,2cm이다.
손님은 6cm 만큼의 길이를 가져간다.

손님이 왔을때 요청한 총 길이가 M일 때
적어도 M만큼의 떡을 얻기 위해 절단기에 설정할 수 있는 높이의 최댓값을 구하는 프로그램을 작성하라

첫째 줄에 떡의 개수 N과 요청한 떡의 길이 M이 주어진다.
둘쨰 줄에 떡의 개별 높이가 주어진다. 떡 높이 총합은 항상 M 이상이다.

적어도 M만큼의 떡을 집에 가져가기 위해 절단기에 설정할 수 있는 높이의 최댓값을 출력하라.
"""

"""

N, M = map(int, input().split())
dduck = list(map(int, input().split()))

print(dduck)

min_length = min(dduck)
max_length = max(dduck)

cutter = []

for cut_length in range(min_length, max_length):
    dduck_cut = []
    print("자르는 길이 : {}".format(cut_length))
    for i in dduck:
        if i - cut_length > 0:
            dduck_cut.append(i - cut_length)
        else:
            dduck_cut.append(0)
    print("잘린 떡 : {}, 합 : {}".format(dduck_cut, sum(dduck_cut)))
    if sum(dduck_cut) >= M:
        cutter.append(cut_length)
print(cutter)
print(max(cutter))

"""

# 절단기 높이를 크게 하면 잘린 떡의 길이가 짧아지고, 높이를 낮게 하면 잘린 떡의 길이가 길어진다.
# -> 이진 탐색 사용 가능
# 현재 이 높이로 자르면 조건을 만족하는가?를 확인한 뒤 조건의 만족 여부에 따라 탐색범위 좁혀 해결 가능.
# 절단기 높이가 0~10억이므로 큰 탐색범위에서 선형탐색 하면 안됨 -> 이진 탐색 필요

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

array = list(map(int, input()))

# 이진 탐색을 위한 시작점, 끝점 설정
start = 0
end = max(array)

# 이진 탐색 수행(반복적)
result = 0
while start <= end:
    total = 0
    mid = (start + end) // 2
    for x in array:
        # 잘랐을 때의 떡의 양 계산
        if x > mid:
            total += x - mid
    # 떡의 양이 충분한 경우 더 자르기(오른쪽 부분 탐색)
    if total < x:
        end = mid - 1
    # 떡의 양이 충분한 경우 덜 자르기(왼쪽 부분 탐색)
    else:
        result = mid
        start = mid + 1

print(result)


import os

from flask import (
    current_app, jsonify, render_template, request, url_for, redirect)
from flask.views import View

from sqlalchemy import func as sql_func

from debsources.excepts import (
    Http500Error, Http404Error, Http404ErrorSuggestions, Http403Error)
from debsources.models import (
    Ctag, Package, PackageName, Checksum, File, Suite)
from debsources.sqla_session import _close_session
from debsources import local_info
from debsources.consts import SUITES
from .forms import SearchForm
from .pagination import Pagination
from .infobox import Infobox
from .helper import format_big_num, url_for_other_page

from . import app_wrapper
app = app_wrapper.app
session = app_wrapper.session

# static file serving
if 'SERVE_STATIC_FILES' in app.config and app.config['SERVE_STATIC_FILES']:
    import flask

    @app.route('/javascript/<path:path>')
    def javascript(path):
        return flask.send_from_directory('/usr/share/javascript/', path)

    @app.route('/icons/<path:path>')
    def icons(path):
        return flask.send_from_directory('/usr/share/icons/', path)

@app.teardown_appcontext
def shutdown_session(exception=None):
    _close_session(session)

# variables needed by "base.html" skeleton
# packages_prefixes and search form (for the left menu),
# last_update (for the footer)
# TODO the context need a little bit modification
@app.context_processor
def skeleton_variables():
    update_ts_file = os.path.join(app.config['CACHE_DIR'], 'last-update')
    # TODO, this part should be moved to per blueprint context processor
    last_update = local_info.read_update_ts(update_ts_file)

    packages_prefixes = PackageName.get_packages_prefixes(
        app.config["CACHE_DIR"])

    credits_file = os.path.join(app.config["LOCAL_DIR"], "credits.html")
    credits = local_info.read_html(credits_file)

    return dict(packages_prefixes=packages_prefixes,
                searchform=SearchForm(),
                last_update=last_update,
                credits=credits)

# jinja2 settings
app.jinja_env.filters['format_big_num'] = format_big_num
app.jinja_env.globals['url_for_other_page'] = url_for_other_page

# ERRORS
class ErrorHandler(object):

    def __init__(self, bp_name='', mode='html', http=404):
        self.bp_name = bp_name
        self.mode = mode
        self.http = http

    def __call__(self, error, http=None):
        if http is not None:
            self.http = http
        try:
            method = getattr(self, 'error_{}'.format(self.http))
        except:
            raise Exception("Unimplemented HTTP error: {}".format(self.http))
        return method(error)

    def bp_path(self, tpl):
        return os.path.join(self.bp_name, tpl)

    def error_403(self, error):
        if self.mode == 'json':
            return jsonify(dict(error=403))
        else:
            return render_template(self.bp_path('403.html')), 403

    def error_404(self, error):
        if self.mode == 'json':
            return jsonify(dict(error=404))
        else:
            if isinstance(error, Http404ErrorSuggestions):
                # let's suggest all the possible locations with a different
                # package version
                possible_versions = PackageName.list_versions(
                    session, error.package)
                suggestions = ['/'.join(
                    filter(None, [error.package, v.version, error.path]))
                    for v in possible_versions]
                return render_template(self.bp_path('404_suggestions.html'),
                                       suggestions=suggestions), 404
            else:
                return render_template(self.bp_path('404.html')), 404

    def error_500(self, error):
        """
        logs a 500 error and returns the correct template
        """
        app.logger.exception(error)

        if self.mode == 'json':
            return jsonify(dict(error=500))
        else:
            return render_template(
                self.bp_path('500.html')), 500

# TODO unlike 403,404, which could be registered per blueprint,
# there could be only one 500 error handler for the whole app.
# thus, the 500 handler should be aware of the active blueprint,
# so that correct page template will be rendered for the blueprint.
# we should avoid hard-coding the 'source'
app.errorhandler(500)(ErrorHandler('sources', http=500))

# following is a plain text, bp-agnostic one.
# app.errorhandler(403)(lambda _: ("Forbidden", 403))
# app.errorhandler(404)(lambda _: ("File not Found", 404))
# app.errorhandler(500)(lambda _: ("Server Error", 500))

# FOR BOTH RENDERING AND API
class GeneralView(View):
    def __init__(self,
                 render_func=jsonify,
                 err_func=ErrorHandler(mode='json'),
                 get_objects=None,
                 **kwargs):
        """
        render_func: the render function, e.g. jsonify or render_template
        err_func: the function called when an error occurs
        get_objects: the function called to get context objects.
        """
        self.render_func = render_func
        self.err_func = err_func

        if get_objects:
            if isinstance(get_objects, basestring):
                self.get_objects = getattr(self, "get_"+get_objects)
            else:
                # we don't check if it's a callable.
                # if err, then let it err.
                self.get_objects = get_objects

        self.d = kwargs

    def get_objects(self, **kwargs):
        return dict()

    def dispatch_request(self, **kwargs):
        """
        renders the view, or call the error function with the error and
        the http error code (404 or 500)
        """
        try:
            context = self.get_objects(**kwargs)
            return self.render_func(**context)
        except Http403Error as e:
            return self.err_func(e, http=403)
        except Http404Error as e:
            return self.err_func(e, http=404)
        except Http500Error as e:
            return self.err_func(e, http=500)
        # do not propagate the exception
        except Exception as e:
            return self.err_func(e, http=500)

# PING #
# this is used to check the health of the service
# for example by codesearch.debian.net
# If we want to stop traffic from codesearch.d.n, just return 500 error
class Ping(View):
    def dispatch_request(self):
        update_ts_file = os.path.join(
            current_app.config['CACHE_DIR'], 'last-update')
        last_update = local_info.read_update_ts(update_ts_file)
        try:
            session.query(Package).first().id  # database check
        except:
            return jsonify(dict(status="db error", http_status_code=500)), 500
        return jsonify(dict(status="ok",
                            http_status_code=200,
                            last_update=last_update))

# for '/'
class IndexView(GeneralView):

    def get_objects(self, **kwargs):
        news_file = os.path.join(current_app.config["LOCAL_DIR"],
                                 self.d['news_html'])
        news = local_info.read_html(news_file)
        return dict(news=news)

# for /docs/*
class DocView(GeneralView):
    """
    Renders page for /doc/*
    """

# for /about/
class AboutView(GeneralView):
    """
    Renders page for /about/
    """

class SearchView(GeneralView):

    def dispatch_request(self, **kwargs):
        if self.d.get('recv_search'):
            return self.recv_search()
        else:
            return super(SearchView, self).dispatch_request(**kwargs)

    def get_query(self, query=''):
        """
        processes the search query and renders the results in a dict
        """
        query = query.replace('%', '').replace('_', '')
        suite = request.args.get("suite") or ""
        suite = suite.lower()
        if suite == "all":
            suite = ""
        # if suite is not specified
        if not suite:
            try:
                exact_matching = (session.query(PackageName)
                                  .filter_by(name=query)
                                  .first())

                other_results = (session.query(PackageName)
                                 .filter(sql_func.lower(PackageName.name)
                                         .contains(query.lower()))
                                 .order_by(PackageName.name)
                                 )
            except Exception as e:
                raise Http500Error(e)  # db problem, ...
        else:
            try:
                exact_matching = (session.query(PackageName)
                                  .filter(sql_func.lower(Suite.suite)
                                          == suite)
                                  .filter(Suite.package_id == Package.id)
                                  .filter(Package.name_id == PackageName.id)
                                  .filter(PackageName.name == query)
                                  .first())

                other_results = (session.query(PackageName)
                                 .filter(sql_func.lower(Suite.suite)
                                         == suite)
                                 .filter(Suite.package_id == Package.id)
                                 .filter(Package.name_id == PackageName.id)
                                 .filter(sql_func.lower(PackageName.name)
                                         .contains(query.lower()))
                                 .order_by(PackageName.name))
            except Exception as e:
                raise Http500Error(e)  # db problem, ...

        if exact_matching is not None:
            exact_matching = exact_matching.to_dict()
        if other_results is not None:
            other_results = [o.to_dict() for o in other_results]
            # we exclude the 'exact' matching from other_results:
            other_results = filter(lambda x: x != exact_matching,
                                   other_results)

        results = dict(exact=exact_matching,
                       other=other_results)
        return dict(results=results, query=query, suite=suite)

    def get_advanced(self):
        return dict(suites_list=SUITES["all"])

    # for '/search/'
    def recv_search(self, **kwargs):
        searchform = SearchForm(request.form)
        if searchform.validate_on_submit():
            params = dict(query=searchform.query.data)
            suite = searchform.suite.data
            if suite:
                params["suite"] = suite
            return redirect(url_for(".search", **params))
        else:
            # we return the form, to display the errors
            return self.render_func(searchform=searchform)

class ChecksumView(GeneralView):

    @staticmethod
    def _files_with_sum(checksum, slice_=None, package=None):
        """
        Returns a list of files whose hexdigest is checksum.
        You can slice the results, passing slice=(start, end).
        """
        results = (session.query(PackageName.name.label("package"),
                                 Package.version.label("version"),
                                 Checksum.file_id.label("file_id"),
                                 File.path.label("path"))
                   .filter(Checksum.sha256 == checksum)
                   .filter(Checksum.package_id == Package.id)
                   .filter(Checksum.file_id == File.id)
                   .filter(Package.name_id == PackageName.id)
                   )
        if package is not None and package != "":
            results = results.filter(PackageName.name == package)

        results = results.order_by("package", "version", "path")

        if slice_ is not None:
            results = results.slice(slice_[0], slice_[1])
        results = results.all()

        return [dict(path=res.path,
                     package=res.package,
                     version=res.version)
                for res in results]

    def get_objects(self, **kwargs):
        """
        Returns the files whose checksum corresponds to the one given.
        """
        try:
            page = int(request.args.get("page"))
        except:
            page = 1
        checksum = request.args.get("checksum")
        package = request.args.get("package") or None

        # we count the number of results:
        count = (session.query(sql_func.count(Checksum.id))
                 .filter(Checksum.sha256 == checksum))
        if package is not None and package != "":  # (only within the package)
            count = (count.filter(PackageName.name == package)
                     .filter(Checksum.package_id == Package.id)
                     .filter(Package.name_id == PackageName.id))
        count = count.first()[0]

        # pagination:
        if self.d.get('pagination'):
            offset = int(current_app.config.get("LIST_OFFSET") or 60)
            start = (page - 1) * offset
            end = start + offset
            slice_ = (start, end)
            pagination = Pagination(page, offset, count)
        else:
            pagination = None
            slice_ = None

        # finally we get the files list
        results = self._files_with_sum(
            checksum, slice_=slice_, package=package)

        return dict(results=results,
                    sha256=checksum,
                    count=count,
                    page=page,
                    pagination=pagination)

class CtagView(GeneralView):

    def get_objects(self):
        """
        Returns the places where ctag are found.
        (limit to package if package is not None)
        """
        try:
            page = int(request.args.get("page"))
        except:
            page = 1
        ctag = request.args.get("ctag")
        package = request.args.get("package") or None

        # pagination:
        if self.d.get('pagination'):
            try:
                offset = int(current_app.config.get("LIST_OFFSET"))
            except:
                offset = 60
            start = (page - 1) * offset
            end = start + offset
            slice_ = (start, end)
        else:
            pagination = None
            slice_ = None
        count, results = Ctag.find_ctag(session, ctag, slice_=slice_,
                                        package=package)
        if self.d.get('pagination'):
            pagination = Pagination(page, offset, count)
        else:
            pagination = None

        return dict(results=results,
                    ctag=ctag,
                    count=count,
                    page=page,
                    package=package,
                    pagination=pagination)

class PrefixView(GeneralView):

    def get_objects(self, prefix='a'):
        """
        returns the packages beginning with prefix
        and belonging to suite if specified.
        """
        prefix = prefix.lower()
        suite = request.args.get("suite") or ""
        suite = suite.lower()
        if suite == "all":
            suite = ""
        if prefix in PackageName.get_packages_prefixes(
                app.config["CACHE_DIR"]):
            try:
                if not suite:
                    packages = (session.query(PackageName)
                                .filter(sql_func.lower(PackageName.name)
                                        .startswith(prefix))
                                .order_by(PackageName.name)
                                .all()
                                )
                else:
                    packages = (session.query(PackageName)
                                .filter(sql_func.lower(Suite.suite)
                                        == suite)
                                .filter(Suite.package_id == Package.id)
                                .filter(Package.name_id == PackageName.id)
                                .filter(sql_func.lower(PackageName.name)
                                        .startswith(prefix))
                                .order_by(PackageName.name)
                                .all()
                                )

                packages = [p.to_dict() for p in packages]
            except Exception as e:
                raise Http500Error(e)
            return dict(packages=packages,
                        prefix=prefix,
                        suite=suite)
        else:
            raise Http404Error("prefix unknown: %s" % str(prefix))

class ListPackagesView(GeneralView):
    def get_objects(self, page=1):
        if not self.d.get('pagination'):  # api form, we retrieve all packages
            try:
                packages = (session.query(PackageName)
                            .order_by(PackageName.name)
                            .all()
                            )
                packages = [p.to_dict() for p in packages]
                return dict(packages=packages)
            except Exception as e:
                raise Http500Error(e)
        else:  # we paginate
            # WARNING: not serializable (TODO: serialize Pagination obj)
            try:
                offset = int(app.config.get("LIST_OFFSET") or 60)

                # we calculate the range of results
                start = (page - 1) * offset
                end = start + offset

                count_packages = (session.query(PackageName)
                                  .count()
                                  )
                packages = (session.query(PackageName)
                            .order_by(PackageName.name)
                            .slice(start, end)
                            )
                pagination = Pagination(page, offset, count_packages)

                return dict(packages=packages,
                            page=page,
                            pagination=pagination)

            except Exception as e:
                raise Http500Error(e)

# INFO PAGES #
class InfoPackageView(GeneralView):
    def get_objects(self, package, version):
        pkg_infos = Infobox(session, package, version).get_infos()
        return dict(pkg_infos=pkg_infos,
                    package=package,
                    version=version)


from src.config import gpu_id
import sys

sys.path.append("../../../Asset Wealth")
import os

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"] = gpu_id
from src.data_utils import generator, create_splits
import matplotlib.pyplot as plt
from functools import partial
from operator import itemgetter

from tensorflow.keras.callbacks import EarlyStopping
import tensorflow as tf
from tensorflow.data import Dataset
from tensorflow.keras import optimizers, models

from sklearn.model_selection import KFold

# import models
from src.vgg19 import VGG19_hyperspectral
from src.resnet50 import ResNet50v2_hyperspectral

import wandb
from wandb.keras import WandbCallback
try:
    from src.config import wandb_project
    from src.config import wandb_entity
    from src.config import wandb_dir
except:
    raise NameError("Set Weights and Bias Parameters in config.py first.")
import atexit

tf.debugging.set_log_device_placement(True)
gpus = tf.config.experimental.list_physical_devices('GPU')
print(gpus)
if gpus:
    try:
        # Currently, memory growth needs to be the same across GPUs
        for gpu in gpus:
            tf.config.experimental.set_memory_growth(gpu, True)
        print(len(gpus), "Physical GPU(s)")
    except RuntimeError as e:
        # Memory growth must be set before GPUs have been initialized
        print(e)

from src.config import img_path
from src.config import pre2015_path
from src.config import csv_path
from src.config import model_name
from src.config import k
from src.config import input_height
from src.config import input_width
from src.config import img_source
from src.config import urban_rural
from src.config import channel_size
from src.config import batch_size
from src.config import epochs
from src.config import subset
from src.config import lr
from src.config import loss
from src.config import early_stopping_patience

def main(img_dir: str, csv_path: str, pre2015_path:str, model_name: str, k: int,
         input_height: int, input_width: int, img_source: str, urban_rural: str,
         channel_size: int, batch_size: int, epochs: int, subset: bool):
    '''Train a Model with the Parameters set in config.py.

    Args:
        img_dir (str): Path to image data
        csv_path (str): Path to label csv files
        pre2015_path(str):  Path to image data older than 2015; if all data is used for training this should be False.
        model_name (str): One of ['vgg19', 'resnet50'] to choose which model is used
        k (int): Number of folds for cross validation
        input_height (int): Pixel height of input
        input_width (int): Pixel width of input
        img_source (str): One of ['s2', 'viirs'] to choose whether Sentinel-2, VIIRS (nightlight) or combined data is used
        urban_rural (str): On of ['u','r','ur'] to choose whether only urban or only rural clusters are used
        channels (list):  Channels to use; [] to use all channels
        channel_size (int): Number of channels (3 for RGB (VIIRS), 13 for all Sentinel-2 channels, 14 for all channels) !Nightlight channel is transformed to 3 channels for model compatibility
        batch_size (int): Size of training batches
        epochs (int): Number of training epochs
        subset (bool): Whether or not to use a subset to test the process
    '''

    if pre2015_path:
        X_train_val, X_test, y_train_val, y_test, X_test_pre2015, y_test_pre2015 = create_splits(img_dir,
                                                                                pre2015_path,
                                                                                csv_path,
                                                                                urban_rural,
                                                                                subset)
    else:
        X_train_val, X_test, y_train_val, y_test = create_splits(img_dir,
                                                                 pre2015_path,
                                                                 csv_path,
                                                                 urban_rural,
                                                                 subset)
    kf = KFold(n_splits=k, random_state=None, shuffle=False)
    for fold, (train_index, val_index) in enumerate(kf.split(X_train_val)):
        print(f'Fold: {fold}')
        # Load Folds
        X_train, X_val = list(itemgetter(*train_index)(X_train_val)), list(itemgetter(*val_index)(X_train_val))
        y_train, y_val = y_train_val[train_index], y_train_val[val_index]
        print(f'Training size: {len(X_train)} \n Validation size: {len(X_val)} \n Test Size: {len(X_test)}')
        # generate datasets
        train_generator_func = partial(generator, img_dir, X_train, y_train, batch_size, input_height, input_width,
                                       channel_size)

        train_ds = Dataset.from_generator(generator=train_generator_func,
                                          output_types=(tf.float64, tf.float64),
                                          output_shapes=((batch_size, input_width, input_height, channel_size),
                                                         (batch_size,)),
                                          )

        # This part generates the validation generator for the NN
        val_generator_func = partial(generator, img_dir, X_val, y_val, batch_size, input_height, input_width,
                                     channel_size)

        val_ds = Dataset.from_generator(generator=val_generator_func,
                                        output_types=(tf.float64, tf.float32),
                                        output_shapes=((batch_size, input_width, input_height, channel_size),
                                                       (batch_size,)),
                                        )

        # adjust to hyperspectral input

        if model_name == 'vgg19':
            hyperspectral_model_obj = VGG19_hyperspectral(img_w=input_width,
                                                          img_h=input_height,
                                                          channels=channel_size
                                                          )
            model = hyperspectral_model_obj.load_vgg19()
        elif model_name == 'resnet50':
            hyperspectral_model_obj = ResNet50v2_hyperspectral(img_w=input_width,
                                                               img_h=input_height,
                                                               channels=channel_size
                                                              )
            model = hyperspectral_model_obj.load_resnet50v2()

        model.compile(optimizer=optimizers.RMSprop(learning_rate=lr),
                      loss=loss, metrics=[tf.keras.metrics.MeanSquaredError(),
                                                          tf.keras.metrics.MeanAbsoluteError(),
                                                          tf.keras.metrics.MeanAbsolutePercentageError(),
                                                          tf.keras.metrics.RootMeanSquaredError(),
                                                          tf.keras.metrics.CosineSimilarity()
                                                          ])

        wandb.init(project=wandb_project, entity=wandb_entity, dir=wandb_dir,
                   group=f'{model_name}_pretrained_model_{urban_rural}_{img_source}_{batch_size}', job_type='train',
                   name=f'{model_name}_pretrained_model_{urban_rural}_{img_source}_{batch_size}_fold_{fold}')
        config = wandb.config  # Config is a variable that holds and saves hyperparameters and inputs
        config.learning_rate = lr
        config.batch_size = batch_size
        config.epochs = epochs
        config.img_width = input_width
        config.img_height = input_height
        config.model_name = model_name
        config.pretrain_weights = 'imagenet'
        config.urban_rural = urban_rural
        config.image_source = img_dir
        config.loss = loss
        config.metrics = config.metrics = [loss,
                          'mean_absolute_error',
                          'mean_absolute_percentage_error',
                          'root_mean_squared_error',
                          'cosine_similarity']
        print('Start Model Training')
        # Fit and train model
        history = model.fit(
            train_ds,
            validation_data=val_ds,
            epochs=epochs,
            verbose=1,
            callbacks=[WandbCallback(),
                       EarlyStopping(
                           monitor="val_loss",
                           patience=early_stopping_patience,
                       )])
        print(history.history)

        # Evaluate model for this fold.

        print('Evaluating Model')

        # This part generates the test generator for the NN
        test_generator_func = partial(generator, img_dir, X_test, y_test, batch_size, input_height, input_width,
                                      channel_size)
        test_ds = Dataset.from_generator(generator=test_generator_func,
                                         output_types=(tf.float64, tf.float32),
                                         output_shapes=((batch_size, input_width, input_height, channel_size),
                                                        (batch_size,)),
                                         )
        # Evaluate on testset
        evaluation = model.evaluate(test_ds)

        wandb.log({'MeanSquaredError': evaluation[0]})
        wandb.log({'MeanAbsoluteError': evaluation[1]})
        wandb.log({'MeanAbsolutePercentageError': evaluation[2]})
        wandb.log({'RootMeanSquaredError': evaluation[3]})
        wandb.log({'CosineSimilarity': evaluation[4]})

        if pre2015_path:
            test_generator_func = partial(generator, pre2015_path, X_test_pre2015, y_test_pre2015, batch_size, input_height, input_width,
                                          channel_size)
            test_ds = Dataset.from_generator(generator=test_generator_func,
                                             output_types=(tf.float64, tf.float32),
                                             output_shapes=((batch_size, input_width, input_height, channel_size),
                                                            (batch_size,)),
                                             )
            # Evaluate on second testset
            evaluation = model.evaluate(test_ds)

            wandb.log({'MeanSquaredError_2012_2014': evaluation[0]})
            wandb.log({'MeanAbsoluteError_2012_2014': evaluation[1]})
            wandb.log({'MeanAbsolutePercentageError_2012_2014': evaluation[2]})
            wandb.log({'RootMeanSquaredError_2012_2014': evaluation[3]})
            wandb.log({'CosineSimilarity_2012_2014': evaluation[4]})

        del model
        del train_ds
        del val_ds
        del test_ds

        wandb.finish()

if __name__ == '__main__':
    main(img_dir=img_path,
         csv_path=csv_path,
         model_name=model_name,
         k=k,
         input_height=input_height,
         input_width=input_width,
         img_source=img_source,
         urban_rural=urban_rural,
         channel_size=channel_size,
         batch_size=batch_size,
         epochs=epochs,
         subset=subset)


class RandomizedSet:

    def __init__(self):
        self.hashmp = {}
        self.arr = []

    def insert(self, val: int) -> bool:
        if val in self.hashmp:
            return False
        self.hashmp[val] = len(self.arr)
        self.arr.append(val)
        return True

    def remove(self, val: int) -> bool:
        if val not in self.hashmp:
            return False

        curInd = self.hashmp[val]

        self.hashmp[self.arr[-1]] = curInd
        self.arr[curInd], self.arr[-1] = self.arr[-1], self.arr[curInd]

        self.arr.pop()
        del self.hashmp[val]
        return True

    def getRandom(self) -> int:
        rn = randint(0, len(self.arr) - 1)
        return self.arr[rn]

# Your RandomizedSet object will be instantiated and called as such:
# obj = RandomizedSet()
# param_1 = obj.insert(val)
# param_2 = obj.remove(val)
# param_3 = obj.getRandom()


# ----------------------------------------------------------
# --------              HW 9: Part 1               ---------
# ----------------------------------------------------------

# ----------------------------------------------------------
# Name: Alexa Canaan
# Time spent on part 1: 8 hours
# Collaborators and sources: lab hours, office hours
#   (List any collaborators or sources here.)
# ----------------------------------------------------------

import turtle
import random

WIDTH = 1024
HEIGHT = 768

def mondrian(x, y, w, h, t):
  # Write your code here
  # You will want to create other Functions
  # for good program design

  W = random_int_gen(w)
  H = random_int_gen(h)

  t.setx(x)       #sets coordinates, turtle will always face east/right to begin
  t.sety(y)

  if w > (.5 * WIDTH) and h > (.5 * HEIGHT):      #checks if the region is wider than half the initial canvas size and the region is taller than half the inital canvas height
    neww, newh = split4ways(x, y, w, h, t)        #region is split into 4 smaller ones
    mondrian(x, y, neww, newh, t)
    mondrian((x + neww), y, (w-neww), newh, t)
    mondrian((x + neww), (y + newh), (w - neww), (h - newh), t)
    mondrian(x, (newh + y), neww, (h - newh), t)

  elif w > (.5 * WIDTH):                          #if the region is wider than half the initial canvas size
    neww = splitVert(x, y, w, h, t)               #region is split into 2 smaller ones w/ vertical line
    mondrian(x, y, neww, h, t)
    mondrian((x + neww), y, (w-neww), h, t)

  elif h > (.5 * HEIGHT):                         #if the region is taller than half the initial canvas size
    newh = splitHoriz(x, y, w, h, t)              #region is split into 2 smaller ones w/ horizontal line
    mondrian(x, y, w, newh, t)
    mondrian(x, (y + newh), w, (h-newh), t)

  elif W >= 120 and H >= 120 and W < w and H < h: #randomly chooses to split horizontally and vertically
    neww, newh = split4ways(x, y, w, h, t)        #region is split into 4 smaller ones
    mondrian(x, y, neww, newh, t)
    mondrian((x + neww), y, (w-neww), newh, t)
    mondrian((x + neww), (y + newh), (w - neww), (h - newh), t)
    mondrian(x, (newh + y), neww, (h - newh), t)

  elif W >= 120 and W < w:                        #randomly chooses to split vertically
    neww = splitVert(x, y, w, h, t)               #region is split into 2 smaller ones
    mondrian(x, y, neww, h, t)
    mondrian((x + neww), y, (w-neww), h, t)

  elif H >= 120 and H < h:                        #randomly chooses to split horizontally
    newh = splitHoriz(x, y, w, h, t)              #region is split into 2 smaller ones
    mondrian(x, y, w, newh, t)
    mondrian(x, (y + newh), w, (h-newh), t)

  else:                                           #when it can't be split anymore, fill it with a color
    fill_color(t)
    t.begin_fill()
    t.forward(w)
    t.left(90)
    t.forward(h)
    t.left(90)
    t.forward(w)
    t.left(90)
    t.forward(h)
    t.end_fill()
    t.left(90)

def fill_color(t):
  '''fills the region'''
  r = random.random()
  if r < .0833:               #probability of filling a region red
    t.fillcolor('red')
  elif r < .1667:             #probability of filling a region blue
    t.fillcolor('blue')
  elif r < .25:               #probability of filling a region yellow
    t.fillcolor('yellow')
  else:                       #probability of filling a region white
    t.fillcolor('white')

def random_int_gen(x):
  '''randomly decides whether or not to split'''
  extralength = x * 1.5
  integer = int(random.uniform(120, extralength))     #generates a num b/w 120 and w *1.5 to split
  return integer

def random_split():
  '''choose the split point'''
  return random.randint(33, 67) / 100   #chooses the percent between 33 and 67 to split at

##def split_region(w, h):
##  '''decides how to split the region'''

def splitVert(x, y, w, h, t):
  '''splits region with a vertical line into 2 regions'''
  t.setx(x)
  t.sety(y)

  pVert = random_split()
  neww = w * pVert

  t.forward(w * pVert)        #draws the left box
  t.left(90)
  t.forward(h)
  t.left(90)
  t.forward(w * pVert)
  t.left(90)
  t.forward(h)
  t.left(90)

  t.penup()                   #draws the right box
  t.forward(w * pVert)
  t.pendown()
  t.forward(w - neww)
  t.left(90)
  t.forward(h)
  t.left(90)
  t.forward(w - neww)
  t.left(90)
  t.forward(h)
  t.right(90)
  t.penup()
  t.forward(neww)
  t.left(180)
  t.pendown()

  return neww

def splitHoriz(x, y, w, h, t):
  '''splits region with a horizontal line into 2 regions'''
  t.setx(x)
  t.sety(y)
  pHoriz = random_split()
  newh = h * pHoriz

  t.forward(w)                #draws the bottom box
  t.left(90)
  t.forward(h * pHoriz)
  t.left(90)
  t.forward(w)
  t.left(90)
  t.forward(h* pHoriz)
  t.left(90)

  t.left(90)                  #draws the top box
  t.forward(h)
  t.right(90)
  t.forward(w)
  t.right(90)
  t.forward(h - newh)
  t.right(90)
  t.forward(w)
  t.left(90)
  t.forward(newh)
  t.left(90)

##  t.left(90)
##  t.forward(h * pHoriz)
##  t.right(90)
##  t.forward(w)
##  t.right(90)
##  t.forward(h * pHoriz)
##  t.right(90)
##  t.forward(w)
##  t.left(180)
  return newh

def split4ways(x, y, w, h, t):
  '''splits the region with a horizontal line and a vertical line into 4 regions'''
  newh = splitHoriz(x, y, w, h, t)
  neww = splitVert(x, y, w, h, t)
##  pVert = random_split()
##  pHoriz = random_split()
##  neww = w * pVert
##  newh = h * pHoriz
##
##  t.setx(x)
##  t.sety(y)
##
##  t.forward(w * pVert)
##  t.left(90)
##  t.forward(h)
##  t.left(90)
##  t.forward(w * pVert)
##  t.left(90)
##  t.forward(h)
##  t.left(90)
##
##  t.penup()
##  t.forward(w * pVert)
##  t.pendown()
##  t.forward(w - neww)
##  t.left(90)
##  t.forward(h)
##  t.left(90)
##  t.forward(w - neww)
##  t.left(90)
##  t.forward(h)
##  t.right(90)
##  t.penup()
##  t.forward(neww)
##  t.left(180)
##  t.pendown()
##
##  t.forward(w)
##  t.left(90)
##  t.forward(h * pHoriz)
##  t.left(90)
##  t.forward(w)
##  t.left(90)
##  t.forward(h* pHoriz)
##  t.left(90)
##
##  t.left(90)
##  t.forward(h)
##  t.right(90)
##  t.forward(w)
##  t.right(90)
##  t.forward(h - newh)
##  t.right(90)
##  t.forward(w)
##  t.left(90)
##  t.forward(newh)
##  t.left(90)

  return neww, newh

def main():
  # Create a window with a canvas
  t = turtle.Turtle()
  wn = turtle.Screen()
  wn.setworldcoordinates(0, 0, WIDTH+1, HEIGHT+1)
  t.pensize(5)
  t.speed(0)
  t.hideturtle()

  # Draw the art
  t.forward(WIDTH)              #draws the initial box
  t.left(90)
  t.forward(HEIGHT)
  t.left(90)
  t.forward(WIDTH)
  t.left(90)
  t.forward(HEIGHT)
  t.left(90)
  mondrian(0, 0, 1024, 768, t)
##  split_region(1024, 768)
  wn.exitonclick()

if __name__ == '__main__':
  main()


import sys
import subprocess

# def read_file_paths(file_path):
#     with open(file_path, 'r') as file:
#         return [line.strip() for line in file]

# def read_file_paths(file_path):
#     encodings = ['utf-8', 'iso-8859-1', 'cp1252']  # 常见的几种编码
#     for encoding in encodings:
#         try:
#             with open(file_path, 'r', encoding=encoding) as file:
#                 return [line.strip() for line in file]
#         except UnicodeDecodeError:
#             continue
#     raise ValueError(f"Cannot decode file {file_path} with any of the known encodings.")

# def read_file_paths(file_path):
#     # print("Reading file path:", file_path)  # 调试打印
#     try:
#         with open(file_path, 'r', encoding='utf-8') as file:
#             return [line.strip() for line in file]
#     except (IOError, UnicodeDecodeError):
#         # 如果文件无法作为文本文件打开，或者编码不是utf-8，则假定它是直接的路径
#         return [file_path]

def read_file_paths(file_path):
    if file_path.endswith('.txt'):  # 检查是否为文本文件
        try:
            with open(file_path, 'r', encoding='utf-8') as file:
                return [line.strip() for line in file]
        except (IOError, UnicodeDecodeError):
            print(f"Error reading file: {file_path}")
            return []
    else:
        return [file_path]  # 如果不是文本文件，直接返回路径

def is_video_file(file_path):
    video_extensions = ['.mp4', '.avi', '.mov', '.wmv', '.flv']
    return any(file_path.lower().endswith(ext) for ext in video_extensions)

def process_file(file_path, file_type):
    if file_type == 'xls':
        preset_inputs_xls = [
            file_path,  # 输入路径
            'y' # mark
        ]
        execute_process(preset_inputs_xls)

    elif file_type == 'csv':

        # print("Processing CSV file:", file_path)  # 调试打印

        preset_inputs_csv = [
            file_path,  # 输入路径
            'n' # mark
        ]
        execute_process(preset_inputs_csv)

    else:
        preset_inputs = [
            file_path,  # 输入视频路径
            'n',  # 旋转视频
            'n',  # 灰度检测
            'E',  # 输入roi信息
            '629,385', # roi脚点
            '40,137', # roi尺寸
            'y', # 提取放大前
            'n', # darkest mark
            'n', # canny mark
            '5,13,10', # 放大参数
            'n', # darkest mark
        ]
        execute_process(preset_inputs)

        preset_inputs = [
            file_path,  # 输入视频路径
            'n',  # 旋转视频
            'n',  # 灰度检测
            'E',  # 输入roi信息
            '629,385', # roi脚点
            '40,137', # roi尺寸
            'n', # 提取放大前
            # 'n', # darkest mark
            # 'n', # canny mark
            '5,13,15', # 放大参数
            'n', # darkest mark
        ]
        execute_process(preset_inputs)

        preset_inputs = [
            file_path,  # 输入视频路径
            'n',  # 旋转视频
            'n',  # 灰度检测
            'E',  # 输入roi信息
            '629,385', # roi脚点
            '40,137', # roi尺寸
            'n', # 提取放大前
            # 'n', # darkest mark
            # 'n', # canny mark
            '13,22,10', # 放大参数
            'n', # darkest mark
        ]
        execute_process(preset_inputs)

        preset_inputs = [
            file_path,  # 输入视频路径
            'n',  # 旋转视频
            'n',  # 灰度检测
            'E',  # 输入roi信息
            '629,385', # roi脚点
            '40,137', # roi尺寸
            'n', # 提取放大前
            # 'n', # darkest mark
            # 'n', # canny mark
            '13,22,15', # 放大参数
            'n', # darkest mark
        ]
        execute_process(preset_inputs)

def execute_process(preset_inputs):

    # print("Executing process with:", preset_inputs)  # 调试打印

    process = subprocess.Popen(['python', 'main.py'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
    for user_input in preset_inputs:
        process.stdin.write(user_input + '\n')
    process.stdin.close()

    while process.poll() is None:
        output = process.stdout.readline()
        if output:
            print("Output:", output.strip())

# def main():
#     file_paths = []
#     for file_path in sys.argv[1:]:
#         file_paths.extend(read_file_paths(file_path))

#     for path in file_paths:
#         if path.endswith('.xls'):
#             process_file(path, True)
#         elif is_video_file(path):
#             process_file(path, False)

def main():
    # print("Command line arguments:", sys.argv)  # 调试打印
    file_paths = []
    for file_path in sys.argv[1:]:
        file_paths.extend(read_file_paths(file_path))
        # print("Processed file paths:", file_paths)  # 新增的调试打印
    for path in file_paths:
        if path.endswith('.xls'):
            process_file(path, 'xls')
            # print("Processing as XLS")  # 新增的调试打印
        elif path.endswith('.csv'):
            process_file(path, 'csv')
            # print("Processing as CSV")  # 新增的调试打印
        elif is_video_file(path):
            # print("Processing as Video")  # 新增的调试打印
            process_file(path, 'video')

if __name__ == "__main__":
    main()


import sys
input = sys.stdin.readline

a_list, b_list, c_list, d_list = [], [], [], []
N = int(input())

for _ in range(N):
    a, b, c, d = map(int, input().split())
    a_list.append(a)
    b_list.append(b)
    c_list.append(c)
    d_list.append(d)

ab = dict()

for a in a_list:
    for b in b_list:
        ab[a + b] = ab.get(a + b, 0) + 1

answer = 0
for c in c_list:
    for d in d_list:
        answer += ab.get(-(c + d), 0)
print(answer)

백준알고리즘/이분 탐색/python/합이 0인 네 정수.py

합이 0인 네 정수.py


import io
import numpy as np
import cv2

def figure_to_numpy(figure):
    buffer = io.BytesIO()
    figure.savefig(buffer, format='png', dpi=90, bbox_inches='tight')
    buffer.seek(0)
    image = np.frombuffer(buffer.getvalue(), dtype=np.uint8)
    buffer.close()
    image = cv2.imdecode(image, 1)
    return image


# we need to initialize a list which we return in result and a subset for every iteration
# we start with iteration at index 0
# we append nums[i] to subset then we backtrack by incremeneting the index
# we check if the subset is equal to nums the return subset
# then we pop previous set such that we can have ttwo possibilities
# adding a number and not adding a number
class Solution:
    def subsets(self, nums: list[int]) -> list[list[int]]:
        res = []

        subset = []

        def dfs(i):
            if i >= len(nums):
                res.append(subset.copy())
                return
            # decision to include nums[i]
            subset.append(nums[i])
            dfs(i + 1)
            # decision NOT to include nums[i]
            subset.pop()
            dfs(i + 1)

        dfs(0)
        return res


#!/usr/bin/env python
# -*- coding: utf-8 -*-
from setuptools import setup

with open("README.md") as readme_file:
    readme = readme_file.read()

install_requirements = [
    "sceptre>=2.1.2"
]

setup(
    name='sceptre-provisioner-hooks',
    version="1.0.1",
    description="Sceptre hooks to help facilitate the"
                "Sage auto provisioner",
    py_modules=['ec2_notify',
                's3_notify',
                'synapse_bucket_notify',
                's3_web_notify',
                'utils',
                'constants',
                'exceptions',],
    long_description=readme,
    long_description_content_type="text/markdown",
    author="zaro0508",
    author_email="zaro0508@gmail.com",
    license='Apache2',
    url="https://github.com/Sage-Bionetworks/sceptre-provisioner-hooks",
    entry_points={
        'sceptre.hooks': [
            'ec2_notify = '
            'ec2_notify:EC2Notify',
            's3_notify = '
            's3_notify:S3Notify',
            'synapse_bucket_notify = '
            'synapse_bucket_notify:SynapseBucketNotify',
            's3_web_notify = '
            's3_web_notify:S3WebNotify',
        ],
    },
    keywords="sceptre",
    classifiers=[
        "Development Status :: 5 - Production/Stable",
        "Intended Audience :: Developers",
        "Natural Language :: English",
        "Environment :: Console",
        "Programming Language :: Python :: 2.7",
        "Programming Language :: Python :: 3.5",
        "Programming Language :: Python :: 3.6"
    ],
    install_requires=install_requirements,
    include_package_data=True,
    zip_safe=False,
)


import grok
import simplejson as json

from partybuilder import resource
from interfaces import IUser, IParty, ILayout, IUserProfile, IBuilderApp
from zope import component
from oauth2.interfaces import IOAuthSite, IOAuthPrincipalSource
from zope.catalog.interfaces import ICatalog
from zope.schema.fieldproperty import FieldProperty
from zope.session.interfaces import ISession
from zope.authentication.interfaces import IUnauthenticatedPrincipal

class User(grok.Model):
    grok.implements(IUser)
    id = FieldProperty(IUser['id'])
    title = FieldProperty(IUser['title'])
    description = FieldProperty(IUser['description'])
    userno = FieldProperty(IUser['userno'])
    domain = FieldProperty(IUser['domain'])
    login = FieldProperty(IUser['login'])
    secret = FieldProperty(IUser['secret'])
    gw2_apikey = FieldProperty(IUser['gw2_apikey'])
    disco_id = FieldProperty(IUser['disco_id'])

    profile = None
    grok.traversable('profile')

    def __init__(self, userno, id=None):
        self.userno = int(userno)
        self.id = id

class Party(grok.Model):
    grok.implements(IParty)

    def __init__(self, partyno):
        self.partyno = partyno

class Users(grok.Container):
    grok.implements(IUser, ILayout, IOAuthPrincipalSource)
    sequence = 0
    domain = u'PartyBuilder'

    def __init__(self):
        super(Users, self).__init__()
        self.sequence = 0

    def __contains__(self, id):
        return len(self.find(id=id))>0

    def new(self, id):
        seq = str(self.sequence)
        self.sequence += 1
        user = self[seq] = User(seq, id=id)
        return self[seq]

    def find(self, **kw):
        catalog = component.getUtility(ICatalog, name='userindex')
        return catalog.searchResults(**kw)

class PrincipalSourceAdapter(grok.Adapter):
    grok.context(IOAuthSite)
    grok.implements(IOAuthPrincipalSource)

    def __new__(self, context):
        return context['users']

class Parties(grok.Container):
    grok.implements(IParty, ILayout)
    sequence = 0
    def __init__(self):
        super(Parties, self).__init__()
        self.sequence = 0

class Partybuilder(grok.Application, grok.Container):
    grok.implements(ILayout, IOAuthSite, IBuilderApp)

    def __init__(self):
        super(Partybuilder, self).__init__()
        self['users'] = Users()
        self['parties'] = Parties()

class Traverse(grok.Traverser):
    grok.context(Partybuilder)

    def traverse(self, path):

        if path == 'profile':
            if IUnauthenticatedPrincipal.providedBy(self.request.principal):
                return self.context
            else:
                session = ISession(self.request)['OAuth2']
                if 'principal' in session.keys():
                    user = session['principal']
                    return IUserProfile(user)

class UserIndex(grok.Indexes):
    grok.site(Partybuilder)
    grok.context(User)
    grok.name('userindex')

    id = grok.index.Text()  # an internal Principal ID

class Index(grok.View):
    grok.context(ILayout)
    grok.require('zope.Public')

    def update(self):
        resource.bootstrap.need()
        resource.style.need()


import requests, re
from bs4 import BeautifulSoup

def get_id(val):
    url = ("https://www.google.com/search?q="+val+"spotify")
    page = requests.get(url)

    soup = BeautifulSoup(page.content, 'html.parser')
    url = []
    for link in soup.find_all('a'):
        a = link.get('href')
        if a.startswith('/url?q=https://open.spotify.com/artist/'):
            url.append(a)

    data = url[0]
    data = data[7:61]
    md = data.split('/')
    return md[-1]

artist = input('Enter the artist name: ')
x = get_id(artist)
print(x)


import json
import requests
import urllib.request as urllib2

def request(url):
    """
    sends url request
    """

    req = urllib2.Request(url)
    response = urllib2.urlopen(req)

    return response.read().decode()

def getFacebookData(page_id, access_token):
    """
    constructs the URL string
    """

    base = "https://graph.facebook.com/v2.8"
    node = "/" + page_id

    parameters = "?fields=taggable_friends{name}"
    url = base + node + parameters + "&access_token=%s"%access_token
    data = json.loads(request(url))

    return data

def main():
    with open('access_token.txt', 'r') as f:
        access_token = f.readline()

    page_id = 'me'

    friends = getFacebookData(page_id, access_token)['taggable_friends']
    friend_list = []

    while True:
        for friend in friends['data']: friend_list.append(friend['name'])
        try:
            friends = requests.get(friends['paging']['next']).json()
        except KeyError:
            break
    with open('friends.txt', 'a') as f:
        for friend in friend_list: print(friend, file = f)

if __name__ == "__main__":
    main()


import radarsimpy
import numpy as np
from radarsimpy import Radar, Transmitter, Receiver
from radarsimpy.simulator import simc, simpy

from scipy import signal
import radarsimpy.processing as proc
from radarsimpy.processing import doa_music, doa_root_music, doa_esprit

from scipy import linalg
from scipy import fft

import plotly.graph_objects as go
import plotly.io as pio

import json

from targets import *
from plot import *

import logging
import datetime
import time
# import tqdm
from tqdm import tqdm

c= 3e8

############Setup Logging################
path = "logs/"
# Get the current date and time
current_datetime = datetime.datetime.now()
# Generate the log file name with the current date and time
log_filename = current_datetime.strftime(path +"/logfile_%Y-%m-%d_%H-%M-%S.log")
# Configure logging format and level, and use the generated log filename
logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s [%(levelname)s] %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S',
    filename=log_filename,
    filemode='a'
)

def read_config(PATH_to_config = "config.json"):
    # Read the contents of the config.json file
    with open(PATH_to_config, 'r') as f:
        config_data = json.load(f)
    return config_data

def setup_tx(config_data):
    """
    Read about the antenna placement for the TX and RX,
    Currently I can support only 2 TX and any number of RX
    """

    N_rx = config_data["rx_params"]["n_rx"]
    wavelength = c /((config_data["tx_params"]["fc_top"] + config_data["tx_params"]["fc_bot"])/2)

    #Setup Transmitter
    channels = []
    #location is of the form of x, y, z
    #place the two transmitters on the extreme ends of the receivers
    channels.append(
        dict(
            location=(0, -N_rx/2*wavelength/2, 0),
        ))

    channels.append(
        dict(
            location=(0, wavelength*N_rx/2-N_rx/2*wavelength/2, 0),
        ))

    tx = Transmitter(f=[config_data["tx_params"]["fc_top"], config_data["tx_params"]["fc_bot"]],
                     t=[0, config_data["tx_params"]["t_pulse"]],
                     tx_power=config_data["tx_params"]["tx_power"],
                     prp=config_data["tx_params"]["prp"],
                     pulses=config_data["tx_params"]["n_pulses"],
                     channels=channels)
    return tx

def setup_rx(config_data):

    N_rx = config_data["rx_params"]["n_rx"]
    wavelength = c /((config_data["tx_params"]["fc_top"] + config_data["tx_params"]["fc_bot"])/2)

    #setup the Receiver
    channels = []
    for idx in range(0, N_rx):
        channels.append(
            dict(
                location=(0, wavelength/2*idx-(N_rx-1) * wavelength/4, 0),
            ))

    rx = Receiver(fs=config_data["rx_params"]["f_samp"],
              noise_figure=config_data["rx_params"]["noise_figure"],
              rf_gain=config_data["rx_params"]["rf_gain"],
              load_resistor=config_data["rx_params"]["load_resistor"],
              baseband_gain=config_data["rx_params"]["baseband_gain"],
              channels=channels)

    return rx

def range_doppler_proc(radar, baseband):

    range_window = signal.windows.chebwin(radar.samples_per_pulse, at=80)
    doppler_window = signal.windows.chebwin(radar.transmitter.pulses, at=80)

    range_doppler = proc.range_doppler_fft(
        baseband, rwin=range_window, dwin=doppler_window)

    return range_doppler

def find_unique_within_tolerance(arr, tol):
    unique_values = np.unique(arr)
    unique_within_tol = []

    for value in unique_values:
        # Check if the value is not already present in 'unique_within_tol' within the tolerance 'tol'
        if not any(np.isclose(unique_within_tol, value, atol=tol)):
            unique_within_tol.append(value)

    return np.array(unique_within_tol)

def return_unique_range_doppler(radar, config_data, det_ranges, det_vel_wo_direction):
    max_range = (c * radar.receiver.fs *
             radar.transmitter.pulse_length /
             radar.transmitter.bandwidth / 2)
    max_speed = c /radar.transmitter.prp[0] / \
        radar.transmitter.fc_vect[0] / 2

    unique_det_range = find_unique_within_tolerance(det_ranges, tol = config_data["hyper_params"]["range_tol"]*max_range/radar.transmitter.pulses )
    # print("radial_distance",unique_det_range)

    unique_det_indices = np.ones((len(unique_det_range)), dtype = int)
    for i in range(0, len(unique_det_range)):
        unique_det_indices[i]= int(np.median(np.where(det_ranges == unique_det_range[i])[0]))

    unique_det_dop_wo_dir = det_vel_wo_direction[unique_det_indices]

    unique_det_dop_w_dir = np.zeros((len(unique_det_dop_wo_dir)))
    for i in range(0, len(unique_det_dop_wo_dir)):
        if(unique_det_dop_wo_dir[i] < -0.5*max_speed):
            unique_det_dop_w_dir[i] = (unique_det_dop_wo_dir[i] + max_speed)
        else:
            unique_det_dop_w_dir[i] = (unique_det_dop_wo_dir[i])

    return unique_det_range, unique_det_dop_w_dir, unique_det_dop_wo_dir

def peakdet_and_convmat(config_data, radar, range_doppler):

    N_rx = config_data["rx_params"]["n_rx"]
    N_tx = config_data["tx_params"]["n_tx"]

    '''
    Peak detection algorithm
    Range doppler has the dimensions
    [channels, Doppler, range]
    '''
    # peaks, _ = signal.find_peaks(range_doppler, height=config_data["hyper_params"]["peak_thresh"])
    # print(peaks)
    # exit()
    range_doppler_map = 20*np.log10(np.mean(np.abs(range_doppler), axis=0))
    doppler_ind, range_ind = np.where(range_doppler_map > config_data["hyper_params"]["peak_thresh"] )

    """
    Map to range velocity and then we get back
    """

    max_range = (c * radar.receiver.fs *
             radar.transmitter.pulse_length /
             radar.transmitter.bandwidth / 2)
    max_speed = c /radar.transmitter.prp[0] / \
        radar.transmitter.fc_vect[0] / 2

    det_ranges = -1*np.interp(range_ind, [0, radar.samples_per_pulse],[-1*max_range, 0])
    det_vel_wo_direction = np.interp(doppler_ind, [0, radar.transmitter.pulses], [-1*max_speed, 0])
    # print(det_ranges)
    # print(det_vel_wo_direction)

    unique_det_range, unique_det_dop_w_dir, unique_det_dop_wo_dir = return_unique_range_doppler(radar, config_data, det_ranges, det_vel_wo_direction)
    # print("radial_distance",unique_det_range)
    # print("velocity", unique_det_dop_w_dir)

    det_ranges_ind = range_ind
    det_vel_dir_ind = doppler_ind
    # print(det_ranges_ind)
    # print(det_vel_dir_ind)
    # det_ranges_ind = np.interp(-1*unique_det_range, [-1*max_range, 0], [0, radar.samples_per_pulse])
    # det_vel_dir_ind = np.interp(unique_det_dop_wo_dir, [-1*max_speed, 0], [0, radar.transmitter.pulses])
    # print(range_ind, doppler_ind)
    # exit()
    # det_ranges_ind = range_ind

    '''
    The dimension of range_ind and doppler_ind is the same as the number of target.
    We will iterate through all the targets create the covariance matrix based on the
    Ns observation snapshots
    '''

    bv_all = []

    for i in range(0, len(det_ranges_ind)):
        bv =range_doppler[:,int(det_vel_dir_ind[i]),int(det_ranges_ind[i])]
        bv = bv/linalg.norm(bv)
        bv_all.append(bv)
    bv_all_np = np.array(bv_all)
    bv_all_music = bv_all_np.T
    cov_mat = np.cov(bv_all_music.conjugate())

    # scan_angle = np.arange(-90, 90, 0.1)
    # music_doa, music_idx, ps_db = doa_music(cov_mat, config_data["target"]["num_target"], scanangles=scan_angle)

    return cov_mat, unique_det_range, unique_det_dop_w_dir

def run_sim(config_data, logging):
    # start_time = time.time()

    radar = Radar(transmitter = setup_tx(config_data), receiver = setup_rx(config_data))

    num_epoch = config_data["run_params"]["run_itr"]
    # print(num_epoch)

    for i in tqdm(range(num_epoch)):

        range_arr, angle_arr, speed_arr, targets = get_targets(radar, config_data, logging)
        # print(ranges, angles, speed)
        # exit()
        # print("############Starting Simulator##############")
        # bb_data = simpy(radar, targets, noise=True)
        bb_data = simc(radar, targets, noise=True)
        time_matrix = bb_data['timestamp']
        baseband = bb_data['baseband']
        # print("###########End simulator###################")

        range_doppler = range_doppler_proc(radar, baseband)
        # plot_range_doppler(radar, range_doppler)

        #########################Different DoA Estimators#################################################

        #Find the beam vector of the peak and create covariance matrix for DoA
        # covmat = peakdet_and_convmat(config_data, radar, range_doppler)
        cov_mat, unique_det_range, unique_det_dop_w_dir = peakdet_and_convmat(config_data, radar, range_doppler)
        # plot_peaks(range_doppler)

        logging.info("radial_distance" + str(unique_det_range))
        logging.info("velocity"+ str(unique_det_dop_w_dir))

        scan_angle = np.arange(-90, 90, 0.1)
        music_doa, music_idx, ps_db = doa_music(cov_mat, config_data["target"]["num_target"], scanangles=scan_angle)

        logging.info('DoAs from MUSIC:'+ str(music_doa) + 'degrees')

        # rootmusic_doa = doa_root_music(cov_mat, config_data["target"]["num_target"])
        # logging.info('DoAs from root MUSIC:'+ str(rootmusic_doa) + 'degrees')

        # esprit_doa = doa_esprit(cov_mat, config_data["target"]["num_target"])
        # logging.info('DoAs from ESPRIT:'+ str(esprit_doa) + 'degrees')

        """
        Save the results:
        We would be saving the the target info
        range doppler np array --> It is very big so don't save now
        and covariance matrix np array
        """

        # np.savez(config_data["run_params"]["save_path"]+"/epoch_test.npz", arr1 = range_arr, arr2 = speed_arr,
                #  arr3 = angle_arr, arr4 = range_doppler, arr5 = cov_mat)
        # print(range_arr, angle_arr, speed_arr)
        # print(cov_mat.shape)
        np.savez(config_data["run_params"]["save_path"]+"/epoch_"+str(i)+".npz", range = range_arr, speed = speed_arr,
                 angle = angle_arr, cov_mat = cov_mat)

        # end_time = time.time()
        # print("Execution Time", end_time - start_time )

def main():

    config_data = read_config()

    #dump configs to logging
    logging.info(config_data)
    run_sim(config_data, logging)

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


import datetime
import unittest

try:
    from unittest import mock
except ImportError:
    import mock

from webapp.src.proto import model
from webapp.src.tasks import removing_outdated_devices
from webapp.src.testing import unittest_base

class RemoveOutdatedDevicesTest(unittest_base.UnitTestBase):
    """Tests for RemoveOutdatedDevices cron class.

    Attributes:
        remove_outdated_device: A mock device_heartbeat.RemoveOutdatedDevices
                                instance.
    """

    def setUp(self):
        """Initializes test"""
        super(RemoveOutdatedDevicesTest, self).setUp()
        # Mocking RemoveOutdatedDevices and essential methods.
        self.remove_outdated_device = (
            removing_outdated_devices.RemoveOutdatedDevices(mock.Mock()))
        self.remove_outdated_device.response = mock.Mock()
        self.remove_outdated_device.response.write = mock.Mock()

    def testRemoveOutdatedDevicesTest(self):
        """Asserts job heartbeat detects unavailable jobs."""
        device_a_serial = "a"
        device_b_serial = "b"
        device_c_serial = "c"
        device_d_serial = "c"

        # create a device A, which is outdated.
        device = self.GenerateDeviceModel(serial=device_a_serial)
        device.timestamp = datetime.datetime.now() - datetime.timedelta(
            hours=100)
        device.put()

        # create a device B, which is offline for a day.
        device = self.GenerateDeviceModel(serial=device_b_serial)
        device.timestamp = datetime.datetime.now() - datetime.timedelta(
            hours=24)
        device.put()

        # create a device C and D, which are alive.
        for serial in [device_c_serial, device_d_serial]:
            device = self.GenerateDeviceModel(serial=serial)
            device.timestamp = datetime.datetime.now()
            device.put()

        # Remove outdated devices.
        self.remove_outdated_device.get()

        devices = model.DeviceModel.query().fetch()

        # device A should not be included.
        self.assertEqual(len(devices), 3)
        self.assertTrue(device_a_serial not in [x.serial for x in devices])

        # change devices' timestamp
        for device in devices:
            device.timestamp = device.timestamp - datetime.timedelta(hours=25)
            device.put()

        # Remove outdated devices.
        self.remove_outdated_device.get()

        devices = model.DeviceModel.query().fetch()

        # Now device B should not be included also.
        self.assertEqual(len(devices), 2)
        self.assertTrue(device_b_serial not in [x.serial for x in devices])

        # change devices' timestamp
        for device in devices:
            device.timestamp = device.timestamp - datetime.timedelta(hours=25)
            device.put()

        # Remove outdated devices.
        self.remove_outdated_device.get()

        devices = model.DeviceModel.query().fetch()

        # Now there should not be no devices.
        self.assertEqual(len(devices), 0)

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