import asyncio
import logging
import os
import re
from datetime import datetime, date
from weakref import WeakValueDictionary
from aiogram import Bot
from vk_api import vk_api
from VK import VKDatabase
from Twitch import twitch_link

class VKGroup:
    # Ссылка на страницу группы в ВК
    vk_group_link: str = "https://vk.com/official_group_by_wycc220"

    # Идентификатор группы в ВК
    vk_group_id: str = os.environ["VK_GROUP_ID"]

    # Паттерны для поиска анонсов
    vk_wall_patterns: list = [
        re.compile(u"подруб"),
        re.compile(u"стрим"),
        re.compile(u"анонс"),
        re.compile("twitch")
    ]

    # Временный буфер постов, чтобы не проверять их наличие в БД.
    vk_posts_buffer: list = []

    # Доступ к сессии VK
    vk_session: vk_api.VkApiMethod = vk_api.VkApi(token=os.environ["VK_TOKEN"]).get_api()

    @classmethod
    async def get_wall_announces(cls, amount: int = 5) -> list:
        """
        Метод для получения списка последних анонсов со стены группы ВК.
        :param amount: Количество последних анонсов со стены.
        :return list: Список с полученными анонсами.
        """
        # Ограничение, чтобы нельзя было вернуть более 5 последних постов.
        amount = min(amount, 5)

        # Список анонсов, который будет возвращён.
        announces: list = []

        # Вернуть список последних постов в группе
        posts: WeakValueDictionary = cls.vk_session.wall.get(owner_id=cls.vk_group_id, count=amount)

        # Собрать нужные посты из группы ВК
        for post in posts["items"]:
            post_id: str = post["id"]
            post_text: str = re.sub("\n", " ", post["text"].strip())
            post_timestamp: float = post["date"]

            patterns: list = list(filter(lambda pattern: re.search(pattern, post_text.lower()), cls.vk_wall_patterns))
            if patterns:
                announces.append({
                    "post_id": post_id,
                    "post_text": post_text,
                    "post_date": datetime.fromtimestamp(post_timestamp)
                })

        return announces
        # noqa

    @classmethod
    async def get_new_activities(cls, amount: int = 5) -> list:
        """
        Получить список последней активности с анонсами на стене ВК.
        :param amount: Максимальное количество анонсов.
        :return: Лист с актуальными анонсами.
        """
        # Полночь по Минску
        midnight: datetime = datetime.combine(date.today(), datetime.min.time())

        # Итоговый список анонсов
        activities = []

        # Найти последние 5 анонсов
        posts: list = await cls.get_wall_announces(amount)

        # Получить из анонсов ID всех подходящих постов, если их нет в буфере
        # Это исключает необходимость постоянных запросов к БД, если пост уже есть в памяти
        post_ids = [post.get("post_id") for post in posts if post.get("post_id") not in cls.vk_posts_buffer]

        # Если вообще посты не найдены, то просто отправить пустой лист.
        if not post_ids:
            return activities

        # Найти список этих постов в базе данных.
        posts_from_database: dict = await VKDatabase.find_posts_by_id(post_ids)

        for post in posts:
            post_id = post.get("post_id")
            post_date = post.get("post_date")

            # Если пост не в базе данных и дата больше, чем полночь
            if post_id not in posts_from_database and post_date >= midnight:
                # То вставить пост в базу данных и список активностей
                await VKDatabase.insert_post(post_id, post_date)
                activities.append(post)
                if post_id not in cls.vk_posts_buffer:
                    cls.vk_posts_buffer.append(post_id)

        return activities
        # noqa

    @staticmethod
    async def notify_activities(bot: Bot, interval: int = 300):
        """
        Отправить уведомление о новых анонсах в группу Телеграм.
        :param bot: API бота Телеграм.
        :param interval: Интервал до следующей проверки.
        :return:
        """

        while True:
            try:
                announces = await VKGroup.get_new_activities()
                for announce in announces:
                    text = announce.get("post_text")
                    # Если в посте нет ссылки на твич, то добавить её.
                    text = text if re.search("twitch", text) else f"{text}\n{twitch_link}"

                    await bot.send_message(os.environ["TG_GROUP_ID"], f"\n{text}")
            except Exception as ex:
                logging.error(f"ОШИБКА: {ex}")

            await asyncio.sleep(interval)


"""

file ：函数 全局变量和局部变量.py
date :2021.03.21
author :Lucky
desc :

"""

total = 0  # 在这里的total1是一个全局变量

# 可写函数说明
def sum(arg1, arg2):
    """返回2个参数的和"""
    total = arg1 + arg2  # 在这里的total1是局部变量
    print("函数内是局部变量:", total)
    return total

# 调用sum函数
sum(10, 20)
print("函数外是全局变量:", total)

函数 全局变量和局部变量.py

函数 全局变量和局部变量.py


from django import template

register = template.Library()

censored_word = ["образование"]

@register.filter()
def censor(value):
    for word in censored_word:
        if word.lower() in value.lower():
            value = value.replace(word[2:], '*' * len(word))
    return value


#!/usr/bin/python3
"""island_perimeter method and it's dependencies"""

def island_perimeter(grid):
    """Calculates the perimeter of a grid based on given rules"""

    perim = 0
    for x in range(len(grid)):
        for y in range(len(grid[x])):
            if grid[x][y] == 1:
                if x + 1 >= len(grid) or grid[x + 1][y] == 0:
                    perim += 1
                if x - 1 < 0 or grid[x - 1][y] == 0:
                    perim += 1
                if y + 1 >= len(grid[x]) or grid[x][y + 1] == 0:
                    perim += 1
                if y - 1 < 0 or grid[x][y - 1] == 0:
                    perim += 1
    return (perim)


import math

from .blueprint import *
from .prototype_loader import recipes

def add_single_am3_module(entities:list, x, y, recipe_name, request_filter_list, output_passive_provider_bar,
                          am_direction=Direction.NORTH, machine_name="assembling-machine-3",
                          input_inserter="fast-inserter", output_inserter="fast-inserter",
                          items=None, power_pole=True):
    entities.extend([
        Entity(machine_name, Position(x, y), recipe=recipe_name, direction=am_direction, items=items),
        Entity(input_inserter, Position(x - 1, y - 2), direction=Direction.NORTH),
        Entity("logistic-chest-requester", Position(x - 1, y - 3),
               request_filter_list=request_filter_list
        ),
        Entity(output_inserter, Position(x + 1, y - 2), direction=Direction.SOUTH),
        Entity("logistic-chest-passive-provider", Position(x + 1, y - 3), bar=output_passive_provider_bar),
    ])

    if power_pole:
        entities.append(Entity("medium-electric-pole", Position(x, y - 2)))

def add_single_am3_unbarreler(entities:list, x, y, recipe_name, request_filter_list, direction):
    entities.extend([
        Entity("assembling-machine-3", Position(x, y), recipe=recipe_name, direction=direction),
        Entity("fast-inserter", Position(x - 1, y - 2), direction=Direction.NORTH),
        Entity("logistic-chest-requester", Position(x - 1, y - 3),
               request_filter_list=request_filter_list
        ),
        Entity("fast-inserter", Position(x + 1, y - 2), direction=Direction.SOUTH),
        Entity("logistic-chest-active-provider", Position(x + 1, y - 3)),
        # Entity("medium-electric-pole", Position(x, y - 2))
    ])

def add_single_am3_liquid_module(entities: list, x, y, recipe_name, request_filter_list,
                                 unbarrel_recipe_name, unbarreler_request_filter_list, output_passive_provider_bar,
                                 input_inserter=None, output_inserter=None, items=None):

    add_single_am3_module(entities, x, y, recipe_name, request_filter_list, output_passive_provider_bar, Direction.EAST,
                          input_inserter=input_inserter, output_inserter=output_inserter, items=items)
    add_single_am3_unbarreler(entities, x + 3, y, unbarrel_recipe_name, unbarreler_request_filter_list, Direction.EAST)

def add_single_speed_beacon(entities:list, x, y):
    entities.append(
        Entity("beacon", Position(x, y), items={"speed-module-3": 2})
    )

def assembler_liquid(prod_node):
    for ingredient in prod_node['ingredients']:
        if ingredient['item_type'] == 'fluid':
            return ingredient
    return None

def count_machines(prod_list:list):

    assembler_furnace_count = 0
    for prod_node in prod_list:

        if prod_node['machine_name'] == 'assembling-machine-3' or prod_node['machine_name'] == 'electric-furnace':
            machine_amount = math.ceil(round(prod_node['machine_amount'], 2))
            if assembler_liquid(prod_node) == None:
                assembler_furnace_count += machine_amount
            else:
                assembler_furnace_count += machine_amount * 2

    return assembler_furnace_count

def generate(prod_list:list):

    total_assemblers_placed = 0
    total_assemblers = count_machines(prod_list)

    machines_per_row = round(math.sqrt(total_assemblers) * math.sqrt(5/3))

    entities = []

    prod_node_index = 0
    i = 0
    j = 0

    node_assemblers_placed = 0
    while total_assemblers_placed < total_assemblers:
        if j >= machines_per_row:
            i += 1
            j = 0

        prod_node = prod_list[prod_node_index]
        prod_node_machine_amount = math.ceil(round(prod_node['machine_amount'], 2))

        requester_filter_list = []
        barreler_filter_list = []
        for ingr in prod_node['ingredients']:
            if ingr['item_type'] == 'item':
                requester_filter_list.append(Logistic_Filter(ingr['item_name'], (ingr['item_rate']/prod_node_machine_amount) * 50))
            else:
                barreler_filter_list.append(Logistic_Filter(ingr['item_name'] + '-barrel', (ingr['item_rate']/prod_node_machine_amount)*2))

        if len(barreler_filter_list) == 0:
            add_single_am3_module(entities, j*3, i*5, prod_node['recipe_name'], requester_filter_list,
                                  1, machine_name=prod_node['machine_name'], input_inserter=prod_node["input_inserter"],
                                  output_inserter=prod_node["output_inserter"], power_pole=(j % 2 == 0 or j == (machines_per_row - 1)))
            j += 1
            total_assemblers_placed += 1
        elif len(barreler_filter_list) == 1:
            add_single_am3_liquid_module(entities, j*3, i*5, prod_node['recipe_name'], requester_filter_list,
                                         'empty-' + ingr['item_name'] + '-barrel', barreler_filter_list, 1)
            j += 2
            total_assemblers_placed += 2
        else:
            raise NotImplementedError

        node_assemblers_placed += 1
        if node_assemblers_placed >= prod_node_machine_amount:
            prod_node_index += 1
            node_assemblers_placed = 0

    return Blueprint.to_dict(Blueprint(entities))

def generate_with_beacons(prod_list:list):
    def calc_machines_per_row(total_assemblers:int)->int:
        a = round(math.sqrt(total_assemblers) * (0.5))
        machines_per_column = a if a <= 5 else 5
        machines_per_row = math.ceil(total_assemblers / machines_per_column)
        return machines_per_row, machines_per_column

    def generate_beacons(entities, x_start, y_start, beacons_width, beacons_height):
        for i in range(0, beacons_height):
            for j in range(0, beacons_width):
                add_single_speed_beacon(entities, x_start + j*3, y_start + i * 8)

    total_assemblers_placed = 0
    total_assemblers = count_machines(prod_list)

    machines_per_row, machines_per_column = calc_machines_per_row(total_assemblers)
    beacons_per_row = machines_per_row + 3

    entities = []
    generate_beacons(entities, -4, -5, beacons_per_row, machines_per_column + 1)

    prod_node_index = 0
    i = 0
    j = 0

    node_assemblers_placed = 0
    while total_assemblers_placed < total_assemblers:
        if j >= machines_per_row:
            i += 1
            j = 0

        prod_node = prod_list[prod_node_index]
        prod_node_machine_amount = math.ceil(round(prod_node['machine_amount'], 2))

        requester_filter_list = []
        barreler_filter_list = []
        for ingr in prod_node['ingredients']:
            if ingr['item_type'] == 'item':
                requester_filter_list.append(Logistic_Filter(ingr['item_name'], math.ceil(ingr['item_rate']/prod_node_machine_amount) * 12))
            else:
                barreler_filter_list.append(Logistic_Filter(ingr['item_name'] + '-barrel', math.ceil(ingr['item_rate']/prod_node_machine_amount) * 2))

        if len(barreler_filter_list) == 0:
            add_single_am3_module(entities, j*3, i*8, prod_node['recipe_name'], requester_filter_list,
                                  1, machine_name=prod_node['machine_name'], input_inserter=prod_node["input_inserter"],
                                  output_inserter=prod_node["output_inserter"], items=prod_node['machine_modules'],
                                  power_pole=(j % 2 == 0 or j == (machines_per_row - 1)))
            j += 1
            total_assemblers_placed += 1
        elif len(barreler_filter_list) == 1:
            add_single_am3_liquid_module(entities, j*3, i*8, prod_node['recipe_name'], requester_filter_list,
                                         'empty-' + ingr['item_name'] + '-barrel', barreler_filter_list, 1,
                                         input_inserter=prod_node['input_inserter'], output_inserter=prod_node['output_inserter'],
                                         items=prod_node['machine_modules'])
            j += 2
            total_assemblers_placed += 2
        else:
            raise NotImplementedError

        node_assemblers_placed += 1
        if node_assemblers_placed >= prod_node_machine_amount:
            prod_node_index += 1
            node_assemblers_placed = 0

    return Blueprint.to_dict(Blueprint(entities))


import os,argparse
from Bio import SeqIO
import gzip
import itertools

#os.chdir("/Users/zoliq/ownCloud/progs/PYTHON/mydata")
"""
prefixes = [x for x in os.listdir("./alignments") if x.endswith(".ali")]
#prefixes = ["PF00134_rp75", "PF02984_rp75"]
for prefix in prefixes:
	#os.system("hmmbuild {0}.hmm {0}.ali".format(prefix))
	os.system("hmmsearch -o {0}.result.txt --notextw --tblout {0}.table.txt --cpu 2 {0}.hmm hmmdb.fa".format(prefix, prefix))
"""

def make_clade_set(infilelist):
	"""Compares a subset of the MATOU database that contains unigenes with the given Pfam

	Input:		TSV with seqIDs (number-only) in the first column

	Returns:	Subset of infile contained in a seqID set

	"""
	if isinstance(infilelist, str):
		infilelist = infilelist.split(",")
	clade_set = set()
	for infile in infilelist:
		with open(infile, "rt") as f:
			for x in f:
				seqid = x.split("\t")[0]
				if seqid in hmmids_nt:
					clade_set.add(seqid)

	return clade_set

# def hmm_hits(genefile):
# 	#provide a set of all hmmer hits
# 	if genefile == "batch":
# 		files = [x for x in os.listdir(".") if x.endswith("table.txt")]
# 	else:
# 		files = genefile.split(",")
# 	files.sort()
# 	hmmids_nt = set()
# 	for file in files:
# 		with open(file) as f:
# 			for line in f:
# 				if "inclusion threshold" in line or "Domain annotation" in line:
# 					print("HMMER inclusion threshold reached, wrapping up...")
# 					break
# 				line = line.split()
# 				if len(line) < 9:
# 					continue
# 				if  line[0] != "#":
# 					item = line[8]
# 					if not item.startswith("MATOU"):
# 						print("Problem with line", " ".join(line))
# 					#modify item so that prodigal appendix is removed ==> gene ID
# 					#item = item[:item.rfind("_")]
# 					hmmids_nt.add(item)
#
# 	return hmmids_nt

def hmm_hits_thresholded(genefile):
	"""Provides a set of thresholded hmmer hits;
	Expects one file from function "occurrence" but can work with multiple,
	e.g. to process entire pathways.

	Input		List of files as a ","-separated string

	Returns 	Set of seqIDs from HMMER hmmids_nt_filtered.

	"""
	if genefile == "batch":
		files = [x for x in os.listdir(".") if x.endswith("table.txt")]
	else:
		files = genefile.split(",")
	files.sort()
	multidomain = set()
	written = {} #move multidomain, written into the for loop to have domain-specific files
	for file in files:
		with open(file) as infile:
			for line in infile:
				if "inclusion threshold" in line or "Domain annotation" in line:
					print("HMMER inclusion threshold reached, wrapping up...")
					break
				line = line.split()
				if len(line) < 9:
					continue
				if  line[0] != "#":
					try:
						evalue = float(line[0])
						#seqname = line[8][:line[8].rfind("_")] #trim the prodigal appendix
						seqname = line[8].split("_")[1] #extract raw seqID
						#print(seqname)
						if seqname in written:
							pass
						elif evalue < 1: #which is the usual case for hits above inclusion threshold
							written[seqname] = line[8]
							multidomain.add(seqname)
						elif seqname in multidomain: #another weak domain found in the same seq
							written[seqname] = line[8]
						else: #when there is a weak domain in the target
							multidomain.add(seqname)
					except ValueError:
						pass
						#this is not a score table line
	return written

def writeseqs(fastadb, genefile, lineagefile):
	"""Writes a subset of MATOU database that were found as HMM hits

	Input:		List of SeqIDs

	Returns:	Writes a file

	"""
	#prepare a file list
	if genefile == "batch":
		files = [x for x in os.listdir(".") if x.endswith("table.txt")]
	else:
		files = genefile.split(",")
	files.sort()
	print("Files to be processed", ", ".join(files))

	global hmmids_nt
	hmmids_nt = hmm_hits_thresholded(genefile)
	if lineagefile != "":
		lineage_subset = make_clade_set(lineagefile)
		if len(lineage_subset) > 0:
			hmmids_nt_filtered = { x: hmmids_nt[x] for x in hmmids_nt.keys() if x in lineage_subset }
	else:
		hmmids_nt_filtered = hmmids_nt
	hmmids_aa = set(hmmids_nt_filtered.values())
	print(type(hmmids_aa))

	print("Total of {} hits found".format(len(hmmids_nt)))
	if lineagefile != "":
		print("Filtered hits: {}".format(len(hmmids_nt_filtered)))
	print("Examples:", [x for x in itertools.islice(hmmids_nt_filtered, 10)])
	print("Example seqids:", [x for x in itertools.islice(hmmids_aa, 10)])

	#filter seqs identified as hits
	print("Now to extract sequences from db file", fastadb)
	if len(files) == 1:
		#single file mode
		file = files[0]
		print("Processing for FASTA extraction:", file)
		outname = file.replace(".table.txt", "-dbhits.fasta")
		with open(file) as infile, open(outname, "w") as result:
			if fastadb.split(".")[-1] in ("fasta", "fas", "faa"):
				fastafile = SeqIO.parse(fastadb, "fasta")
				for seq in fastafile:
					if seq.name in hmmids_aa:
						result.write(">{}\n{}\n".format(seq.name, str(seq.seq).replace("*", "")))
			elif fastadb.endswith("gz"):
				with gzip.open(fastadb, "rt") as unzipped:
					for seq in SeqIO.parse(unzipped, "fasta"):
						if seq.name in hmmids_aa:
							result.write(">{}\n{}\n".format(seq.name, str(seq.seq).replace("*", "")))
			else:
				quit("fasta database invalid format")

	else:
		seq_d = {}
		print("Warning, script will run silently for a long time!")
		if fastadb.split(".")[-1] in ("fasta", "fas", "faa"):
			fastafile = SeqIO.parse(fastadb, "fasta")
			for seq in fastafile:
				if seq.name in hmmids_aa:
					seq_d[seq.name] = str(seq.seq).replace("*", "")
		elif fastadb.endswith("gz"):
			with gzip.open(fastadb, "rt") as fastafile:
				for seq in SeqIO.parse(fastafile, "fasta"):
					if seq.name in hmmids_aa:
						seq_d[seq.name] = str(seq.seq).replace("*", "")
		else:
			quit("fasta database invalid format")
		print("Total of {} sequences matched hits".format(len(seq_d.keys())))

		#filter results and export fasta
		for file in files:
			print("Processing for FASTA extraction:", file)
			multidomain = set()
			written = set() #move multidomain, written into the for loop to have domain-specific files
			name = file.replace(".table.txt", "-dbhits.fasta")
			with open(file) as infile, open(name, "w") as result:
				for line in infile:
					if "inclusion threshold" in line or "Domain annotation" in line:
						print("HMMER inclusion threshold reached, wrapping up...")
						break
					line = line.split()
					if len(line) < 9:
						continue
					if  line[0] != "#":
						#seqnames match between prodigal faa and hmmer hit hmmids_aa
						seqname = line[8]
						if seqname in hmmids_aa:
							result.write(">{}\n{}\n".format(seqname, seq_d[seqname]))
	print("Sequence extraction finished!")

def main():
	parser = argparse.ArgumentParser(description='How to use argparse')
	parser.add_argument('-f', '--infile', help='Fasta database file to process', default='/mnt/mokosz/home/zoli/proj/MATOU/MATOU-v1.prodigal.faa.gz')
	parser.add_argument('-l', '--lineage', help='Lineage filter', default='')
	parser.add_argument('-d', '--directory', help='Workdirectory', default='.')
	parser.add_argument('-g', '--genefile', help='Gene file', default='batch')
	parser.add_argument('-e', '--export_hits', help='Write HMMER hits as fasta', action='store_true')

	args = parser.parse_args()
	if args.directory != ".":
		os.chdir(args.directory)
	if args.export_hits:
		writeseqs(args.infile, args.genefile, args.lineage)

if __name__ == '__main__':
	main()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Nov 23 11:51:16 2021

@author: michaeltown
"""

# NWAC data EDA analysis of the Heather Meadows and Pan Dome data

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

import os
import datetime as dt

def seasonFilter(x):

    if (x > 11) | (x < 3):
        return 'djf';
    elif (x >2) & (x <6 ):
        return 'mam';
    elif (x >5) & (x < 9):
        return 'jja';
    elif (x >8) & (x <12 ):
        return 'son';
    else:
        print('I do not recognize that month value. Returning NaN.');
        return np.nan;

# function to convert degF to degC
def convertFtoC(tf):
    return (tf-32)*5/9;

# function to convert mph to m/s
def convertwsMPHtoMS(ws):
    return ws*0.44704;

# function to convert in to mm
def convertprecipIntomm(p):
    return p*25.4;

def myHistFunc(x,ra,xll,xlu,yll,ylu,title,xlab,ylab,fileloc,filename):
    fig1 = plt.figure();
    plt.hist(x,bins = ra,color = 'blue',alpha = 0.5, density = True);
    plt.xlim([xll,xlu]);
    plt.ylim([yll,ylu]);
    plt.title(title);
    plt.ylabel(ylab);
    plt.xlabel(xlab);
    plt.text((xlu-xll)*2/3+xll,(ylu-yll)/2+yll,'n = '+str(len(x)));
    plt.text((xlu-xll)*2/3+xll,(ylu-yll)/2+yll-(ylu-yll)/10,'mean = '+str(np.round(np.mean(x),2)));
    plt.text((xlu-xll)*2/3+xll,(ylu-yll)/2+yll-2*(ylu-yll)/10,'stdev = '+str(np.round(np.std(x),2)));
    os.chdir(fileloc)
    fig1.savefig(filename+'.jpg')

# load the data framces
os.chdir('/home/michaeltown/work/metis/modules/linearRegressionWebScraping/data/');

pdDF = pd.read_csv('MtBaker-PanDome2014-2021.csv');
hmDF = pd.read_csv('MtBaker-HeatherMeadows2014-2021.csv');

# strip all columns of spaces and make all letters lowercase

pdDF.columns = pdDF.columns.str.replace(' ','').str.lower().str.replace('/','').str.replace('(','').str.replace(')','').str.replace(')','').str.replace('%','').str.replace('"','').str.replace('.','');
hmDF.columns = hmDF.columns.str.replace(' ','').str.lower().str.replace('/','').str.replace('(','').str.replace(')','').str.replace(')','').str.replace('%','').str.replace('"','').str.replace('.','');

# convert to pandas date/time
pdDF.datetimepst = pd.to_datetime(pdDF.datetimepst);
hmDF.datetimepst = pd.to_datetime(hmDF.datetimepst);

# prep the time series for daily, monthly, and seasonal composites - some conversions to SI units
pdDF['date'] = pd.to_datetime(pdDF.datetimepst.dt.date);
pdDF['month'] = pdDF.datetimepst.dt.month;
pdDF['year'] = pdDF.datetimepst.dt.year;
pdDF['season'] = pdDF.month.apply(seasonFilter);
pdDF['Tc'] = pdDF.temperaturedegf.apply(convertFtoC);
pdDF['precipitation'] = pdDF.precipitation.apply(convertprecipIntomm);
pdDF['wsAvgMs'] = pdDF.windspeedaveragemph.apply(convertwsMPHtoMS);
pdDF['wsMinMs'] = pdDF.windspeedminimummph.apply(convertwsMPHtoMS);
pdDF['wsMaxMs'] = pdDF.windspeedmaximummph.apply(convertwsMPHtoMS);

hmDF['date'] = pd.to_datetime(hmDF.datetimepst.dt.date);
hmDF['month'] = hmDF.datetimepst.dt.month;
hmDF['year'] = hmDF.datetimepst.dt.year;
hmDF['season'] = hmDF.month.apply(seasonFilter);
hmDF['Tc'] = hmDF.temperaturedegf.apply(convertFtoC);
hmDF['precipitation'] = hmDF.precipitation.apply(convertprecipIntomm);
hmDF['wsAvgMs'] = hmDF.windspeedaveragemph.apply(convertwsMPHtoMS);
hmDF['wsMinMs'] = hmDF.windspeedminimummph.apply(convertwsMPHtoMS);
hmDF['wsMaxMs'] = hmDF.windspeedmaximummph.apply(convertwsMPHtoMS);

# TODO in this space, please drop all the unnecessary columns

# plot the initial EDA histograms
fileLoc = '/home/michaeltown/work/metis/modules/linearRegressionWebScraping/figures/nwacFigures/';
myHistFunc(pdDF.Tc,range(-50,50,1),-50,50,0,0.15,'Temperature for Pan Dome, 5020 ft, Mt. Baker (2014-2021)','Temperature ($^\circ$C)'
           ,'Fraction',fileLoc,'Tc_panDomeMtBakerhist_2014-2021');

myHistFunc(pdDF.wsAvgMs,range(-2,30,1),-2,30,0,0.3,'Wind Speed for Pan Dome, 5020 ft, Mt. Baker (2014-2021)','Wind Speed (m/s)'
           ,'Fraction',fileLoc,'wsAvg_panDomeMtBakerhist_2014-2021');

myHistFunc(pdDF.winddirectiondeg,range(-0,361,1),-5,365,0,0.01,'WDir for Pan Dome, 5020 ft, Mt. Baker (2014-2021)','Wind Dir (deg)'
           ,'Fraction',fileLoc,'wdir_panDomeMtBakerhist_2014-2021');

# heather meadows
myHistFunc(hmDF.Tc,range(-50,50,1),-50,50,0,0.15,'Temperature for Heather Meadows, 4210 ft, Mt. Baker (2014-2021)','Temperature ($^\circ$C)'
           ,'Fraction',fileLoc,'Tc_heatherMeadowsMtBakerhist_2014-2021');

myHistFunc(hmDF.precipitation,np.arange(0,10,1),0,10,0,1,'Precip for Heather Meadows, 4210 ft, Mt. Baker (2014-2021)','Precip (mm)'
           ,'Fraction',fileLoc,'Precip_heatherMeadowsMtBakerhist_2014-2021');

#
#myHistFunc(pdDF.wsAvgMs,range(-2,30,1),-2,30,0,0.3,'Wind Speed for Heather Meadows, 4210 ft, Mt. Baker (2014-2021)','Wind Speed (m/s)'
#           ,'Fraction',fileLoc,'wsAvg_heatherMeadowsMtBakerhist_2014-2021');

# yearsNWAC = range(2014,2022,1);
months = range(1,13,1);
monthListH = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
monthList = ['01','02','03','04','05','06','07','08','09','10','11','12'];
monDictH = dict(zip(months,monthListH));
monDict = dict(zip(months,monthList));
yearsNWAC = range(2014,2022,1);

for y in yearsNWAC:

    for m in months:
        myHistFunc(pdDF[(pdDF.year==y)&(pdDF.month == m)].Tc,range(-50,50,1),-50,50,0,0.15,'T ($^\circ$C) for Pan Dome ('+monDictH[m]+', '+str(y)+') , 5020 ft, Mt. Baker (2014-2021)','Temperature ($^\circ$C)'
           ,'Fraction',fileLoc,'Tc_panDomeMtBakerhist_'+str(y)+monDict[m]);

        myHistFunc(pdDF[(pdDF.year==y)&(pdDF.month == m)].wsAvgMs,range(-2,30,1),-2,30,0,0.3,'WS for Pan Dome ('+monDictH[m]+', '+str(y)+'), 5020 ft, Mt. Baker (2014-2021)','Wind Speed (m/s)'
           ,'Fraction',fileLoc,'wsAvg_panDomeMtBakerhist_'+str(y)+monDict[m]);

        myHistFunc(pdDF[(pdDF.year==y)&(pdDF.month == m)].winddirectiondeg,range(-0,361,1),-5,365,0,0.10,'WDir for Pan Dome ('+monDictH[m]+', '+str(y)+'), 5020 ft, Mt. Baker (2014-2021)','Wind Dir (deg)'
           ,'Fraction',fileLoc,'wdir_panDomeMtBakerhist_'+str(y)+monDict[m]);

        myHistFunc(hmDF[(pdDF.year==y)&(pdDF.month == m)].Tc,range(-50,50,1),-50,50,0,0.15,'T ($^\circ$C) for Heath Mead ('+monDictH[m]+', '+str(y)+'), 4250 ft, Mt. Baker (2014-2021)','Temperature ($^\circ$C)'
           ,'Fraction',fileLoc,'Tc_heatherMeadowsMtBakerhist_'+str(y)+monDict[m]);

        myHistFunc(hmDF.precipitation[(pdDF.year==y)&(pdDF.month == m)],np.arange(0,10,1),0,10,0,1,'Precip for Heather Meadows, 4210 ft, Mt. Baker ('+monDictH[m]+', '+str(y)+')','Precip (mm)'
           ,'Fraction',fileLoc,'Precip_heatherMeadowsMtBakerhist_'+str(y)+monDict[m]);

# # group by date
# pdDFdateGmean = pdDF.groupby(['date'])['Tc','relativehumidity','wsAvgMs','winddirectiondeg'].mean();
# pdDFdateGstd = pdDF.groupby(['date'])['Tc','relativehumidity','wsAvgMs'].agg(np.std);
# pdDFdateGmax = pdDF.groupby(['date'])['Tc','relativehumidity','wsAvgMs'].max();
# pdDFdateGmin = pdDF.groupby(['date'])['Tc','relativehumidity','wsAvgMs'].max();

# pdDFdateGmean = pdDFdateGmean.unstack(level= 1);
# pdDFdateGstd = pdDFdateGstd.unstack(level = 1);
# pdDFdateGmax = pdDFdateGmax.unstack(level = 1);
# pdDFdateGmin = pdDFdateGmin.unstack(level = 1);

# pickle the data frames

pdDF.to_pickle("../data/panDomeDF2014-2021.pkl")
hmDF.to_pickle("../data/heatherMeadowsDF2014-2021.pkl")


from django.conf.urls import patterns, url
from ranks import views

urlpatterns = patterns('',
	url(r'^$', views.index, name='index'),
	url(r'^games$', views.game_viewer, name='game-viewer'),
	url(r'^add-player$', views.add_player_detail, name='add-player-detail'),
	url(r'^add-player-update$', views.add_player, name='add-player'),
	url(r'^add-game/gameid=(?P<game_id>[0-9A-Za-z._%+-]+)', views.add_game, name='add-game'),
	url(r'^add-game-cont', views.add_game_places, name='add-game-places'),
	url(r'^add-game', views.add_game_detail, name='add-game-detail'),
)


"""
gets a tank installed on its roof and every house with only an incoming pipe and no outgoing pipe gets a tap.

Given two integers n and p denoting the number of houses and the number of pipes. The connections of pipe among the houses contain three input values: ai, bi, di denoting the pipe of diameter di from house ai to house bi. Find the efficient way for the construction of the network of pipes.

The output will contain the number of pairs of tanks and taps t installed in first line and the next t lines contain three integers: house number of tank, house number of tap and the minimum diameter of pipe between them.

Example 1:

Input:
n = 9, p = 6
a[] = {7,5,4,2,9,3}
b[] = {4,9,6,8,7,1}
d[] = {98,72,10,22,17,66}
Output:
3
2 8 22
3 1 66
5 6 10
Explanation:
Connected components are
3->1, 5->9->7->4->6 and 2->8.
Therefore, our answer is 3
followed by 2 8 22, 3 1 66, 5 6 10.

Your Task:
You don't need to read input or print anything. Your task is to complete the function solve() which takes an integer n(the number of houses), p(the number of pipes),the array a[] , b[] and d[] (where d[i] denoting the diameter of the ith pipe from the house a[i] to house b[i]) as input parameter and returns the array of pairs of tanks and taps installed i.e ith element of the array contains three integers: house number of tank, house number of tap and the minimum diameter of pipe between them.

Expected Time Complexity: O(n+p)
Expected Auxiliary Space: O(n+p)

Constraints:
1<=n<=20
1<=p<=50
1<=a[i],b[i]<=20
1<=d[i]<=100
"""

class Solution:
    def __init__(self):
        self.ans0 = 0
        self.ans1 = []
        self.ans2 = []
        self.ans3 = []
        self.rd1 = [0]*1100
        self.wt2 = [0]*1100
        self.cd3 = [0]*1100
        self.f_ans = []

    def dfs(self, w):
        if (self.cd3[w] == 0):
            return w
        if (self.wt2[w] < self.ans0):
            self.ans0 = self.wt2[w]
        return self.dfs(self.cd3[w])

    def solve(self, n, p ,a, b, d):

        i = 0

        while i < p:
            x = a[i]
            y = b[i]
            z = d[i]

            self.cd3[x] = y
            self.wt2[x] = z
            self.rd1[y] = x
            i += 1

        for j in range(1, n + 1):
            if self.rd1[j] == 0 and self.cd3[j]:

                self.ans0 = 1000000000
                w = self.dfs(j)

                self.ans1.append(j)
                self.ans2.append(w)
                self.ans3.append(self.ans0)

        for i in range(len(self.ans1)):
            self.f_ans.append([self.ans1[i], self.ans2[i], self.ans3[i]])

        return self.f_ans

if __name__ == '__main__':
    t = int(input())
    for _ in range(t):

        n,p = map(int,input().strip().split())
        a = []
        b = []
        d = []
        for i in range(p):
            x,y,z = map(int,input().strip().split())
            a.append(x)
            b.append(y)
            d.append(z)

        ob = Solution()
        ans = ob.solve(n, p, a, b, d)
        print(len(ans))
        for i in ans:
            print(str(i[0])+" "+str(i[1])+" "+str(i[2]))


print("Problem 3.37")

def points(x1,y1,x2,y2):
    import math
    d = math.sqrt((x2-x1)**2 + (y2-y1)**2)
    print("The distance :", d, "unit")
    if (x2-x1) !=0:
        m = ((y2-y1)/(x2-x1))
        print("The slope: ", m)
    else:
        print("The slopes is infinity")

Book Introduction to Computing Using Python by Ljubomir Perkovic/Ch-3_Imperative Programming/P-3.37.py


import numbers
import os

import numpy as np
import pandas as pd

from concurrent.futures import ProcessPoolExecutor
from typing import Union, Optional
from typing_extensions import Literal

from .. import utils, config
from ..core import NeuronList, Dotprops, make_dotprops
from .base import Blaster

__all__ = ['nblast', 'nblast_smart', 'nblast_allbyall', 'sim_to_dist']

fp = os.path.dirname(__file__)
smat_path = os.path.join(fp, 'score_mats')

logger = config.logger

class ScoringFunction:
    """Class representing scoring function."""

    def __init__(self, smat):
        if isinstance(smat, type(None)):
            self.scoring_function = self.pass_through
        elif isinstance(smat, (pd.DataFrame, str)):
            self.parse_matrix(smat)
            self.scoring_function = self.score_lookup
        else:
            raise TypeError

    def __call__(self, dist, dot):
        return self.scoring_function(dist, dot)

    @property
    def max_dist(self):
        """Max distance considered by the scoring matrix.

        Returns ``None`` if pass through.
        """
        if self.scoring_function == self.pass_through:
            return None
        # The last bin is always `np.inf`, so we need the second last bin
        return self.dist_bins[-2]

    def pass_through(self, dist, dot):
        """Pass-through scores if no scoring matrix."""
        return dist * dot

    def score_lookup(self, dist, dot):
        return self.cells[
                          np.digitize(dist, self.dist_bins),
                          np.digitize(dot, self.dot_bins),
                         ]

    def parse_matrix(self, smat):
        """Parse matrix."""
        if isinstance(smat, str):
            smat = pd.read_csv(smat, index_col=0)

        if not isinstance(smat, pd.DataFrame):
            raise TypeError(f'Excepted filepath or DataFrame, got "{type(smat)}"')

        self.cells = smat.to_numpy()

        self.dist_thresholds = [self.parse_interval(s) for s in smat.index]
        # Make sure right bin is open
        self.dist_thresholds[-1] = np.inf
        self.dist_bins = np.array(self.dist_thresholds, float)

        self.dot_thresholds = [self.parse_interval(s) for s in smat.columns]
        # Make sure right bin is open
        self.dot_thresholds[-1] = np.inf
        self.dot_bins = np.array(self.dot_thresholds, float)

    def parse_interval(self, s):
        """Strip brackets and parse right interval.

        Example
        -------
        >>> parse_intervals("(0,0.1]")                          # doctest: +SKIP
        0.1
        """
        return float(s.strip("([])").split(",")[-1])

class NBlaster(Blaster):
    """Implements version 2 of the NBLAST algorithm.

    Please note that some properties are computed on initialization and
    changing parameters (e.g. ``use_alpha``) at a later stage will mess things
    up!

    Parameters
    ----------
    use_alpha :     bool
                    Whether or not to use alpha values for the scoring.
                    If True, the dotproduct of nearest neighbor vectors will
                    be scaled by ``sqrt(alpha1 * alpha2)``.
    normalized :    bool
                    If True, will normalize scores by the best possible score
                    (i.e. self-self) of the query neuron.
    smat :          str | pd.DataFrame
                    Score matrix. If 'auto' (default), will use scoring matrices
                    from FCWB. Same behaviour as in R's nat.nblast
                    implementation. If ``smat=None`` the scores will be
                    generated as the product of the distances and the dotproduct
                    of the vectors of nearest-neighbor pairs.
    limit_dist :    float | "auto" | None
                    Sets the max distance for the nearest neighbor search
                    (`distance_upper_bound`). Typically this should be the
                    highest distance considered by the scoring function. If
                    "auto", will extract that value from the scoring matrix.
    progress :      bool
                    If True, will show a progress bar.

    """

    def __init__(self, use_alpha=False, normalized=True, smat='auto',
                 limit_dist=None, progress=True):
        """Initialize class."""
        super().__init__(progress=progress)
        self.use_alpha = use_alpha
        self.normalized = normalized
        self.desc = "NBlasting"

        if smat == 'auto':
            if self.use_alpha:
                smat = pd.read_csv(f'{smat_path}/smat_alpha_fcwb.csv',
                                   index_col=0)
            else:
                smat = pd.read_csv(f'{smat_path}/smat_fcwb.csv',
                                   index_col=0)

        self.score_fn = ScoringFunction(smat)

        if limit_dist == 'auto':
            self.distance_upper_bound = self.score_fn.max_dist
        else:
            self.distance_upper_bound = limit_dist

    def append(self, dotprops):
        """Append dotprops."""
        if isinstance(dotprops, (NeuronList, list)):
            for n in dotprops:
                self.append(n)
            return

        if not isinstance(dotprops, Dotprops):
            raise ValueError(f'Expected Dotprops, got "{type(dotprops)}"')

        self.neurons.append(dotprops)
        self.ids.append(dotprops.id)
        # Calculate score for self hit
        self.self_hits.append(self.calc_self_hit(dotprops))

    def calc_self_hit(self, dotprops):
        """Non-normalized value for self hit."""
        if not self.use_alpha:
            return len(dotprops.points) * self.score_fn(0, 1.0)
        else:
            dists = np.repeat(0, len(dotprops.points))
            alpha = dotprops.alpha * dotprops.alpha
            dots = np.repeat(1, len(dotprops.points)) * np.sqrt(alpha)
            return self.score_fn(dists, dots).sum()

    def single_query_target(self, q_idx, t_idx, scores='forward'):
        """Query single target against single target."""
        # Take a short-cut if this is a self-self comparison
        if q_idx == t_idx:
            if self.normalized:
                return 1
            return self.self_hits[q_idx]

        # Run nearest-neighbor search for query against target
        data = self.neurons[q_idx].dist_dots(self.neurons[t_idx],
                                             alpha=self.use_alpha,
                                             distance_upper_bound=self.distance_upper_bound)
        if self.use_alpha:
            dists, dots, alpha = data
            dots *= np.sqrt(alpha)
        else:
            dists, dots = data

        scr = self.score_fn(dists, dots).sum()

        # Normalize against best hit
        if self.normalized:
            scr /= self.self_hits[q_idx]

        # For the mean score we also have to produce the reverse score
        if scores in ('mean', 'min', 'max'):
            reverse = self.single_query_target(t_idx, q_idx, scores='forward')
            if scores == 'mean':
                scr = (scr + reverse) / 2
            elif scores == 'min':
                scr = min(scr, reverse)
            elif scores == 'max':
                scr = max(scr, reverse)

        return scr

def nblast_smart(query: Union[Dotprops, NeuronList],
                 target: Optional[str] = None,
                 t: Union[int, float] = 90,
                 criterion: Union[Literal['percentile'],
                                  Literal['score'],
                                  Literal['N']] = 'percentile',
                 scores: Union[Literal['forward'],
                               Literal['mean'],
                               Literal['min'],
                               Literal['max']] = 'forward',
                 return_mask: bool = False,
                 normalized: bool = True,
                 use_alpha: bool = False,
                 smat: Optional[Union[str, pd.DataFrame]] = 'auto',
                 limit_dist: Optional[Union[Literal['auto'], int, float]] = 'auto',
                 n_cores: int = os.cpu_count() // 2,
                 progress: bool = True) -> pd.DataFrame:
    """Smart(er) NBLAST query against target neurons.

    In contrast to :func:`navis.nblast` this function will first run a
    "pre-NBLAST" in which only 10% of the query dotprops' points are used.
    Using those initial scores, we select for each query the highest scoring
    targets and run the full NBLAST only on those query-target pairs (see
    ``t`` and ``criterion`` for fine-tuning).

    Parameters
    ----------
    query :         Dotprops | NeuronList
                    Query neuron(s) to NBLAST against the targets. Neurons
                    should be in microns as NBLAST is optimized for that and
                    have similar sampling resolutions.
    target :        Dotprops | NeuronList, optional
                    Target neuron(s) to NBLAST against. Neurons should be in
                    microns as NBLAST is optimized for that and have
                    similar sampling resolutions. If not provided, will NBLAST
                    queries against themselves.
    t :             int | float
                    Determines for which pairs we will run a full NBLAST. See
                    ``criterion`` parameter for details.
    criterion :     "percentile" | "score" | "N"
                    Criterion for selecting query-target pairs for full NBLAST:

                      - "percentile" runs full NBLAST on the ``t``-th percentile
                      - "score" runs full NBLAST on all scores above ``t``
                      - "N" runs full NBLAST on top ``t`` targets

    return_mask :   bool
                    If True, will also return a boolean mask that shows which
                    scores are based on a full NBLAST and which ones only on
                    the pre-NBLAST.
    scores :        'forward' | 'mean' | 'min' | 'max'
                    Determines the final scores:

                      - 'forward' (default) returns query->target scores
                      - 'mean' returns the mean of query->target and
                        target->query scores
                      - 'min' returns the minium between query->target and
                        target->query scores
                      - 'max' returns the maximum between query->target and
                        target->query scores

    n_cores :       int, optional
                    Max number of cores to use for nblasting. Default is
                    ``os.cpu_count() // 2``. This should ideally be an even
                    number as that allows optimally splitting queries onto
                    individual processes.
    use_alpha :     bool, optional
                    Emphasizes neurons' straight parts (backbone) over parts
                    that have lots of branches.
    normalized :    bool, optional
                    Whether to return normalized NBLAST scores.
    smat :          str | pd.DataFrame
                    Score matrix. If 'auto' (default), will use scoring matrices
                    from FCWB. Same behaviour as in R's nat.nblast
                    implementation. If ``smat=None`` the scores will be
                    generated as the product of the distances and the dotproduct
                    of the vectors of nearest-neighbor pairs.
    limit_dist :    float | "auto" | None
                    Sets the max distance for the nearest neighbor search
                    (`distance_upper_bound`). Typically this should be the
                    highest distance considered by the scoring function. If
                    "auto", will extract that value from the scoring matrix.
    progress :      bool
                    Whether to show progress bars.

    Returns
    -------
    scores :        pandas.DataFrame
                    Matrix with NBLAST scores. Rows are query neurons, columns
                    are targets.
    mask :          np.ndarray
                    Only if ``return_mask=True``: a boolean mask with same shape
                    as ``scores`` that shows which scores are based on a full
                    NBLAST and which ones only on the pre-NBLAST.

    References
    ----------
    Costa M, Manton JD, Ostrovsky AD, Prohaska S, Jefferis GS. NBLAST: Rapid,
    Sensitive Comparison of Neuronal Structure and Construction of Neuron
    Family Databases. Neuron. 2016 Jul 20;91(2):293-311.
    doi: 10.1016/j.neuron.2016.06.012.

    Examples
    --------
    >>> import navis
    >>> nl = navis.example_neurons(n=5)
    >>> nl.units
    <Quantity([8 8 8 8 8], 'nanometer')>
    >>> # Convert to microns
    >>> nl_um = nl * (8 / 1000)
    >>> # Convert to dotprops
    >>> dps = navis.make_dotprops(nl_um)
    >>> # Run a NBLAST where only the top target from the pre-NBLAST is run
    >>> # through a full NBLAST
    >>> scores = navis.nblast_smart(dps[:3], dps[3:], t=1, criterion='N')

    See Also
    --------
    :func:`navis.nblast`
                The conventional full NBLAST.
    :func:`navis.nblast_allbyall`
                A more efficient way than ``nblast(query=x, target=x)``.
    :func:`navis.synblast`
                A synapse-based variant of NBLAST.

    """
    utils.eval_param(criterion, name='criterion',
                     allowed_values=("percentile", "score", "N"))

    if isinstance(target, type(None)):
        target = query

    try:
        t = int(t)
    except BaseException:
        raise TypeError(f'`t` must be (convertable to) integer - got "{type(t)}"')

    if criterion == 'percentile':
        if (t <= 0 or t >= 100):
            raise ValueError('Expected `t` to be integer between 0 and 100 for '
                             f'criterion "percentile", got {t}')
    elif criterion == 'N':
        if (t < 0 or t >= len(target)):
            raise ValueError('`t` must be between 0 and the total number of'
                             f'targets ({len(target)} for criterion "N", '
                             f'got {t}')

    # Make sure we're working on NeuronLists
    query_dps = NeuronList(query)
    target_dps = NeuronList(target)

    # Run NBLAST preflight checks
    nblast_preflight(query_dps, target_dps, n_cores, req_unique_ids=True)

    # Find an optimal partition that minimizes the number of neurons
    # we have to send to each process
    n_rows, n_cols = find_optimal_partition(n_cores, query_dps, target_dps)

    # Make simplified dotprops
    query_dps_simp = query_dps.downsample(10, inplace=False)
    target_dps_simp = target_dps.downsample(10, inplace=False)

    # First we NBLAST the highly simplified dotprops against another
    nblasters = []
    with config.tqdm(desc='Prep. pre-NBLAST',
                     total=n_rows * n_cols,
                     leave=False,
                     disable=not progress) as pbar:
        for qq in np.array_split(query_dps_simp, n_rows):
            for tt in np.array_split(target_dps_simp, n_cols):
                # Initialize NBlaster
                this = NBlaster(use_alpha=use_alpha,
                                normalized=normalized,
                                smat=smat,
                                limit_dist=limit_dist,
                                progress=progress)
                # Add queries and targets
                for n in qq:
                    this.append(n)
                for n in tt:
                    this.append(n)
                # Keep track of indices of queries and targets
                this.queries = np.arange(len(qq))
                this.targets = np.arange(len(tt)) + len(qq)
                this.pbar_position = len(nblasters)
                this.desc = 'Pre(NBLASTING)'

                nblasters.append(this)
                pbar.update()

    # If only one core, we don't need to break out the multiprocessing
    if n_cores == 1:
        scr = this.multi_query_target(this.queries,
                                      this.targets,
                                      scores=scores)
    else:
        with ProcessPoolExecutor(max_workers=len(nblasters)) as pool:
            # Each nblaster is passed to it's own process
            futures = [pool.submit(this.multi_query_target,
                                   q_idx=this.queries,
                                   t_idx=this.targets,
                                   scores=scores) for this in nblasters]

            results = [f.result() for f in futures]

        scr = pd.DataFrame(np.zeros((len(query_dps), len(target_dps))),
                           index=query_dps.id, columns=target_dps.id)

        for res in results:
            scr.loc[res.index, res.columns] = res.values

    # Now select targets of interest for each query
    if criterion == 'percentile':
        # Generate a mask for the scores we want to recalculate from full dotprops
        sel = np.percentile(scr, q=t, axis=1)
        mask = scr >= sel.reshape(-1, 1)
    elif criterion == 'score':
        # Generate a mask for the scores we want to recalculate from full dotprops
        sel = np.full(scr.shape[0], fill_value=t)
        mask = scr >= sel.reshape(-1, 1)
    else:
        # Sort such that the top hit is to the left
        srt = np.argsort(scr.values, axis=1)[:, ::-1]
        # Generate the mask
        mask = pd.DataFrame(np.zeros(scr.shape), dtype=bool,
                            columns=scr.columns, index=scr.index)
        _ = np.arange(mask.shape[0])
        for N in range(t):
            mask.values[_, srt[:, N]] = True

    # Now re-generate the NBLASTERs with the full dotprops
    nblasters = []
    with config.tqdm(desc='Preparing full NBLASTs',
                     total=n_rows * n_cols,
                     leave=False,
                     disable=not progress) as pbar:
        for q in np.array_split(np.arange(len(query_dps)), n_rows):
            for t in np.array_split(np.arange(len(target_dps)), n_cols):
                # Initialize NBlaster
                this = NBlaster(use_alpha=use_alpha,
                                normalized=normalized,
                                smat=smat,
                                limit_dist=limit_dist,
                                progress=progress)
                # Add queries and targets
                for n in query_dps[q]:
                    this.append(n)
                for n in target_dps[t]:
                    this.append(n)

                # Find the pairs to NBLAST in this part of the matrix
                submask = mask.loc[query_dps[q].id,
                                   target_dps[t].id]
                # `pairs` is an array of `[[query, target], [...]]` pairs
                this.pairs = np.vstack(np.where(submask)).T

                # Offset the query indices
                this.pairs[:, 1] += len(q)

                # Track this NBLASTER's mask relative to the original big one
                this.mask = np.zeros(mask.shape, dtype=bool)
                this.mask[q[0]:q[-1]+1, t[0]:t[-1]+1] = submask

                # Make sure position of progress bar checks out
                this.pbar_position = len(nblasters)

                nblasters.append(this)
                pbar.update()

    # If only one core, we don't need to break out the multiprocessing
    if n_cores == 1:
        scr[mask] = this.pair_query_target(this.pairs, scores=scores)
    else:
        with ProcessPoolExecutor(max_workers=len(nblasters)) as pool:
            # Each nblaster is passed to its own process
            futures = [pool.submit(this.pair_query_target,
                                   pairs=this.pairs,
                                   scores=scores) for this in nblasters]

            results = [f.result() for f in futures]

        for res, nbl in zip(results, nblasters):
            scr[nbl.mask] = res

    if return_mask:
        return scr, mask

    return scr

def nblast(query: Union[Dotprops, NeuronList],
           target: Optional[str] = None,
           scores: Union[Literal['forward'],
                         Literal['mean'],
                         Literal['min'],
                         Literal['max']] = 'forward',
           normalized: bool = True,
           use_alpha: bool = False,
           smat: Optional[Union[str, pd.DataFrame]] = 'auto',
           limit_dist: Optional[Union[Literal['auto'], int, float]] = None,
           n_cores: int = os.cpu_count() // 2,
           batch_size: Optional[int] = None,
           progress: bool = True) -> pd.DataFrame:
    """NBLAST query against target neurons.

    This implements the NBLAST algorithm from Costa et al. (2016) (see
    references) and mirror the implementation in R's ``nat.nblast``
    (https://github.com/natverse/nat.nblast).

    Parameters
    ----------
    query :         Dotprops | NeuronList
                    Query neuron(s) to NBLAST against the targets. Neurons
                    should be in microns as NBLAST is optimized for that and
                    have similar sampling resolutions.
    target :        Dotprops | NeuronList, optional
                    Target neuron(s) to NBLAST against. Neurons should be in
                    microns as NBLAST is optimized for that and have
                    similar sampling resolutions. If not provided, will NBLAST
                    queries against themselves.
    scores :        'forward' | 'mean' | 'min' | 'max'
                    Determines the final scores:

                      - 'forward' (default) returns query->target scores
                      - 'mean' returns the mean of query->target and
                        target->query scores
                      - 'min' returns the minium between query->target and
                        target->query scores
                      - 'max' returns the maximum between query->target and
                        target->query scores

    use_alpha :     bool, optional
                    Emphasizes neurons' straight parts (backbone) over parts
                    that have lots of branches.
    normalized :    bool, optional
                    Whether to return normalized NBLAST scores.
    smat :          str | pd.DataFrame
                    Score matrix. If 'auto' (default), will use scoring matrices
                    from FCWB. Same behaviour as in R's nat.nblast
                    implementation. If ``smat=None`` the scores will be
                    generated as the product of the distances and the dotproduct
                    of the vectors of nearest-neighbor pairs.
    limit_dist :    float | "auto" | None
                    Sets the max distance for the nearest neighbor search
                    (`distance_upper_bound`). Typically this should be the
                    highest distance considered by the scoring function. If
                    "auto", will extract that value from the scoring matrix.
    n_cores :       int, optional
                    Max number of cores to use for nblasting. Default is
                    ``os.cpu_count() - 2``. This should ideally be an even
                    number as that allows optimally splitting queries onto
                    individual processes.
    batch_size :    int, optional
                    Set the number of Dotprops per process. This can be useful
                    to reduce the memory footprint at the cost of longer run
                    times. By default (``None``), queries and targets will be
                    evenly distributed across n_cores. Ignored if ``n_cores=1``.
    progress :      bool
                    Whether to show progress bars.

    References
    ----------
    Costa M, Manton JD, Ostrovsky AD, Prohaska S, Jefferis GS. NBLAST: Rapid,
    Sensitive Comparison of Neuronal Structure and Construction of Neuron
    Family Databases. Neuron. 2016 Jul 20;91(2):293-311.
    doi: 10.1016/j.neuron.2016.06.012.

    Examples
    --------
    >>> import navis
    >>> nl = navis.example_neurons(n=5)
    >>> nl.units
    <Quantity([8 8 8 8 8], 'nanometer')>
    >>> # Convert to microns
    >>> nl_um = nl * (8 / 1000)
    >>> # Convert to dotprops
    >>> dps = navis.make_dotprops(nl_um)
    >>> # Run the nblast
    >>> scores = navis.nblast(dps[:3], dps[3:])

    See Also
    --------
    :func:`navis.nblast_allbyall`
                A more efficient way than ``nblast(query=x, target=x)``.
    :func:`navis.nblast_smart`
                A smart(er) NBLAST suited for very large NBLAST.
    :func:`navis.synblast`
                A synapse-based variant of NBLAST.

    """
    # Make sure we're working on NeuronLists
    query_dps = NeuronList(query)
    target_dps = NeuronList(target)

    # Run NBLAST preflight checks
    nblast_preflight(query_dps, target_dps, n_cores,
                     batch_size=batch_size, req_unique_ids=True)

    # Find an optimal partition that minimizes the number of neurons
    # we have to send to each process
    if not batch_size or n_cores == 1:
        n_rows, n_cols = find_optimal_partition(n_cores, query_dps, target_dps)
    else:
        n_rows, n_cols = find_batch_partition(batch_size, query_dps, target_dps)

    nblasters = []
    with config.tqdm(desc='Preparing',
                     total=n_rows * n_cols,
                     leave=False,
                     disable=not progress) as pbar:
        for q in np.array_split(query_dps, n_rows):
            for t in np.array_split(target_dps, n_cols):
                # Initialize NBlaster
                this = NBlaster(use_alpha=use_alpha,
                                normalized=normalized,
                                smat=smat,
                                limit_dist=limit_dist,
                                progress=progress)

                # Use better description if we process in batches
                if batch_size:
                    this.desc += f' (batch {len(nblasters) + 1}/{n_rows * n_cols})'

                # Add queries and targets
                for n in q:
                    this.append(n)
                for n in t:
                    this.append(n)
                # Keep track of indices of queries and targets
                this.queries = np.arange(len(q))
                this.targets = np.arange(len(t)) + len(q)
                this.pbar_position = len(nblasters) % n_cores

                nblasters.append(this)
                pbar.update(1)

    # If only one core, we don't need to break out the multiprocessing
    if n_cores == 1:
        return this.multi_query_target(this.queries,
                                       this.targets,
                                       scores=scores)

    with ProcessPoolExecutor(max_workers=n_cores) as pool:
        # Each nblaster is passed to its own process
        futures = [pool.submit(this.multi_query_target,
                               q_idx=this.queries,
                               t_idx=this.targets,
                               scores=scores) for this in nblasters]

        results = [f.result() for f in futures]

    scores = pd.DataFrame(np.zeros((len(query_dps), len(target_dps))),
                          index=query_dps.id, columns=target_dps.id)

    for res in results:
        scores.loc[res.index, res.columns] = res.values

    return scores

def nblast_allbyall(x: NeuronList,
                    normalized: bool = True,
                    use_alpha: bool = False,
                    smat: Optional[Union[str, pd.DataFrame]] = 'auto',
                    limit_dist: Optional[Union[Literal['auto'], int, float]] = None,
                    n_cores: int = os.cpu_count() // 2,
                    progress: bool = True) -> pd.DataFrame:
    """All-by-all NBLAST of inputs neurons.

    A slightly more efficient way of running ``nblast(query=x, target=x)``.

    Parameters
    ----------
    x :             Dotprops | NeuronList
                    Neuron(s) to NBLAST against each other. Neurons should
                    be in microns as NBLAST is optimized for that and have
                    similar sampling resolutions.
    n_cores :       int, optional
                    Max number of cores to use for nblasting. Default is
                    ``os.cpu_count() - 2``. This should ideally be an even
                    number as that allows optimally splitting queries onto
                    individual processes.
    use_alpha :     bool, optional
                    Emphasizes neurons' straight parts (backbone) over parts
                    that have lots of branches.
    normalized :    bool, optional
                    Whether to return normalized NBLAST scores.
    smat :          str | pd.DataFrame, optional
                    Score matrix. If 'auto' (default), will use scoring matrices
                    from FCWB. Same behaviour as in R's nat.nblast
                    implementation. If ``smat=None`` the scores will be
                    generated as the product of the distances and the dotproduct
                    of the vectors of nearest-neighbor pairs.
    limit_dist :    float | "auto" | None
                    Sets the max distance for the nearest neighbor search
                    (`distance_upper_bound`). Typically this should be the
                    highest distance considered by the scoring function. If
                    "auto", will extract that value from the scoring matrix.
    progress :      bool
                    Whether to show progress bars.

    Returns
    -------
    scores :        pandas.DataFrame
                    Matrix with NBLAST scores.

    References
    ----------
    Costa M, Manton JD, Ostrovsky AD, Prohaska S, Jefferis GS. NBLAST: Rapid,
    Sensitive Comparison of Neuronal Structure and Construction of Neuron
    Family Databases. Neuron. 2016 Jul 20;91(2):293-311.
    doi: 10.1016/j.neuron.2016.06.012.

    Examples
    --------
    >>> import navis
    >>> nl = navis.example_neurons(n=5)
    >>> nl.units
    <Quantity([8 8 8 8 8], 'nanometer')>
    >>> # Convert to microns
    >>> nl_um = nl * (8 / 1000)
    >>> # Make dotprops
    >>> dps = navis.make_dotprops(nl_um)
    >>> # Run the nblast
    >>> scores = navis.nblast_allbyall(dps)

    See Also
    --------
    :func:`navis.nblast`
                For generic query -> target nblasts.

    """
    # Make sure we're working on NeuronLists
    dps = NeuronList(x)

    # Run NBLAST preflight checks
    # Note that we are passing the same dotprops twice to avoid having to
    # change the function's signature. Should have little to no overhead.
    nblast_preflight(dps, dps, n_cores, req_unique_ids=True)

    # Find an optimal partition that minimizes the number of neurons
    # we have to send to each process
    n_rows, n_cols = find_optimal_partition(n_cores, dps, dps)

    nblasters = []
    with config.tqdm(desc='Preparing',
                     total=n_rows * n_cols,
                     leave=False,
                     disable=not progress) as pbar:
        for qix in np.array_split(np.arange(len(dps)), n_rows):
            for tix in np.array_split(np.arange(len(dps)), n_cols):
                # Initialize NBlaster
                this = NBlaster(use_alpha=use_alpha,
                                normalized=normalized,
                                smat=smat,
                                limit_dist=limit_dist,
                                progress=progress)

                # Make sure we don't add the same neuron twice
                # Map indices to neurons
                to_add = list(set(qix) | set(tix))

                ixmap = {}
                for i, ix in enumerate(to_add):
                    this.append(dps[ix])
                    ixmap[ix] = i

                # Keep track of indices of queries and targets
                this.queries = [ixmap[ix] for ix in qix]
                this.targets = [ixmap[ix] for ix in tix]
                this.pbar_position = len(nblasters)

                nblasters.append(this)
                pbar.update()

    # If only one core, we don't need to break out the multiprocessing
    if n_cores == 1:
        return this.all_by_all()

    with ProcessPoolExecutor(max_workers=len(nblasters)) as pool:
        # Each nblaster is passed to it's own process
        futures = [pool.submit(this.multi_query_target,
                               q_idx=this.queries,
                               t_idx=this.targets,
                               scores='forward') for this in nblasters]

        results = [f.result() for f in futures]

    scores = pd.DataFrame(np.zeros((len(dps), len(dps))),
                          index=dps.id, columns=dps.id)

    for res in results:
        scores.loc[res.index, res.columns] = res.values

    return scores

def find_batch_partition(N, q, t):
    """Find partition such that each batch contains at most `N` neurons."""
    import math
    # Number of rows (i.e. how many splits for queries)
    n_rows = max(math.floor(len(q) / (N / 2)), 1)

    # Given the number of queries per batch, how many targets can we have
    remaining = N - (len(q) / n_rows)

    n_cols = max(math.floor(len(t) / remaining), 1)

    return int(n_rows), int(n_cols)

def find_optimal_partition(n_cores, q, t):
    """Find an optimal partition for given NBLAST query."""
    # Find an optimal partition that minimizes the number of neurons
    # we have to send to each process
    neurons_per_query = []
    for n_rows in range(1, n_cores + 1):
        # Skip splits we can't make
        if n_cores % n_rows:
            continue
        if n_rows > len(q):
            continue

        n_cols = min(int(n_cores / n_rows), len(t))

        n_queries = len(q) / n_rows
        n_targets = len(t) / n_cols

        neurons_per_query.append([n_rows, n_cols, n_queries + n_targets])

    # Find the optimal partition
    neurons_per_query = np.array(neurons_per_query)
    n_rows, n_cols = neurons_per_query[np.argmin(neurons_per_query[:, 2]), :2]

    return int(n_rows), int(n_cols)

def force_dotprops(x, k, resample, progress=False):
    """Force data into Dotprops."""
    if isinstance(x, (NeuronList, list)):
        dp = [force_dotprops(n, k, resample) for n in config.tqdm(x,
                                                                  desc='Dotprops',
                                                                  disable=not progress,
                                                                  leave=False)]
        return NeuronList(dp)

    # Try converting non-Dotprops
    if not isinstance(x, Dotprops):
        return make_dotprops(x, k=k, resample=resample)

    # Return Dotprops
    return x

def check_microns(x):
    """Check if neuron data is in microns.

    Returns either [True, None (=unclear), False]
    """
    microns = [config.ureg.Unit('microns'),
               config.ureg.Unit('um'),
               config.ureg.Unit('micrometer'),
               config.ureg.Unit('dimensionless')]
    if not isinstance(x, NeuronList):
        x = NeuronList(x)

    # For very large NeuronLists converting the unit string to pint units is
    # the time consuming step. Here we will first reduce to unique units:
    unit_str = []
    for n in x:
        if isinstance(n._unit_str, str):
            unit_str.append(n._unit_str)
        else:
            unit_str += list(n._unit_str)
    unit_str = np.unique(unit_str)

    any_not_microns = False
    all_units = True
    for u in unit_str:
        # If not a unit (i.e. `None`)
        if not u:
            all_units = False
            continue

        # Convert to proper unit
        u = config.ureg(u).to_compact().units

        if u not in microns:
            any_not_microns = True

    if any_not_microns:
        return False
    elif all_units:
        return True
    return None

def align_dtypes(*x, downcast=False, inplace=True):
    """Align data types of dotprops.

    Parameters
    ----------
    *x :        Dotprops | NeuronLists thereof
    downcast :  bool
                If True, will downcast all points to the lowest precision
                dtype.
    inplace :   bool
                If True, will modify the original neuron objects. If False, will
                make a copy before changing dtypes.

    Returns
    -------
    *x
                Input data with aligned dtypes.

    """
    dtypes = get_dtypes(x)

    if len(dtypes) == 1:
        return x

    if not inplace:
        for i in range(x):
            x[i] = x[i].copy()

    if downcast:
        target = lowest_type(*x)
    else:
        target = np.result_type(*dtypes)

    for n in x:
        if isinstance(n, NeuronList):
            for i in range(len(n)):
                n[i].points = n[i].points.astype(target, copy=False)
        elif isinstance(n, Dotprops):
            n.points = n.points.astype(target, copy=False)
        else:
            raise TypeError(f'Unable to process "{type(n)}"')

    return x

def get_dtypes(*x):
    """Collect data types of dotprops points."""
    dtypes = set()
    for n in x:
        if isinstance(n, NeuronList):
            dtypes = dtypes | get_dtypes(n)
        elif isinstance(n, Dotprops):
            dtypes.add(n.points.dtype)
        else:
            raise TypeError(f'Unable to process "{type(n)}"')
    return dtypes

def lowest_type(*x):
    """Find the lowest data type."""
    dtypes = get_dtypes(x)

    if len(dtypes) == 1:
        return dtypes[0]

    lowest = dtypes[0]
    for dt in dtypes[1:]:
        lowest = demote_types(lowest, dt)

    return lowest

def demote_types(a, b):
    """Determine the lower of two dtypes."""
    if isinstance(a, np.ndarray):
        a = a.dtype
    if isinstance(b, np.ndarray):
        b = b.dtype

    # No change is same
    if a == b:
        return a

    # First, get the "higher" type
    higher = np.promote_types(a, b)
    # Now get the one that's not higher
    if a != higher:
        return a
    return b

def sim_to_dist(x):
    """Convert similarity scores to distances.

    Parameters
    ----------
    x :     (M, M) np.ndarray | pandas.DataFrame
            Similarity score matrix to invert.

    Returns
    -------
    distances

    """
    if not isinstance(x, (np.ndarray, pd.DataFrame)):
        raise TypeError(f'Expected numpy array or pandas DataFrame, got "{type(x)}"')

    if isinstance(x, pd.DataFrame):
        mx = x.values.max()
    else:
        mx = x.max()

    return (x - mx) * -1

def nblast_preflight(query, target, n_cores, batch_size=None,
                     req_unique_ids=False, req_dotprops=True):
    """Run preflight checks for NBLAST."""
    if req_dotprops:
        if query.types != (Dotprops, ):
            raise TypeError(f'`query` must be Dotprop(s), got "{query.types}". '
                            'Use `navis.make_dotprops` to convert neurons.')

        if target.types != (Dotprops, ):
            raise TypeError(f'`target` must be Dotprop(s), got "{target.types}". '
                            'Use `navis.make_dotprops` to convert neurons.')

    if req_unique_ids:
        # At the moment, neurons need to have a unique ID for things to work
        if query.is_degenerated:
            raise ValueError('Queries have non-unique IDs.')
        if target.is_degenerated:
            raise ValueError('Targets have non-unique IDs.')

    # Check if query or targets are in microns
    # Note this test can return `None` if it can't be determined
    if check_microns(query) is False:
        logger.warning('NBLAST is optimized for data in microns and it looks '
                       'like your queries are not in microns.')
    if check_microns(target) is False:
        logger.warning('NBLAST is optimized for data in microns and it looks '
                       'like your targets are not in microns.')

    if not isinstance(n_cores, numbers.Number) or n_cores < 1:
        raise TypeError('`n_cores` must be an integer > 0')

    n_cores = int(n_cores)
    if n_cores > 1 and n_cores % 2:
        logger.warning('NBLAST is most efficient if `n_cores` is an even number')
    elif n_cores < 1:
        raise ValueError('`n_cores` must not be smaller than 1')
    elif n_cores > os.cpu_count():
        logger.warning('`n_cores` should not larger than the number of '
                       'available cores')

    if batch_size is not None:
        if batch_size <= 0:
            raise ValueError('`batch_size` must be >= 1 or `None`.')


from collections import deque

def bfs(y, x) :

	sum = 0

	que = deque([[y, x]])
	visited[y][x] = True

	while que :
		v = que.popleft()
		sum += 1

		for i in range(4) :
			ny = v[0] + dy[i]
			nx = v[1] + dx[i]

			if nx < 0 or nx >= m or ny < 0 or ny >= n :
				continue

			if drawing[ny][nx] == 1 and visited[ny][nx] == False :
				que.append([ny, nx])
				visited[ny][nx] = True

	draw_pix.append(sum)

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

drawing = []

draw_pix = []

for i in range(n) :
	pixel = list(map(int, input().split()))
	drawing.append(pixel)

visited = [[False] * m for _ in range(n)]

dx = [-1, 1, 0 ,0]
dy = [0, 0, -1, 1]

for y in range(n) :
	for x in range(m) :
		if drawing[y][x] == 1 and visited[y][x] == False :
			bfs(y,x)

print(len(draw_pix))
print(max(draw_pix))


# Some basic setup:
# Setup detectron2 logger
import datetime
import glob

import cv2
# import some common detectron2 utilities
from detectron2 import model_zoo
from detectron2.config import get_cfg
from detectron2.engine import DefaultPredictor
from detectron2.utils.logger import setup_logger
from tqdm import tqdm

from converts import convert_box, convert_keypoints, save_to_json, logger
# from visual import test_visual

config_path = '/home/sky/detectron2/configs/COCO-Keypoints/keypoint_rcnn_X_101_32x8d_FPN_3x.yaml'
checkpoint_path = '/home/sky/checkpoint/model_final_5ad38f.pkl'
rgb_path = '/home/sky/data/Thermal-pose_data_set/images/RGB_images'
thermal_path = '/home/sky/data/Thermal-pose_data_set/images/Thermal_images'

kp_thresh = 0.2

def covert_output_to_anno(predictions):
    """ Covert detectron2 output['instances'] into suitable annotation format.
    :param predictions: output['instances']
    :return annotation:
    """
    boxes = predictions.pred_boxes if predictions.has("pred_boxes") else None
    scores = predictions.scores if predictions.has("scores") else None
    classes = predictions.pred_classes if predictions.has("pred_classes") else None
    keypoints = predictions.pred_keypoints if predictions.has("pred_keypoints") else None

    # If no boxes were detected, return None.
    if boxes is not None:
        boxes = convert_box(boxes)
        num_instances = len(boxes)
        # Covert XYXY to XYHW
        boxes[:, 2] -= boxes[:, 0]
        boxes[:, 3] -= boxes[:, 1]
    else:
        return None

    # if num_instances is greater than 3 or ==0, means there is something wrong with the detector, return None
    if num_instances > 3 or num_instances == 0:
        return None

    if keypoints is not None:
        if num_instances:
            assert len(keypoints) == num_instances
        else:
            num_instances = len(keypoints)
        keypoints = convert_keypoints(keypoints)

    return boxes, classes, keypoints

def get_anno_dict():
    """Get COCO annotations from input images.
    :return:
    """
    logger.info("Generating prediction results into COCO format")
    coco_annotations = []
    coco_images = []

    cfg = get_cfg()
    cfg.merge_from_file(model_zoo.get_config_file('COCO-Keypoints/keypoint_rcnn_X_101_32x8d_FPN_3x.yaml'))
    cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.9
    cfg.MODEL.WEIGHTS = checkpoint_path

    predictor = DefaultPredictor(cfg)

    for file in tqdm(glob.glob('{}/*.jpg'.format(rgb_path))):
        im = cv2.imread(file)
        coco_image = {
            'id': file.rsplit('/')[-1].split('.')[0],  # Get image id from file name
            'width': im.shape[1],
            'height': im.shape[0],
            'file_name': file.rsplit('/')[-1],
        }
        coco_images.append(coco_image)

        outputs = predictor(im)
        res = covert_output_to_anno(outputs['instances'].to('cpu'))
        if res is None:
            continue
        else:
            boxes, classes, keypoints = res

        for box, category, keypoints_each in zip(boxes, classes, keypoints):
            # Create a new dict with COCO fields
            coco_annotation = {}

            # COCO requirement:
            #   linking annotations to images
            #   "id" field must start with 1
            coco_annotation['bbox'] = [round(float(x), 3) for x in box]
            coco_annotation['id'] = len(coco_annotations) + 1
            coco_annotation['image_id'] = coco_image['id']
            coco_annotation['category_id'] = category.item() + 1

            # Keypoints
            keypoints_list = [kp.item() for kp in keypoints_each.reshape(51, 1)]
            # If detected keypoints confident score is less than kp threshold, set that keypoint to 0. Otherwise set keypoints visibility to 2 (visible).
            for idx in range(2, len(keypoints_list), 3):
                if keypoints_list[idx] < kp_thresh:
                    keypoints_list[idx - 2], keypoints_list[idx - 1], keypoints_list[idx] = 0, 0, 0
                else:
                    keypoints_list[idx] = 2
                    keypoints_list[idx - 2] = int(keypoints_list[idx - 2])
                    keypoints_list[idx - 1] = int(keypoints_list[idx - 1])

            coco_annotation['keypoints'] = keypoints_list
            coco_annotation['num_keypoints'] = sum(kp > 0 for kp in keypoints_list[2::3])
            coco_annotation["iscrowd"] = 0

            coco_annotations.append(coco_annotation)

    info = {
        "date_created": str(datetime.datetime.now()),
        "description": "Automatically generated COCO json file in Thermal Images.",
    }
    coco_dict = {
        "info": info,
        "images": coco_images,
        "annotations": coco_annotations,
        "categories": [{"supercategory": "person", "id": 1, "name": "person",
                        "keypoints": ["nose", "left_eye", "right_eye", "left_ear", "right_ear", "left_shoulder",
                                      "right_shoulder", "left_elbow", "right_elbow", "left_wrist", "right_wrist",
                                      "left_hip", "right_hip", "left_knee", "right_knee", "left_ankle", "right_ankle"],
                        "skeleton": [[16, 14], [14, 12], [17, 15], [15, 13], [12, 13], [6, 12], [7, 13], [6, 7], [6, 8],
                                     [7, 9], [8, 10], [9, 11], [2, 3], [1, 2], [1, 3], [2, 4], [3, 5], [4, 6],
                                     [5, 7]]}],
        "licenses": None,
    }

    return coco_dict

if __name__ == '__main__':
    logger = setup_logger(name=__name__)
    json_path = '/home/sky/data/Thermal-pose_data_set/annotations/thermal_post_keypoints.json'
    coco_anno = get_anno_dict()
    save_to_json(coco_anno, json_path)


# License: GNU Affero General Public License v3 or later
# A copy of GNU AGPL v3 should have been included in this software package in LICENSE.txt.

""" Results classes for the sideloader module
"""

import dataclasses
from typing import Any, Dict, List, Union

from antismash.common.secmet import Protocluster, Record, SubRegion, FeatureLocation
from antismash.common.secmet.features.protocluster import SideloadedProtocluster
from antismash.common.secmet.features.subregion import SideloadedSubRegion
from antismash.common.module_results import DetectionResults

@dataclasses.dataclass(frozen=True)
class SideloadSimple:
    """ A simple frozen container for the sideload-simple argument values """
    accession: str
    start: int
    end: int

def _qualifier_mapping(original: Dict[str, Any]) -> Dict[str, List[str]]:
    """ Converts a dictionary mapping strings to any type to
        a dictionary mapping strings to strings
    """
    result: Dict[str, List[str]] = {}
    for key, val in original.items():
        if isinstance(val, str):
            val = [val]
        else:
            val = list(map(str, val))
        result[key] = val
    return result

@dataclasses.dataclass(frozen=True, eq=True, order=True, unsafe_hash=True)
class Tool:
    """ A collection of details about the tool responsible for annotations """
    name: str
    version: str
    description: str
    configuration: Dict[str, List[str]]

    def __post_init__(self) -> None:
        for i in self.name:
            if not i.isalpha() and i not in "_- ":
                raise ValueError(f"invalid character in tool name: '{i}'")

    def to_json(self) -> Dict[str, Any]:
        """ Convert a Tool instance to JSON """
        return dataclasses.asdict(self)

    @classmethod
    def from_json(cls, raw: Dict[str, Any]) -> "Tool":
        """ Rebuild a Tool instance from JSON """
        return cls(
            str(raw["name"]),
            str(raw["version"]),
            str(raw.get("description", "")),
            _qualifier_mapping(raw.get("configuration", {})),
        )

class SubRegionAnnotation:
    """ A class for containing arbitrary data about a sideloaded subregion annotation """
    kind = "subregion"

    def __init__(self, start: int, end: int, label: str, tool: Tool, details: Dict[str, List[str]]) -> None:
        if end <= start:
            raise ValueError("area end must be greater than area start")
        self.start = start
        self.end = end
        self.label = label
        self.details = details
        assert isinstance(tool, Tool)
        self.tool = tool

    def __len__(self) -> int:
        return self.end - self.start

    def to_secmet(self) -> SideloadedSubRegion:
        """ Constructs a SideloadedSubRegion instance from the annotation """
        location = FeatureLocation(self.start, self.end)
        return SideloadedSubRegion(location, self.tool.name, label=self.label, extra_qualifiers=self.details)

    def to_json(self) -> Dict[str, Any]:
        """ Converts the annotation to JSON (separate from the JSON schema)"""
        result = dict(vars(self))
        result["tool"] = self.tool.to_json()
        return result

    @classmethod
    def from_json(cls, raw: Dict[str, Any]) -> "SubRegionAnnotation":
        """ Reconstructs an annotation from JSON (separate from the JSON schema)"""
        return cls(
            int(raw["start"]),
            int(raw["end"]),
            str(raw["label"]),
            Tool.from_json(raw["tool"]),
            _qualifier_mapping(raw.get("details", {})),
        )

    @classmethod
    def from_schema_json(cls, raw: Dict[str, Any], tool: Tool) -> "SubRegionAnnotation":
        """ Builds an instance from JSON matching the protocluster schema, along with a tool """
        raw["tool"] = tool.to_json()
        return cls.from_json(raw)

    def __eq__(self, other: Any) -> bool:
        if not isinstance(other, SubRegionAnnotation):
            return False
        return vars(self) == vars(other)

    def __str__(self) -> str:
        return f"Subregion({self.tool.name}, {self.start}-{self.end}, {self.label})"

class ProtoclusterAnnotation:
    """ A class for containing arbitrary data about a sideloaded protocluster annotation """
    kind = "protocluster"

    def __init__(self, core_start: int, core_end: int, product: str, tool: Tool, details: Dict[str, List[str]],
                 neighbourhood_left: int = 0, neighbourhood_right: int = 0) -> None:
        if core_end <= core_start:
            raise ValueError("area end must be greater than area start")
        if neighbourhood_left < 0 or neighbourhood_right < 0:
            raise ValueError("neighbourhoods must be annotated as absolute distances, not relative")
        if core_start - neighbourhood_left < 0:
            raise ValueError("neighbourhoods cannot extend out of a record")
        self.core_start = core_start
        self.core_end = core_end
        self.product = product
        assert isinstance(tool, Tool)
        self.tool = tool
        self.details = details
        self.neighbourhood_left = neighbourhood_left
        self.neighbourhood_right = neighbourhood_right

    @property
    def start(self) -> int:
        """ The start of the protocluster, including neighbourhood """
        return self.core_start - self.neighbourhood_left

    @property
    def end(self) -> int:
        """ The end of the protocluster, including neighbourhood """
        return self.core_end + self.neighbourhood_right

    @property
    def label(self) -> str:
        """ The product of the protocluster, for compatibility purposes """
        return self.product

    def __len__(self) -> int:
        return self.core_end + self.neighbourhood_right - self.start

    def to_json(self) -> Dict[str, Any]:
        """ Converts the annotation to JSON (separate from the JSON schema)"""
        res = dict(vars(self))
        res["tool"] = self.tool.to_json()
        return res

    def to_secmet(self) -> SideloadedProtocluster:
        """ Constructs a SideloadedProtocluster instance from the annotation """
        return SideloadedProtocluster(
            FeatureLocation(self.core_start, self.core_end),
            FeatureLocation(self.start, self.end),
            self.tool.name,
            self.product,
            neighbourhood_range=max(self.neighbourhood_left, self.neighbourhood_right),
        )

    @classmethod
    def from_json(cls, raw: Dict[str, Any]) -> "ProtoclusterAnnotation":
        """ Reconstructs an annotation from JSON (separate from the JSON schema)"""
        return cls(
            int(raw["core_start"]),
            int(raw["core_end"]),
            str(raw["product"]),
            Tool.from_json(raw["tool"]),
            _qualifier_mapping(raw.get("details", {})),
            int(raw.get("neighbourhood_left", 0)),
            int(raw.get("neighbourhood_right", 0)),
        )

    @classmethod
    def from_schema_json(cls, raw: Dict[str, Any], tool: Tool) -> "ProtoclusterAnnotation":
        """ Builds an instance from JSON matching the protocluster schema, along with a tool """
        raw["tool"] = tool.to_json()
        return cls.from_json(raw)

    def __eq__(self, other: Any) -> bool:
        if not isinstance(other, ProtoclusterAnnotation):
            return False
        return vars(self) == vars(other)

    def __str__(self) -> str:
        return f"Protocluster({self.tool.name}, {self.start}-{self.end}, {self.product})"

class SideloadedResults(DetectionResults):
    """ A wrapper allowing for different kinds of sideloaded annotations """
    schema_version = 1

    def __init__(self, record_id: str, subregions: List[SubRegionAnnotation],
                 protoclusters: List[ProtoclusterAnnotation]) -> None:
        super().__init__(record_id)
        self.subregions = subregions
        self.protoclusters = protoclusters

    def to_json(self) -> Dict[str, Any]:
        return {
            "record_id": self.record_id,
            "schema_version": self.schema_version,
            "protoclusters": [proto.to_json() for proto in self.protoclusters],
            "subregions": [sub.to_json() for sub in self.subregions],
        }

    @staticmethod
    def from_json(json: Dict[str, Any], record: Record) -> "SideloadedResults":
        if json["schema_version"] != SideloadedResults.schema_version:
            raise ValueError("Detection results have changed. No results can be reused.")

        assert json["record_id"] == record.id
        subs = [SubRegionAnnotation.from_json(sub) for sub in json["subregions"]]
        protos = [ProtoclusterAnnotation.from_json(proto) for proto in json["protoclusters"]]
        return SideloadedResults(json["record_id"], subs, protos)

    def get_areas(self) -> List[Union[ProtoclusterAnnotation, SubRegionAnnotation]]:
        """ Returns a list of all sideloaded annotations """
        areas: List[Union[ProtoclusterAnnotation, SubRegionAnnotation]] = []
        areas.extend(self.subregions)
        areas.extend(self.protoclusters)
        # sort consistently with secmet's region.get_sideloaded_areas()
        return sorted(areas, key=lambda x: (x.start, -len(x), x.tool.name))

    def get_predicted_subregions(self) -> List[SubRegion]:
        return [sub.to_secmet() for sub in self.subregions]

    def get_predicted_protoclusters(self) -> List[Protocluster]:
        return [proto.to_secmet() for proto in self.protoclusters]

    def add_to_record(self, record: Record) -> None:
        for subregion in self.subregions:
            record.add_subregion(subregion.to_secmet())
        for protocluster in self.protoclusters:
            record.add_protocluster(protocluster.to_secmet())


# coding:utf-8
"""
@Time :    2021/2/7 下午1:41
@Author:  chuwt
"""

import os
import importlib
from template import CtaTemplate

classes = dict()

def load_strategy(path):
    load_strategy_class_from_folder(path, "strategies")

def load_strategy_class_from_folder(path, module_name=""):
    for dirpath, dirnames, filenames in os.walk(str(path)):
        for filename in filenames:
            if filename.split(".")[-1] in ("py", "pyd", "so"):
                strategy_module_name = ".".join([module_name, filename.split(".")[0]])
                load_strategy_class_from_module(strategy_module_name)

def load_strategy_class_from_module(module_name):
    try:
        module = importlib.import_module(module_name)
        for name in dir(module):
            value = getattr(module, name)
            if isinstance(value, type) and \
                    value.__base__.__name__ == CtaTemplate.__name__ and \
                    value is not CtaTemplate:
                classes[value.__name__] = value
    except Exception as e:  # noqa
        print("not found", str(e))
        return "not found"

def get_strategy_instance(strategy_path, strategy_class_name, strategy_name, vt_symbol, setting):
    load_strategy(strategy_path)
    strategy_class = classes.get(strategy_class_name, None)
    if not strategy_class:
        print("none")
        return None
    return strategy_class(None, strategy_name, vt_symbol, setting)

if __name__ == "__main__":
    strategy = get_strategy_instance(
        "/Volumes/hdd1000gb/workspace/src/github.com/chuwt/zing/python/github.com/chuwt/zing/strategies",
        "MaDingStrategy",
        "chuwt",
        "chuwt",
        ""
    )
    strategy.on_contract(
        '{"gateway":"huobi","symbol":"btcusdt","name":"","product":"现货","min_order_amt":"0.0001","min_order_value":"5","min_volume":"0.000001"}')
    strategy.on_init()
    print(strategy)


'''
    Module
'''

import sys
import unittest,os,sys
sys.path.append( os.getcwd() )

import unittest
from brazil.FixHtml import fixHtml

class dummyFixHtml(fixHtml):
    def __init__(self):
        pass

class TestFix(unittest.TestCase):

    def setUp(self):
        self.fix = dummyFixHtml()

    def testDeleteScript(self):
        self.fix.html = '

'
        self.fix.delete_script()
        self.assertEqual( self.fix.html, '

')

    def testQuoteHref(self):
        self.fix.html = '
Wow
'
        self.fix.quote_href()
        self.assertEqual( self.fix.html, '
Wow
')

    def testQuoteOnclick(self):
        self.fix.html = '
Wow
'
        self.fix.quote_onclick()
        self.assertEqual( self.fix.html, '
Wow
')

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


def solution(n, k):
    answer = []
    target = [n for n in range(1, n + 1)]
    k -= 1

    for num in range(n, 0, -1):
        split_num = fact(num) // num
        answer.append(target[k // split_num])
        target.pop(k // split_num)

        k %= split_num

    return answer

def fact(n):
    ret = 1
    for i in range(1, n+1):
        ret *= i

    return ret

프로그래머스/lv2/12936. 줄 서는 방법/줄 서는 방법.py


#!/usr/bin/python
#-*- coding:utf-8 -*-

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

# 1.Pandas绘图,DataFrame绘图

# np.random.seed(100)
df = pd.DataFrame({'A': np.random.randn(365).cumsum(0),
                  'B': np.random.randn(365).cumsum(0) + 20,
                  'C': np.random.randn(365).cumsum(0) - 20},
                 index=pd.date_range('2017/1/1', periods=365))
print(df.head())
# df.plot()
# plt.show()

# df.plot('A', 'B', kind='scatter')
# plt.show()

# df.plot(kind='box')
# plt.show()

# df.plot(kind='hist', alpha=0.7)
# plt.show()
#
# df.plot(kind='kde')
# plt.show()

# # pandas.tools.plotting
#
# # 2. Seaborn绘图
import seaborn as sns
np.random.seed(100)
v1 = pd.Series(np.random.normal(0, 10, 1000), name='v1')
v2 = pd.Series(2 * v1 + np.random.normal(60, 15, 1000), name='v2')

np.random.seed(100)
v1 = pd.Series(np.random.normal(0, 10, 1000), name='v1')
v2 = pd.Series(2 * v1 + np.random.normal(60, 15, 1000), name='v2')

# # 通过matplotlib绘图
# plt.figure()
# plt.hist(v1, alpha=0.7, bins=np.arange(-50, 150, 5), label='v1')
# plt.hist(v2, alpha=0.7, bins=np.arange(-50, 150, 5), label='v2')
# plt.legend()
# plt.show()

plt.figure()
plt.hist([v1, v2], histtype='barstacked', normed=True)
v3 = np.concatenate((v1, v2))
sns.kdeplot(v3)
plt.show()

# # 使用seaborn绘图
# plt.figure()
# sns.distplot(v3)
# # plt.show()
#
#
# # 使用seaborn绘图
# plt.figure()
# sns.jointplot(v1, v2, alpha=0.4)
# # plt.show()
#
# # 使用seaborn绘图
# plt.figure()
# grid = sns.jointplot(v1, v2, alpha=0.4)
# grid.ax_joint.set_aspect('equal')
# plt.show()
#
# plt.figure()
# sns.jointplot(v1, v2, kind='hex')
# plt.show()
#
# plt.figure()
# sns.jointplot(v1, v2, kind='kde')
#
# iris = pd.read_csv('iris.csv')
# print(iris.head())
#
# sns.pairplot(iris, hue='Name', diag_kind='kde')
#
# plt.figure()
# plt.subplot(121)
# sns.swarmplot('Name', 'PetalLength', data=iris)
# plt.subplot(122)
# sns.violinplot('Name', 'PetalLength', data=iris)
# plt.show()


import pya

def merge():
    files = file2.split(",")
    opt = pya.LoadLayoutOptions()
    opt_oas = pya.SaveLayoutOptions()
    ly = pya.Layout()

    for file in files:
        lmap = ly.read(file1)

        ly = change_uid(ly)

        opt.set_layer_map(lmap, True)
        ly.read(file, opt)

        ly.write(output)

    for cells in ly.each_cell():
        ci = cells.cell_index()
        if "$" in cells.name:
            ly.delete_cell_rec(ci)

    opt_oas.set_format_from_filename(output)
    opt_oas.oasis_substitution_char=''
    ly.write(output, opt_oas)

def change_uid(lib):
    for cells in lib.each_cell():
        ci = cells.cell_index()
        if "xxxxyyyy" in cells.name:
            name = cells.name.replace("xxxxyyyy", user_id)
            lib.rename_cell(ci, name)
    return lib

if __name__ == "__main__":
    output = "caravel_" + user_id + ".oas"
    merge()


#!/usr/bin/python
# written by Miguel Brown 2015-Feb-17. Sets up a pipeline vm, creates cinder blocks, and attaches

import sys
sys.path.append('/home/ubuntu/TOOLS/Scripts/utility')
import os
import re
import json
import argparse
from date_time import date_time
import subprocess
from setup_vm import setup_vm
from attach_cinder import attach_cinder

class Setup():

    def __init__(self, bid,json_config,wait):
        self.json_config = json_config
        self.wait=wait
        self.bid=bid
        self.parse_config()

    def parse_config(self):
        self.config_data = json.loads(open(self.json_config, 'r').read())
        (self.vm_id,self.flavor,self.key)=(self.config_data['vm_image']['id'],self.config_data['vm_image']['flavor'],self.config_data['vm_image']['key'])
        self.create_vm()

    def create_vm(self):
        (flag,vid,vip)=setup_vm(self.bid,self.vm_id,self.flavor,self.key,self.wait)
        vm = "vm_pipe_" + self.bid
        if flag==1:
            sid=self.config_data['cinder_ref']['id']
            size=self.config_data['cinder_ref']['size']
            sys.stderr.write("Attaching cinder volume...\n")
            vol=attach_cinder(sid,vid,self.bid,size,vip,self.wait)
            sys.stderr.write("Volume attached.  Go play and have fun!\n")
        else:
            sys.stderr.write("VM setup time out for " + vm + "Check connection settings or increase wait time and try again\n")

def main():
    parser=argparse.ArgumentParser(description='VM spawner for pipeline processes.  Sets up vm for sample analysis and attaches sotrage references.  BE SURE TO DOUBLE CHECK VM AND CINDER IDS OF CONFIGURATION FILES BEFORE PROCEEDING!')
    parser.add_argument('-id','--BID',action='store',dest='bid',help='Project Bionimbus ID')
    parser.add_argument('-j','--json',action='store',dest='config_file',help='JSON config file with snapshot ids and set up params')
    parser.add_argument('-w','--wait',action='store',dest='wait',help='Wait time before giving up on spawning an image.  Recommended value 600 (in seconds)')

    if len(sys.argv)==1:
        parser.print_help()
        sys.exit(1)

    inputs=parser.parse_args()

    bid=inputs.bid
    config_file=inputs.config_file
    wait=inputs.wait
    setup=Setup(bid,config_file,wait)
if __name__ == '__main__':
  main()


from django.test import TestCase

from pygipo.models import memoize, Dump

class TestMemoize(TestCase):

    @staticmethod
    def _get_xs():
        return [
            {'a': 23},
            {'b': 12}
        ]

    def test(self):
        dump = Dump.create()

        @memoize(entity='fooentity', dump=dump)
        def get_xs():
            return self._get_xs()

        xs1 = get_xs()
        xs2 = get_xs()

        for x1, x2 in zip(xs1, xs2):
            self.assertDictEqual(x1, x2)

        for rec, x in zip(dump.records, xs1):
            self.assertDictEqual(rec.json, x)

    def test_latest_dump(self):
        @memoize('barentity')
        def bars():
            return self._get_xs()

        xs1 = bars()
        xs2 = bars()

        for x1, x2 in zip(xs1, xs2):
            self.assertDictEqual(x1, x2)

        dump = Dump.objects.latest()
        for rec, x in zip(dump.records, xs1):
            self.assertDictEqual(rec.json, x)

    def test_no_unpack(self):
        @memoize('barentity', unpack=False)
        def bars():
            return self._get_xs()

        xs1 = bars()
        xs2 = bars()

        for x1, x2 in zip(xs1, xs2):
            self.assertDictEqual(x1, x2)

        dump = Dump.objects.latest()
        rec = dump.record_set.first()
        self.assertEqual(rec.json, xs1)


def Dragon(n):
	if isinstance(n, int) is  False or  n < 0:
		return ''
	D0 = "Fa"
	replace_a = "aRbFR"
	replace_b = "LFaLb"
	while n >= 1:
		D1 =""
		for c in D0:
			if c is  'a':
				D1 += replace_a
				continue
			elif c is  'b':
				D1 += replace_b
				continue
			D1 += c
		D0 = D1
		n -= 1
	return D0.replace("a", "").replace("b", "")