__author__ = "Domenico Solazzo"
__version__ = "0.1"

RESPONSE_CODES = {
        200: "OK: Success",
        202: "Accepted: The request was accepted and the user was queued for processing",
        401: "Not Authorized: either you need to provide authentication credentials, or the credentials provided aren't valid.",
        403: "Bad Request: Your request is invalid and we'll return and error message that tells you why. This is the status code if you have exceeded the rate limit.",
        404: "Not Found: either you are requesting an invalid URI or the resource in question doesn't exist.",
        500: "Internal Server Error: we did something wrong.",
        502: "Bad Gateway: returned if Klout is down or being upgraded.",
        503: "Service Unavailable: the Klout servers are up, but are overloaded with requests. Try again later."
}
class KloutError( Exception ):
    def __init__(self, code=0, msg=''):
        super(KloutError, self).__init__()
        self.code = code
        self.msg = msg
    def __str__(self):
        return repr(self)
    def __repr__(self):
        return "%i: %s" % (self.code, self.msg)

class Klout( object ):
    def __init__(self, key, serviceType="service"):
        self._apiKey = key
        self.__service = self.__getProxyFactory(serviceType)

    def __getProxyFactory(self, serviceType):
        service = None
        if serviceType == "test":
            service = TestKloutService(serviceType)
        else:
            service = KloutService(self._apiKey)
        self.__service = service
        return self.__service

    def score(self, users):
        """
            Retrieve a Klout score
            @param: users - List of usernames
            @return: A list of tuples in the form (username, klout_score)
        """
        if not users:
            raise KloutError(0, "No Users")
        if not isinstance(users, (list, tuple)):
            raise KloutError(0, "Wrong input.")
        users = ",".join(users)
        query = {"users": users}
        result = self.__service.makeCall("score", query)

        return result
    def show(self, users):
        """
            Retrieve a user object
            @param: users - List of usernames
            @return: A dictionary with the returned data
        """
        if not users:
            raise KloutError(0, "No Users.")
        if not isinstance(users, (list, tuple)):
            raise KloutError(0, "Wrong input.")
        users = ",".join(users)
        query = {"users":users}
        result = self.__service.makeCall("user", query)
        return result
    def topics(self, users):
        """
            Returns the top 3 topics objects
            @param: users - A list of usernames
            @return: A list of dicts in the form [{username:['topic1, topic2, topic3]..}
        """
        if not users:
            raise KloutError(0, "No Users")
        if not isinstance(users, (list, tuple)):
            raise KloutError(0, "Wrong Input.")
        users = ",".join(users)
        query = {"users":users}
        result = self.__service.makeCall("topics", query)
        return result
    def influencerOf(self, users):
        """
            Returns up to 5 user score pairs for user that are influencer for the given user
            @param: users - A list of usernames
            @return: A list of dicts in the form [{username:[(username, score),..}
        """
        if not users:
            raise KloutError(0, "No Users")
        if not isinstance(users, (list, tuple)):
            raise KloutError(0, "Wrong Input.")
        users = ",".join(users)
        query = {"users":users}
        result = self.__service.makeCall("influencerOf", query)
        return result
    def influencedBy(self, users):
        """
            Returns up to 5 user score pairs for user that are influenced by the given user
            @param: users - A list of usernames
            @return: A list of dicts in the form [{username:[(username, score),..}
        """
        if not users:
            raise KloutError(0, "No Users")
        if not isinstance(users, (list, tuple)):
            raise KloutError(0, "Wrong Input.")
        users = ",".join(users)
        query = {"users":users}
        result = self.__service.makeCall("influencedBy", query)
        return result

class KloutService(object):
    def __init__(self, apiKey):
        self.apiKey = apiKey
        self.VERSION_API = "/1/"
        self.API_URL = "api.klout.com"

    def getCallUrl(self, callName):
        servicePath = ""
        if callName == "score":
            servicePath = "klout.json"
        elif callName == "user":
            servicePath = "users/show.json"
        elif callName == "topics":
            servicePath = "users/topics.json"
        elif callName == "influencedBy":
            servicePath = "soi/influenced_by.json"
        elif callName == "influencerOf":
            servicePath = "soi/influencer_of.json"
        else:
            raise Exception("Url not available")
        return self.VERSION_API + servicePath

    def _remove_empty_params(self, query):
        if not isinstance(query, type({})):
            raise Exception("Wrong query in input")
        returnedQuery = {}
        for key in query:
            if not query[key] == None:
                returnedQuery[key] = query[key]
        return returnedQuery

    def makeCall(self, callName, query):
        import urllib, httplib, json
        url = self.getCallUrl(callName)

        query = self._remove_empty_params(query)

        if 'key' not in query:
            query["key"] = self.apiKey

        queryStr = urllib.urlencode(query)

        if len(query) > 0:
            if url.find("?") == -1:
                url = url + "?" + queryStr
            else:
                url = url + "&" + queryStr
        try:
            conn = httplib.HTTPConnection(self.API_URL)
            conn.request('GET', url)
            response = conn.getresponse()
            data = response.read()
            data = json.loads(data)
        except httplib.HTTPException as err:
            msg = err.read() or RESPONSE_CODES.get(err.code, err.message)
            raise KloutError(err.code, msg)
        except ValueError:
            msg = "Invalid data: %s" % data
            raise KloutError(0, msg)
        return data
class TestKloutService(KloutService):
    def makeCall(self, callName, query):
        if callName == "score":
            return {"users":[{"twitter_screen_name":"user1","kscore":23.02}]}
        elif callName == "user":
            return {"users":[{
                "twitter_id": "111111",
                "twitter_screen_name":"name",
                "score":{
                    "kscore":10,
                    "slope":1,
                    "description":"description",
                    "kclass_id":1,
                    "kclass":"Socializer",
                    "kclass_description":"kclass description",
                    "network_score":22,
                    "amplification_score":18,
                    "true_reach": 10,
                    "delta_1day": 0.2,
                    "delta_5day": 0.4
                }
            }]}
        elif callName == "topics":
            return {"users":[{"twitter_screen_name":"user1", "topics":["python"]}]}
        elif callName == "influencedBy":
            return {"users":[
                                {
                                "twitter_screen_name":"user1",
                                "influencers":[{"twitter_screen_name":"user2",
                                                "kscore":10.00
                                                }]
                                }
                            ]
                    }
        elif callName == "influencerOf":
            return {"users":[
                                {
                                "twitter_screen_name":"user1",
                                "influencers":[{"twitter_screen_name":"user2",
                                                "kscore":10.00
                                                }]
                                }
                            ]
                    }
        elif callName == "history":
            return {'dates':[], 'klout_score':[], 'amplification':[],
                    'retweets':[], 'mentions':[],'network':[],
                    'followers_following':[], 'followers_count':[], 'mentioners':[],
                    'retweeters':[],'true_reach':[],'in_out':[]
                    }


from utils import read_input

def age_and_spawn_the_fish(fishes):
    baby_age = 8

    spawns = determine_num_spawns(fishes)

    for i, fish in enumerate(fishes):
        fishes[i] = calc_next_age(fish)

    for i in range(0, spawns):
        fishes.append(baby_age)

    return fishes

def calc_next_age(fish):
    spawn_time = 6
    if fish > 0:
        return fish - 1
    else:
        return spawn_time

def determine_num_spawns(fishes):
    return len([i for i in fishes if i == 0])

def p2_spawn_and_age_the_fish(fishes_dict):
    new_counts = {}
    new_counts[0] = fishes_dict[1]
    new_counts[1] = fishes_dict[2]
    new_counts[2] = fishes_dict[3]
    new_counts[3] = fishes_dict[4]
    new_counts[4] = fishes_dict[5]
    new_counts[5] = fishes_dict[6]
    new_counts[6] = fishes_dict[7] + fishes_dict[0]
    new_counts[7] = fishes_dict[8]
    new_counts[8] = fishes_dict[0]

    return new_counts

if __name__ == "__main__":
    fishes = [int(i) for i in read_input("day6_input.txt")[0].split(",")]

    days = 256
    # PART 1
    # for i in range(0, days):
    #     print(f"DAY {i}")
    #     fishes = age_and_spawn_the_fish(fishes)
    #
    # print(f"FINAL: {len(fishes)}")

    # PART 2
    fishes_dict = {}
    for i in range(0, 9):
        fishes_dict[i] = len([f for f in fishes if f == i])

    for i in range(0, days):
        fishes_dict = p2_spawn_and_age_the_fish(fishes_dict)

    print(f"PART 2: {sum([fishes_dict[i] for i in fishes_dict])}")


from urllib.request import urlopen
from bs4 import BeautifulSoup

url = input('Enter URL:')
count = int(input('Enter count:'))
position = int(input('Enter position:'))-1
html = urlopen(url).read()

soup = BeautifulSoup(html,"html.parser")
href = soup('a')
#print href

for i in range(count):
    link = href[position].get('href', None)
    print (href[position].contents[0])
    html = urlopen(link).read()
    soup = BeautifulSoup(html,"html.parser")
    href = soup('a')


#!/usr/bin/env python3

import sys
import re
import glob
import prettytable
import pandas as pd
import argparse
import os

def readFile(filename):
	fileContents = list()
	with open(filename, "r") as f:
		for line in f:
			line = line.strip()
			fileContents.append(line)
	return fileContents

def getStatusLine(fileContents):
	totallines = len(fileContents)
	statusLine = -1
	for i in range(totallines):
		result = re.match(r"Resource", fileContents[i])
		if result:
			statusLine = i - 2
	return(statusLine)

def splitStrip(i):
	temp = i.split(sep=":")[1]
	temp = temp.strip()
	return temp

def getJobDetails(fileContents, lineNumber):
	lines = fileContents[lineNumber:]
	status = lines[0]
	for i in lines:
		if re.match(r"CPU", i):
			cpu_time = splitStrip(i)
		if re.match(r"Max Memory", i):
			max_mem = splitStrip(i)
		if re.match(r"Total Requested Memory", i):
			total_mem = splitStrip(i)
		if re.match(r"Max Processes", i):
			max_proc = splitStrip(i)
		if re.match(r"Max Threads", i):
			max_threads = splitStrip(i)
		if re.match(r"Run time", i):
			run_time = splitStrip(i)
	x = {'cpu_time':cpu_time,
	'status': status,
	'max_mem': max_mem,
	'total_mem': total_mem,
	'max_proc': max_proc,
	'max_threads': max_threads,
	'run_time': run_time
	}
	return(x)

def getStartEnd(fileContents):
	for i in fileContents:
		if	re.match(r"Started at", i):
			start = i.replace("Started at", "")
		if	re.match(r"Terminated at", i):
			end = i.replace("Terminated at", "")
	x = {"start": start, "end":end}
	return(x)

def pullOutJobData(fileName):
	#print(f"Pulling out job data from ... {fileName}", file = sys.stderr)
	fileContents = readFile(fileName) # read file as a list
	lineNumber = getStatusLine(fileContents) # get status line
	if lineNumber == -1:
		job_details = {"status": "running"}
		return(job_details)
	job_status = fileContents[lineNumber]
	job_start_end = getStartEnd(fileContents)
	job_details = getJobDetails(fileContents, lineNumber)

	if not re.match(r"Successfully completed", job_status):
		jminus1=fileContents[lineNumber -  1]
		job_status = job_status + " - " + jminus1

	job_details.update(job_start_end)
	job_details.update({"status": job_status})
	return(job_details)

class job:
	counter = 0
	def __init__(self, fileName):
		self.fileName = fileName
		temp = pullOutJobData(fileName)
		self.status = temp['status']
		if self.status == "running":
			return

		self.cpu_time = temp['cpu_time']
		self.max_mem = temp['max_mem']
		self.total_mem = temp['total_mem']
		self.max_proc = temp['max_proc']
		self.run_time = temp['run_time']
		self.start = temp['start']
		self.end = temp['end']
		job.counter += 1

	def details(self):
		job_details = self.__dict__.items()
		if self.counter == 1:
			for k,v in job_details:
				print("%s" % k, end = "\t")
			print()

		for k,v in job_details:
			print("%s" % v, end = "\t")
		print()

	def forTable(self, onlyHeader = False):
		job_details = self.__dict__.items()
		x = list()
		if onlyHeader:
			for k,v in job_details:
				x.append(k)
		if not onlyHeader:
			for k,v in job_details:
				x.append(v)
		return(x)

		#print(f"{self.fileName}\t{self.status}\t{self.start}\t{self.end}\t{self.cpu_time}\t{self.max_mem}\t{self.total_mem}")

if __name__ == "__main__":
	parser = argparse.ArgumentParser()
	parser.add_argument("--progArgs", default = "pretty", help="output type: [pretty, csv]")
	parser.add_argument("--comments", default = "", help="filter for names")
	args = parser.parse_args()
	if not os.path.isdir(".bsub/"):
		print("No farm job log found. See if .bsub exists", file = sys.stderr)
		exit(0)

	# Search files
	search = ".bsub/*" + args.comments + "*.farm"
	files = glob.glob(search)

	c = 0
	lof = list()
	for f in files:
		j = job(f)
		if j.status == "running":
			continue
		if c == 0:
			colnames = j.forTable(onlyHeader = True)
			table = prettytable.PrettyTable(colnames)
			lof.append(colnames)
		l = j.forTable(onlyHeader = False)
		table.add_row(l)
		lof.append(l)
		c += 1

	if args.progArgs == "pretty":
		print(table)
	if args.progArgs == "csv":
		df = pd.DataFrame(lof)
		print(df.to_csv(index=False, header = False))


'''
Link: https://www.lintcode.com/problem/shortest-path-in-undirected-graph/description
'''

# Uses bidirectional BFS. I closesly followed the teachings on Jiuzhang.com.
from collections import deque
class Solution:
    """
    @param graph: a list of Undirected graph node
    @param A: nodeA
    @param B: nodeB
    @return:  the length of the shortest path
    """
    def shortestPath(self, graph, A, B):
        # Write your code here
        length = 0
        if A == B:
            return length
        queue_a, queue_b = deque([A]), deque([B])
        a_visited, b_visited = set([A]), set([B])
        while len(queue_a) and len(queue_b):
            size_queue_a, size_queue_b = len(queue_a), len(queue_b)
            if size_queue_a > 0:
                length += 1
            for _ in range(size_queue_a):
                node = queue_a.popleft()
                for neib in node.neighbors:
                    if neib in a_visited:
                        continue
                    if neib in b_visited:
                        return length
                    queue_a.append(neib)
                    a_visited.add(neib)
            if size_queue_b > 0:
                length += 1
            for _ in range(size_queue_b):
                node = queue_b.popleft()
                for neib in node.neighbors:
                    if neib in b_visited:
                        continue
                    if neib in a_visited:
                        return length
                    queue_b.append(neib)
                    b_visited.add(neib)

        return -1


from django.urls import path
from .views import RegistrationView, CustomLoginView, CustomLogoutView, ProfileView, UserProfileUpdateView, UserEducationalUpdateView

urlpatterns = [
    path('register/', RegistrationView.as_view(), name='register'),
    path('login/', CustomLoginView.as_view(), name='login'),
    path('logout/', CustomLogoutView.as_view(), name='logout'),
    path('profile/', ProfileView.as_view(), name='profile'),
    path('profile-update/', UserProfileUpdateView.as_view(), name='profile_update'),
    path('educational-update/', UserEducationalUpdateView.as_view(), name='educational_update'),
]


"""Form definitions."""
from braces.forms import UserKwargModelFormMixin

from crispy_forms.helper import FormHelper, Layout
from crispy_forms.layout import Fieldset, Submit

from django import forms
from django.utils.translation import gettext_lazy as _

from .models import Sheet

class SheetForm(UserKwargModelFormMixin, forms.ModelForm):
    """ModelForm for the Sheet model."""

    class Meta:  # noqa: D101
        model = Sheet
        fields = ['exercises']

    def __init__(self, *args, **kwargs):
        """Add crispy-forms helper and layout to form."""
        super(SheetForm, self).__init__(*args, **kwargs)

        # add Crispy Forms foo
        self.helper = FormHelper()
        self.helper.form_id = 'id-SheetForm'
        self.helper.add_input(Submit('continue', 'Save & continue editing'))
        self.helper.add_input(Submit('submit', 'Save'))

        self.helper.layout = Layout(
            Fieldset(
                _('sheet form'),
                'exercises',
            ),
        )


from django.contrib.auth.models import AbstractUser, Group
from django.db import models

class User(AbstractUser):
    CREATOR = 'CREATOR'
    SUBSCRIBER = 'SUBSCRIBER'
    ROLE_CHOICES = (
        (CREATOR, 'Créateur'),
        (SUBSCRIBER, 'Abonné'),
    )
    profile_photo = models.ImageField(verbose_name='Photo de profil')
    role = models.CharField(max_length=30, choices=ROLE_CHOICES, verbose_name='Rôle')
    follows = models.ManyToManyField(
        'self', # Model en relation: les utilisateurs suivent d'autres utilisateurs. donc le même model
        limit_choices_to={'role': CREATOR}, # On ne peut suivre que les créateurs
        symmetrical=False, # True si on suit un utilisateur amis.
        verbose_name='suit',
    )

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)

        if self.role == self.CREATOR:
            group = Group.objects.get(name='creators')
            group.user_set.add(self)
        elif self.role == self.SUBSCRIBER:
            group = Group.objects.get(name='subscribers')
            group.user_set.add(self)


from datetime import datetime
import json
from odd_utils import *

VERSION = "1.0"

def shallow_copy(data) -> dict:
    if type(data) is list:
        return traverse(data)
    elif(type(data) is str):
        with open(data, "r") as f:
            return shallow_copy(json.load(f))
    else:
        return traverse(data)
def traverse(data) -> dict:
    fields = dict()
    if(type(data) in odd_primitives):
        return odd_primitives[type(data)]
    elif(data is None or len(data) < 1):
        raise Exception("Data provided is either invalid or empty")
    elif(type(data) is list and len(data) > 0):
        temp_list = list()
        temp_list.append(traverse(data[0]))
        return temp_list
    elif(type(data) is dict and len(data) > 0):
        for key, value in data.items():
            d_type = type(value)
            if(d_type in odd_primitives):
                fields[key] = odd_primitives[d_type]
            elif(d_type is dict and len(value) > 0):
                fields[key] = traverse(value)
            elif(d_type is list and len(value) > 0):
                temp_list = list()
                temp_list.append(traverse(value[0]))
                fields[key] = temp_list
            else:
                fields[key] = odd.EMPTY.value
    else:
        fields[key] = odd.EMPTY.value
    return fields


import torch
import torch.nn as nn
import torch.nn.functional as F
from torch import Tensor
from dptb.nnet.mlp import MLP
from dptb.utils.tools import _get_activation_fn
from typing import Optional, Any, Union, Callable

class ResBlock(nn.Module):
    def __init__(self, n_in, n_hidden, n_out, activation: Union[str, Callable[[Tensor], Tensor]] = F.relu, if_batch_normalized=False, device='cpu', dtype=torch.float32):
        super(ResBlock, self).__init__()
        self.layer = MLP(n_in, n_hidden, n_out, if_batch_normalized=if_batch_normalized, device=device, dtype=dtype, activation=activation)
        self.n_out = n_out
        self.n_in = n_in
        if isinstance(activation, str):
            self.activation = _get_activation_fn(activation)
        else:
            self.activation = activation

    def __setstate__(self, state):
        pass
        # super(ResBlock, self).__setstate__(state)

    def forward(self, x):
        out = self.layer(x)
        if self.n_in < self.n_out:
            out = nn.functional.interpolate(x.unsqueeze(1), size=[self.n_out]).squeeze(1) + out
        elif self.n_in == self.n_out:
            out = x + out
        else:
            out = nn.functional.adaptive_avg_pool1d(input=x, output_size=self.n_out) + out

        out = self.activation(out)

        return out

class ResNet(nn.Module):
    def __init__(self, config, activation, if_batch_normalized=False, device='cpu', dtype=torch.float32):
        super(ResNet, self).__init__()
        self.layers = nn.ModuleList([])
        for kk in range(len(config)-1):
            self.layers.append(ResBlock(**config[kk], if_batch_normalized=if_batch_normalized, activation=activation, device=device, dtype=dtype))
        if isinstance(activation, str):
            self.activation = _get_activation_fn(activation)
        else:
            self.activation = activation

        if config[-1].get('n_hidden') is None:
            self.out_layer = nn.Linear(in_features=config[-1]['n_in'], out_features=config[-1]['n_out'], device=device, dtype=dtype)
            # nn.init.normal_(self.out_layer.weight, mean=0, std=1e-3)
            # nn.init.normal_(self.out_layer.bias, mean=0, std=1e-3)
        else:
            self.out_layer = MLP(**config[-1],  if_batch_normalized=False, activation=activation, device=device, dtype=dtype)

    def forward(self, x):
        for layer in self.layers:
            x = layer(x)
            x = self.activation(x)

        return self.out_layer(x)

if __name__ == '__main__':
    config = [
        {'n_in': 3, 'n_hidden': 4, 'n_out': 8},
        {'n_in': 8, 'n_hidden': 6, 'n_out': 4}
    ]
    net = ResNet(config, activation='relu', if_batch_normalized=True)

    a = torch.randn(100, 3)

    print(net(a).size())


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

from threading import Thread, Event
from yasc.utils import CONFIG, state, ZoneAction, in_production, ControllerMode
from datetime import datetime, timedelta
from time import sleep
import logging

# RPi imports not working
if in_production():
    from yasc.pi_controller import get_active_zone, activate_zone, stop_sprinkler
else:
    __dev_zone = 0

    def activate_zone(zone):
        logging.debug('Activation zone {0}.'.format(zone))
        global __dev_zone
        __dev_zone = zone
        state.zone_on(zone)

    def get_active_zone():
        return __dev_zone

    def stop_sprinkler():
        logging.debug('Stopping sprinkler zone')
        global __dev_zone
        if __dev_zone > 0:
            logging.debug('Stopping zone {0}.'.format(__dev_zone))
            state.zone_off(__dev_zone)
            __dev_zone = 0

# FIXME: use thread pool

class ManualRunner(Thread):
    def __init__(self, zone, interval):
        Thread.__init__(self, name='Zone Run')
        self.__interval = interval
        self.__zone = zone
        self.__stop = Event()

    def stop(self):
        logging.info('Stop manual run for zone {0}.'.format(self.__zone))
        if not self.__stop.is_set():
            self.__stop.set()

    def run(self):
        state.single_zone_on()
        start_time = datetime.now()
        activate_zone(self.__zone)
        while not self.__stop.is_set():
            now = datetime.now()
            timediff = timedelta(minutes=self.__interval) if in_production() else timedelta(seconds=self.__interval)
            if now - start_time > timediff:
                self.__stop.set()
            sleep(1)
        stop_sprinkler()
        state.run_off()
        logging.info('Manual run for zone {0} end.'.format(self.__zone))

class CycleRunner(Thread):
    def __init__(self, interval):
        Thread.__init__(self, name='Cycle Run')
        self.__interval = interval
        self.__stop = Event()

    def stop(self):
        logging.info('Stop cycle.')
        if not self.__stop.is_set():
            self.__stop.set()

    def __start_zone(self, zone_index):
        zone_info = CONFIG.active_zones[zone_index]
        activate_zone(zone_info.zone)

        interval = getattr(zone_info, "interval", self.__interval)
        logging.info('Running zone {0} for {1} min/sec.'.format(zone_info.zone, interval))
        return datetime.now(), timedelta(minutes=interval) if in_production() else timedelta(seconds=interval)

    def run(self):
        logging.info('Starting cycle.')
        state.cycle_on()
        zone_index = 0
        zone_count = len(CONFIG.active_zones)
        start_time, interval = self.__start_zone(zone_index)
        while not self.__stop.is_set():
            now = datetime.now()
            if now - start_time > interval:
                zone_index += 1
                if zone_index < zone_count:
                    stop_sprinkler()
                    start_time, interval = self.__start_zone(zone_index)
                else:
                    self.__stop.set()
            sleep(1)
        stop_sprinkler()
        state.run_off()
        logging.info('Cycle end.')

class ZoneController(Thread):
    def __init__(self):
        Thread.__init__(self, name='Zone Controller')
        self.__stop = Event()
        self.__manual_runner = None
        self.__cycle_runner = None

    def __stop_cycle_runner(self):
        if self.__cycle_runner is not None and self.__cycle_runner.is_alive():
            logging.warning('Cycle is running. Terminating...')
            self.__cycle_runner.stop()
            self.__cycle_runner.join()
            self.__cycle_runner = None

    def is_cycle_running(self):
        return self.__cycle_runner is not None and self.__cycle_runner.is_alive()

    def __stop_manual_runner(self):
        if self.__manual_runner is not None and self.__manual_runner.is_alive():
            logging.warning('Manual runner is acitve. Terminating...')
            self.__manual_runner.stop()
            self.__manual_runner.join()
            self.__manual_runner = None

    def is_manual_running(self):
        return self.__manual_runner is not None and self.__manual_runner.is_alive()

    def get_active_zone(self):
        return get_active_zone()

    def stop(self):
        if not self.__stop.is_set():
            self.__stop.set()
        self.__stop_manual_runner()
        self.__stop_cycle_runner()
        state.run_zone_action((ZoneAction.TERMINATE, 0))
        self.join()

    def control_mode_changed(self):
        if state.active_controller_mode() is ControllerMode.OFF:
            state.run_zone_action((ZoneAction.STOP, 0))

    def __get_zone_index(self, zone):
        for index, zone_info in enumerate(CONFIG.active_zones):
            if zone_info.zone == zone:
                return index
        return -1

    def __zone_in_active_zones(self, zone):
        for zone_info in CONFIG.active_zones:
            if zone_info.zone == zone:
                return True
        return False

    def __queue_processor(self, queue):
        action_type, event_value = queue.get()
        logging.debug('Received action {0} with event value {1}.'.format(action_type, event_value))
        self.__stop_manual_runner()
        self.__stop_cycle_runner()
        if action_type in [ZoneAction.TERMINATE, ZoneAction.STOP]:
            # Leave dummy for now
            pass
        elif action_type == ZoneAction.RUN_CYCLE:
            self.__cycle_runner = CycleRunner(CONFIG.default_interval)
            self.__cycle_runner.start()
        elif action_type == ZoneAction.NEXT:
            current_active = get_active_zone()
            current_index = self.__get_zone_index(current_active)
            next_index = current_index + 1
            if -1 < next_index < len(CONFIG.active_zones):
                zone = CONFIG.active_zones[next_index].zone
                self.__manual_runner = ManualRunner(zone, CONFIG.default_interval)
                self.__manual_runner.start()
            else:
                logging.debug('Next index {0} outside active zone range. Stop yasc.'.format(next_index))
        elif action_type == ZoneAction.ZONE:
            if self.__zone_in_active_zones(event_value):
                self.__manual_runner = ManualRunner(event_value, CONFIG.default_interval)
                self.__manual_runner.start()
            else:
                logging.error('Zone {0} is not an active zone!'.format(event_value))

        queue.task_done()

    def run(self):
        logging.info('Zone Controller started')
        while not self.__stop.is_set():
            state.process_queue(self.__queue_processor)

        logging.info('Zone Controller stopped')


import cv2
import torch
from PIL import Image
from utils.segmenter import Segmenter
from utils.type_conversion import *

def resize(img, short_size):
    w, h = img.size
    if w < h:
        nw, nh = short_size, int(w * short_size / h)
    else:
        nw, nh = int(h * short_size / w), short_size

    return img.resize((nh, nw))

def test_image(args, model):
    if args.detector == 'dlib':
        import dlib
    elif args.detector == 'faceboxes':
        from utils.face_detector import FaceDetectorFaceboxes

    model.eval()

    device = torch.device("cuda" if args.gpu else "cpu")

    image = Image.open(args.image).convert('RGB')

    if args.resize > 0:
        image = resize(image, args.resize)

    detector = None
    if args.detector == 'dlib':
        detector = dlib.get_frontal_face_detector()
    elif args.detector == 'faceboxes':
        MODEL_PATH = 'model/faceboxes.pb'
        detector = FaceDetectorFaceboxes(MODEL_PATH, gpu_memory_fraction=0.25, visible_device_list='0')

    segmenter = Segmenter(model, device, detector, mode=args.detector)

    result = segmenter.segment(PIL2opencv(image), args.remove_small_area)
    result = opencv2PIL(result)

    if args.save:
        result.save(args.save)

    if not args.unshow:
        result.show()
        image.show()

def test_video(args, model):
    if args.video == '0':
        cap = cv2.VideoCapture(0)
    else:
        cap = cv2.VideoCapture(args.video)

    w_win = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    h_win = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

    print(w_win, h_win)

    if args.resize > 0:
        short_size = args.resize
        if w_win > h_win:
            nw, nh = short_size, int(w_win * short_size / h_win)
        else:
            nw, nh = int(h_win * short_size / w_win), short_size
    else:
        nw, nh = w_win, h_win

    detector = None
    if args.detector == 'dlib':
        detector = dlib.get_frontal_face_detector()
    elif args.detector == 'faceboxes':
        MODEL_PATH = 'model/faceboxes.pb'
        detector = FaceDetectorFaceboxes(MODEL_PATH, gpu_memory_fraction=0.25, visible_device_list='0')

    device = torch.device("cuda" if args.gpu else "cpu")
    segmenter = Segmenter(model, device, detector, mode=args.detector)

    if args.save:
        fourcc = cv2.VideoWriter_fourcc(*'MJPG')
        out = cv2.VideoWriter(args.save, fourcc, 20, (nh, nw), True)

    while True:
        frame = cap.read()[1]

        if frame is None:
            break

        frame = cv2.resize(frame, (nh, nw))

        result = segmenter.segment(frame, args.remove_small_area)

        if args.save:
            out.write(result)

        if not args.unshow:
            cv2.imshow('image', result)

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    cap.release()
    cv2.destroyAllWindows()

    if args.save:
        out.release()


"""Django FilterSet classes for Nautobot."""

import django_filters
from nautobot.apps.filters import BaseFilterSet, NautobotFilterSet, SearchFilter

from nautobot_chatops.choices import PlatformChoices
from nautobot_chatops.models import CommandLog, AccessGrant, ChatOpsAccountLink, CommandToken

class CommandLogFilterSet(BaseFilterSet):
    """FilterSet for filtering a set of CommandLog objects."""

    class Meta:
        """Metaclass attributes of CommandLogFilterSet."""

        model = CommandLog
        fields = [
            "start_time",
            "runtime",
            "user_name",
            "user_id",
            "platform",
            "command",
            "subcommand",
            "status",
            "details",
        ]

class AccessGrantFilterSet(BaseFilterSet):
    """FilterSet for filtering a set of AccessGrant objects."""

    class Meta:
        """Metaclass attributes of AccessGrantFilterSet."""

        model = AccessGrant
        fields = ["command", "subcommand", "grant_type", "value"]

class ChatOpsAccountLinkFilterSet(NautobotFilterSet):
    """FilterSet for filtering the ChatOps Account Links."""

    q = SearchFilter(
        filter_predicates={
            "user_id": "icontains",
            "platform": "icontains",
        }
    )
    platform = django_filters.MultipleChoiceFilter(choices=PlatformChoices)

    class Meta:
        """Metaclass attributes of ChatOpsAccountLinkFilterSet."""

        model = ChatOpsAccountLink
        fields = "__all__"

class CommandTokenFilterSet(BaseFilterSet):
    """FilterSet for filtering a set of CommandToken objects."""

    class Meta:
        """Metaclass attributes of CommandTokenFilterSet."""

        model = CommandToken
        fields = ["comment", "platform"]


from django.urls import path, include
from . import views

app_name = "accounts"

urlpatterns = [
    # login
    path("login/", views.LoginView.as_view(), name="login"),
    # logout
    path("logout/", views.LogoutView.as_view(), name="logout"),
    # signup
    path("signup/", views.SignupView.as_view(), name="signup"),
    # api
    path("api/v1/", include("accounts.api.v1.urls")),
]


import unittest
import warnings
from datetime import date, datetime
from decimal import Decimal

import pytz
from babel import Locale

from fluent.runtime.types import FluentDateType, FluentNumber, fluent_date, fluent_number

class TestFluentNumber(unittest.TestCase):

    locale = Locale.parse('en_US')

    def setUp(self):
        self.cur_pos = fluent_number(123456.78123,
                                     currency='USD',
                                     style='currency')
        self.cur_neg = fluent_number(-123456.78123,
                                     currency='USD',
                                     style='currency')

    def test_int(self):
        i = fluent_number(1)
        self.assertTrue(isinstance(i, int))
        self.assertTrue(isinstance(i, FluentNumber))
        self.assertEqual(i + 1, 2)

    def test_float(self):
        f = fluent_number(1.1)
        self.assertTrue(isinstance(f, float))
        self.assertTrue(isinstance(f, FluentNumber))
        self.assertEqual(f + 1, 2.1)

    def test_decimal(self):
        d = Decimal('1.1')
        self.assertTrue(isinstance(fluent_number(d), Decimal))
        self.assertTrue(isinstance(fluent_number(d), FluentNumber))
        self.assertEqual(d + 1, Decimal('2.1'))

    def test_disallow_nonexistant_options(self):
        self.assertRaises(
            TypeError,
            fluent_number,
            1,
            not_a_real_option=True,
        )

    def test_style_validation(self):
        self.assertRaises(ValueError,
                          fluent_number,
                          1,
                          style='xyz')

    def test_use_grouping(self):
        f1 = fluent_number(123456.78, useGrouping=True)
        f2 = fluent_number(123456.78, useGrouping=False)
        self.assertEqual(f1.format(self.locale), "123,456.78")
        self.assertEqual(f2.format(self.locale), "123456.78")
        # ensure we didn't mutate anything when we created the new
        # NumberPattern:
        self.assertEqual(f1.format(self.locale), "123,456.78")

    def test_use_grouping_decimal(self):
        d = Decimal('123456.78')
        f1 = fluent_number(d, useGrouping=True)
        f2 = fluent_number(d, useGrouping=False)
        self.assertEqual(f1.format(self.locale), "123,456.78")
        self.assertEqual(f2.format(self.locale), "123456.78")

    def test_minimum_integer_digits(self):
        f = fluent_number(1.23, minimumIntegerDigits=3)
        self.assertEqual(f.format(self.locale), "001.23")

    def test_minimum_integer_digits_decimal(self):
        f = fluent_number(Decimal('1.23'), minimumIntegerDigits=3)
        self.assertEqual(f.format(self.locale), "001.23")

    def test_minimum_fraction_digits(self):
        f = fluent_number(1.2, minimumFractionDigits=3)
        self.assertEqual(f.format(self.locale), "1.200")

    def test_maximum_fraction_digits(self):
        f1 = fluent_number(1.23456)
        self.assertEqual(f1.format(self.locale), "1.235")
        f2 = fluent_number(1.23456, maximumFractionDigits=5)
        self.assertEqual(f2.format(self.locale), "1.23456")

    def test_minimum_significant_digits(self):
        f1 = fluent_number(123, minimumSignificantDigits=5)
        self.assertEqual(f1.format(self.locale), "123.00")
        f2 = fluent_number(12.3, minimumSignificantDigits=5)
        self.assertEqual(f2.format(self.locale), "12.300")

    def test_maximum_significant_digits(self):
        f1 = fluent_number(123456, maximumSignificantDigits=3)
        self.assertEqual(f1.format(self.locale), "123,000")
        f2 = fluent_number(12.3456, maximumSignificantDigits=3)
        self.assertEqual(f2.format(self.locale), "12.3")
        f3 = fluent_number(12, maximumSignificantDigits=5)
        self.assertEqual(f3.format(self.locale), "12")

    def test_currency(self):
        # This test the default currencyDisplay value
        self.assertEqual(self.cur_pos.format(self.locale), "$123,456.78")

    def test_currency_display_validation(self):
        self.assertRaises(ValueError,
                          fluent_number,
                          1234,
                          currencyDisplay="junk")

    def test_currency_display_symbol(self):
        cur_pos_sym = fluent_number(self.cur_pos, currencyDisplay="symbol")
        cur_neg_sym = fluent_number(self.cur_neg, currencyDisplay="symbol")
        self.assertEqual(cur_pos_sym.format(self.locale), "$123,456.78")
        self.assertEqual(cur_neg_sym.format(self.locale), "-$123,456.78")

    def test_currency_display_code(self):
        # Outputs here were determined by comparing with Javascrpt
        # Intl.NumberFormat in Firefox.
        cur_pos_code = fluent_number(self.cur_pos, currencyDisplay="code")
        cur_neg_code = fluent_number(self.cur_neg, currencyDisplay="code")
        self.assertEqual(cur_pos_code.format(self.locale), "USD123,456.78")
        self.assertEqual(cur_neg_code.format(self.locale), "-USD123,456.78")

    @unittest.skip("Babel doesn't provide support for this yet")
    def test_currency_display_name(self):
        cur_pos_name = fluent_number(self.cur_pos, currencyDisplay="name")
        cur_neg_name = fluent_number(self.cur_neg, currencyDisplay="name")
        self.assertEqual(cur_pos_name.format(self.locale), "123,456.78 US dollars")
        self.assertEqual(cur_neg_name.format(self.locale), "-123,456.78 US dollars")

        # Some others locales:
        hr_BA = Locale.parse('hr_BA')
        self.assertEqual(cur_pos_name.format(hr_BA),
                         "123.456,78 američkih dolara")
        es_GT = Locale.parse('es_GT')
        self.assertEqual(cur_pos_name.format(es_GT),
                         "dólares estadounidenses 123,456.78")

    def test_copy_attributes(self):
        f1 = fluent_number(123456.78, useGrouping=False)
        self.assertEqual(f1.options.useGrouping, False)

        # Check we didn't mutate anything
        self.assertIs(FluentNumber.default_number_format_options.useGrouping, True)

        f2 = fluent_number(f1, style="percent")
        self.assertEqual(f2.options.style, "percent")

        # Check we copied
        self.assertEqual(f2.options.useGrouping, False)

        # and didn't mutate anything
        self.assertEqual(f1.options.style, "decimal")
        self.assertEqual(FluentNumber.default_number_format_options.style, "decimal")

class TestFluentDate(unittest.TestCase):

    locale = Locale.parse('en_US')

    def setUp(self):
        self.a_date = date(2018, 2, 1)
        self.a_datetime = datetime(2018, 2, 1, 14, 15, 16, 123456,
                                   tzinfo=pytz.UTC)

    def test_date(self):
        fd = fluent_date(self.a_date)
        self.assertTrue(isinstance(fd, date))
        self.assertTrue(isinstance(fd, FluentDateType))
        self.assertEqual(fd.year, self.a_date.year)
        self.assertEqual(fd.month, self.a_date.month)
        self.assertEqual(fd.day, self.a_date.day)

    def test_datetime(self):
        fd = fluent_date(self.a_datetime)
        self.assertTrue(isinstance(fd, datetime))
        self.assertTrue(isinstance(fd, FluentDateType))
        self.assertEqual(fd.year, self.a_datetime.year)
        self.assertEqual(fd.month, self.a_datetime.month)
        self.assertEqual(fd.day, self.a_datetime.day)
        self.assertEqual(fd.hour, self.a_datetime.hour)
        self.assertEqual(fd.minute, self.a_datetime.minute)
        self.assertEqual(fd.second, self.a_datetime.second)
        self.assertEqual(fd.microsecond, self.a_datetime.microsecond)
        self.assertEqual(fd.tzinfo, self.a_datetime.tzinfo)

    def test_format_defaults(self):
        fd = fluent_date(self.a_date)
        en_US = Locale.parse('en_US')
        en_GB = Locale.parse('en_GB')
        self.assertEqual(fd.format(en_GB), '1 Feb 2018')
        self.assertEqual(fd.format(en_US), 'Feb 1, 2018')

    def test_dateStyle_date(self):
        fd = fluent_date(self.a_date, dateStyle='long')
        en_US = Locale.parse('en_US')
        en_GB = Locale.parse('en_GB')
        self.assertEqual(fd.format(en_GB), '1 February 2018')
        self.assertEqual(fd.format(en_US), 'February 1, 2018')

    def test_dateStyle_datetime(self):
        fd = fluent_date(self.a_datetime, dateStyle='long')
        en_US = Locale.parse('en_US')
        en_GB = Locale.parse('en_GB')
        self.assertEqual(fd.format(en_GB), '1 February 2018')
        self.assertEqual(fd.format(en_US), 'February 1, 2018')

    def test_timeStyle_datetime(self):
        fd = fluent_date(self.a_datetime, timeStyle='short')
        en_US = Locale.parse('en_US')
        en_GB = Locale.parse('en_GB')
        self.assertRegex(fd.format(en_US), '^2:15\\sPM$')
        self.assertEqual(fd.format(en_GB), '14:15')

    def test_dateStyle_and_timeStyle_datetime(self):
        fd = fluent_date(self.a_datetime, timeStyle='short', dateStyle='short')
        en_US = Locale.parse('en_US')
        en_GB = Locale.parse('en_GB')
        self.assertRegex(fd.format(en_US), '^2/1/18, 2:15\\sPM$')
        self.assertEqual(fd.format(en_GB), '01/02/2018, 14:15')

    def test_validate_dateStyle(self):
        self.assertRaises(ValueError,
                          fluent_date,
                          self.a_date,
                          dateStyle="nothing")

    def test_validate_timeStyle(self):
        self.assertRaises(ValueError,
                          fluent_date,
                          self.a_datetime,
                          timeStyle="nothing")

    def test_timeZone(self):
        en_GB = Locale.parse('en_GB')
        LondonTZ = pytz.timezone('Europe/London')

        # 1st July is a date in British Summer Time

        # datetime object with tzinfo set to BST
        dt1 = datetime(2018, 7, 1, 23, 30, 0, tzinfo=pytz.UTC).astimezone(LondonTZ)
        fd1 = fluent_date(dt1, dateStyle='short', timeStyle='short')
        self.assertEqual(fd1.format(en_GB), '02/07/2018, 00:30')
        fd1b = fluent_date(dt1, dateStyle='full', timeStyle='full')
        self.assertRegex(fd1b.format(en_GB), '^Monday, 2 July 2018(,| at) 00:30:00 British Summer Time$')
        fd1c = fluent_date(dt1, dateStyle='short')
        self.assertEqual(fd1c.format(en_GB), '02/07/2018')
        fd1d = fluent_date(dt1, timeStyle='short')
        self.assertEqual(fd1d.format(en_GB), '00:30')

        # datetime object with no TZ, TZ passed in to fluent_date
        dt2 = datetime(2018, 7, 1, 23, 30, 0)  # Assumed UTC
        fd2 = fluent_date(dt2, dateStyle='short', timeStyle='short',
                          timeZone='Europe/London')
        self.assertEqual(fd2.format(en_GB), '02/07/2018, 00:30')
        fd2b = fluent_date(dt2, dateStyle='full', timeStyle='full',
                           timeZone='Europe/London')
        self.assertRegex(fd2b.format(en_GB), '^Monday, 2 July 2018(,| at) 00:30:00 British Summer Time$')
        fd2c = fluent_date(dt2, dateStyle='short',
                           timeZone='Europe/London')
        self.assertEqual(fd2c.format(en_GB), '02/07/2018')
        fd2d = fluent_date(dt1, timeStyle='short',
                           timeZone='Europe/London')
        self.assertEqual(fd2d.format(en_GB), '00:30')

    def test_allow_unsupported_options(self):
        # We are just checking that these don't raise exceptions
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            fluent_date(self.a_date,
                        hour12=True,
                        weekday="narrow",
                        era="narrow",
                        year="numeric",
                        month="numeric",
                        day="numeric",
                        hour="numeric",
                        minute="numeric",
                        second="numeric",
                        timeZoneName="short",
                        )

    def test_disallow_nonexistant_options(self):
        self.assertRaises(
            TypeError,
            fluent_date,
            self.a_date,
            not_a_real_option=True,
        )

    def test_dont_wrap_unnecessarily(self):
        f1 = fluent_date(self.a_date)
        f2 = fluent_date(f1)
        self.assertIs(f1, f2)

    def test_copy_attributes(self):
        f1 = fluent_date(self.a_date, dateStyle='long', hour12=False)
        self.assertEqual(f1.options.dateStyle, 'long')

        f2 = fluent_date(f1, hour12=False)

        # Check we copied other attributes:
        self.assertEqual(f2.options.dateStyle, "long")
        self.assertEqual(f2.options.hour12, False)

        # Check we can override
        f3 = fluent_date(f2, dateStyle="full")
        self.assertEqual(f3.options.dateStyle, "full")

        # and didn't mutate anything
        self.assertEqual(f1.options.dateStyle, "long")
        self.assertEqual(f2.options.dateStyle, "long")


import json
import re
from typing import Any, Dict, List, Text

from airflow.exceptions import AirflowException
from airflow.providers.google.cloud.hooks.datacatalog import CloudDataCatalogHook
import google.auth.transport.requests
from google.auth.transport.urllib3 import AuthorizedHttp
from grizzly.config import Config
from grizzly.etl_action import parse_table
from grizzly.grizzly_typing import TGrizzlyOperator

_TPolicyTags = Dict[str, str]

class DataCatalogTag:
  """Perform actions with DataCatalog.

  Should be used for Data Catalog Table and column tags.
  Assign Column level security throw DataCatalog Taxonomy.

  Attributes:
    execution_context (GrizzlyOperator): Instance of GrizzlyOperator executed.
    column_policy_tags (list[dict]): List of Column level policy (security) tags
      to be applied in format
      { 'column_name': 'column_policy_tag_id'}
    datacatalog_tags (list[dict]): Content of JSON file defined in
      [data_catalog_tags] attribute of task YML file. Content is rendered as
      JINJA2 template and loaded as list of dictionaries with definition of
      table and column tags to be applied.
    authed_http (google.auth.transport.urllib3.AuthorizedHttp): Authorized http
      connection for work with Data Catalog Rest API.
    base_api_url (string): Base URL for work with DataCatalog Rest API.
    dc_hook (CloudDataCatalogHook):
      Airflow predefined hooks for work with GCP Data Catalog.
  """

  def __init__(self,
               execution_context: TGrizzlyOperator,
               column_policy_tags: List[_TPolicyTags],
               datacatalog_tags: List[Text]) -> None:
    """Set up DataCatalogTag instance.

    If [column_policy_tags] or [datacatalog_tags] was defined set up
    correspondent class properties.

    Args:
      execution_context (TGrizzlyOperator): Instance of GrizzlyOperator
        executed.
      column_policy_tags (list): List of Column level policy (security)
        tags to be applied in format
        {'column_name': 'taxonomy|tag_hierarchy'}
        Contains column level security configuration.
      datacatalog_tags (list): Content of JSON file defined in
        [data_catalog_tags] attribute of task YML file. Content is rendered as
        JINJA2 template and loaded as list of dictionaries with definition of
        table and column tags to be applied. Contains Table and column tags.
    """
    self.execution_context = execution_context
    if column_policy_tags or datacatalog_tags:
      self.__setup_datacatalog_connection()

    if column_policy_tags:
      # Get list of DataCatalog security policy tag mapping
      self.column_policy_tags = self.__get_column_policy_tags_mapping(
          column_policy_tags)
    else:
      self.column_policy_tags = None
    if datacatalog_tags:
      self.datacatalog_tags = datacatalog_tags
    else:
      self.datacatalog_tags = None

  def __get_table_entry_id(self, target_table: Dict[str, str]) -> Any:
    """Get an DataCatalog EntryId by table name."""
    target_table = parse_table(target_table)
    resource_name = (f'//bigquery.googleapis.com/'
                     f'projects/{target_table["project_id"]}/'
                     f'datasets/{target_table["dataset_id"]}/'
                     f'tables/{target_table["table_id"]}')
    table_entry = self.dc_hook.lookup_entry(linked_resource=resource_name)
    return table_entry

  def __setup_datacatalog_connection(self) -> None:
    """Setup connection credentials for access Data Catalog API."""
    scopes = ['https://www.googleapis.com/auth/cloud-platform']
    # pylint: disable=unused-variable
    credentials, project = google.auth.default(scopes=scopes)

    auth_req = google.auth.transport.requests.Request()
    credentials.refresh(auth_req)
    self.authed_http = AuthorizedHttp(credentials)
    access_token = credentials.token
    self.base_api_url = (
        'https://datacatalog.googleapis.com/v1/{api_call}?access_token='
        + access_token)
    # setup datacatalog hooks
    self.dc_hook = CloudDataCatalogHook()

  def __get_column_policy_tags_mapping(
      self,
      column_policy_tags: List[_TPolicyTags]
  ) -> _TPolicyTags:
    """Return a list of all applicable taxonomies for job/table.

    Parse user defined format from task YML file and transform it into format
    consumable by DataCatalog Rest API.
    Method gets all taxonomy list on environment. Then select taxonomy defined
    by user and parses taxonomy tag hierarchy to find [column_policy_tag_id]
    that matches with taxonomy tag hierarchy defined by user in task YML file
    attribute [column_policy_tags].

    Args:
      column_policy_tags (list[dict]): List of column policy tag definition to
        be parsed in format: {'column_name': 'taxonomy|tag_hierarchy'}

    Raises:
      AirflowException: Raise error in case if Column policy taxonomy as not
        defined on target GCP project or if user defined reference to policy tag
        that does not exist.

    Returns:
      (dict): List of column policy tag definition in format
        {'column_name': 'column_policy_tag_id'}
    """
    column_policy_tags_mapping = {}
    # get a set of all applicable taxonomies
    # accordingly to job YML configuration [column_policy_tags]
    requested_taxonomies = set()
    for c in column_policy_tags:
      for v in c.values():
        # Add taxonomy name to set
        requested_taxonomies.add(v.split('|')[0])

    # Get list of DataCatalog taxonomies
    api_call = Config.DEFAULT_DATACATALOG_TAXONOMY_LOCATION
    session_url = self.base_api_url.format(api_call=api_call)
    r = self.authed_http.urlopen(method='get', url=session_url)
    taxonomy_mapping = {
    }
    # looks like {'taxonomy_name': 'projects/prj_id/locations/us/taxonomies/64'}
    if r.status == 200:
      response = json.loads(r.data)
      # work only with taxonomies that were requested in YML
      taxonomy_mapping = {
          i['displayName']: i['name']
          for i in response['taxonomies']
          if i['displayName'] in requested_taxonomies
      }
      # extract raw list of tags for each taxonomy
      for k, v in taxonomy_mapping.items():
        taxonomy_tag_list_raw = self.__get_taxonomy_policy_tags_raw(v)
        for t in taxonomy_tag_list_raw:
          column_policy_tags_mapping.update(
              self.__get_tag_hierarchy(
                  taxonomy_name=k, raw_data=taxonomy_tag_list_raw, tag=t))
    else:
      raise AirflowException(
          ('Could not receive a list of taxonomies for '
           f'project {Config.GCP_PROJECT_ID}. Check security configuration '
           'for service account.')
      )

    # iterate requested tags.
    # raise Exception if taxonomy does not exist in project
    for ct in column_policy_tags:
      for column, tag in ct.items():
        if tag not in column_policy_tags_mapping:
          raise AirflowException(
              (f'Check your YML configuration. Column [{column}] : Tag [{tag}] '
               'does not exist in GCP Data Catalog.')
          )
    # transform array column policy mapping into dictionary with correct tag Ids
    column_policy_tags_resultset = dict()
    for c in column_policy_tags:
      for key in c:
        column_policy_tags_resultset[key] = column_policy_tags_mapping[c[key]]
    return column_policy_tags_resultset

  def __get_tag_hierarchy(self,
                          taxonomy_name: str,
                          raw_data: Any,
                          tag: Dict[str, Any],
                          tag_display_name: str = '',
                          tag_id: str = '') -> Dict[str, Any]:
    """Get Data Catalog Taxonomy tag hierarchy mapping.

    Method performs recursive scan of taxonomy tags hierarchy and creates
    mapping between DataCatalog policy tag id and human-readable
    representation of this tag in format similar to 'taxonomy|tag_hierarchy'

    Args:
      taxonomy_name (string): Human readable taxonomy name from
        [column_policy_tags] attribute defined in task YML raw_data.
      raw_data: Raw json response from DataCatalog Rest API.
      tag (dict): Rest API definition of policy tag. More details about format
        of dictionary you can find here:
        https://cloud.google.com/data-catalog/docs/reference/rest/v1/projects.locations.taxonomies.policyTags#PolicyTag
      tag_display_name (string): Tag name in human-readable format
        'parent_tag_1|parent_tag_1.1|tag'
      tag_id (string): Tag id in format supported by Data Catalog Rest API.
        projects/{project}/locations/{location}/taxonomies/{taxonomies}/policyTags/{policytag}

    Returns:
      (dict): List of column policy tag definition in format
        {'taxonomy_name|tag_display_name': 'tag_id'}
        For example:
        {
          'proto_column_access_policy|PII|high':
            'projects/prj/locations/us/taxonomies/11/policyTags/22'
        }
    """
    # parse raw taxonomy data and return tag hierarchy
    parent_id = tag.get('parentPolicyTag', None)
    tag_id = tag_id if tag_id else tag['name']
    tag_display_name = '|'.join([tag['displayName'], tag_display_name
                                ]) if tag_display_name else tag['displayName']
    # if tag not in a root of hierarchy
    if parent_id:
      # get parent tag details
      parent_tag = list(filter(lambda x: x['name'] == parent_id, raw_data))[0]
      return self.__get_tag_hierarchy(
          taxonomy_name=taxonomy_name,
          raw_data=raw_data,
          tag=parent_tag,
          tag_display_name=tag['displayName'],
          tag_id=tag_id)
    else:
      return {taxonomy_name + '|' + tag_display_name: tag_id}

  def __get_taxonomy_policy_tags_raw(self,
                                     taxonomy_id: str) -> List[Dict[str, Any]]:
    """Get a list of all policy tags inside Data Catalog Policy Tags taxonomy.

    Next Rest API call is used
    https://cloud.google.com/data-catalog/docs/reference/rest/v1/projects.locations.taxonomies.policyTags/list

    Args:
      taxonomy_id (string): Taxonomy id in format acceptable by Rest API
        projects/{project}/locations/{location}/taxonomies/{taxonomies}

    Raises:
      AirflowException: Raise exception in case if Data Catalog Rest API not
        able to retrieve list of tags inside taxonomy.

    Returns:
      (list(dict)): List of policy tags in format
        https://cloud.google.com/data-catalog/docs/reference/rest/v1/projects.locations.taxonomies.policyTags#PolicyTag
    """
    api_call = f'{taxonomy_id}/policyTags'
    session_url = self.base_api_url.format(api_call=api_call)
    r = self.authed_http.urlopen(method='GET', url=session_url)

    if r.status == 200:
      response = json.loads(r.data)
    else:
      raise AirflowException(
          f'Could not receive a tag list for taxonomy {taxonomy_id}.')
    return response['policyTags']

  def set_column_policy_tags(self, target_table: str) -> None:
    """Update column policy tags on target table.

    Assign Column policy tags from [self.column_policy_tags] to table columns on
    a base of column level security defined in attribute [column_policy_tags] of
    task YML file.

    Args:
      target_table (string): Name of a table on which you want to set up column
        level security.
    """
    if self.column_policy_tags:
      target_table = parse_table(target_table)
      table_schema_definition = self.execution_context.bq_cursor.get_schema(
          dataset_id=target_table['dataset_id'],
          table_id=target_table['table_id'])['fields']
      tagged_column_list = [*self.column_policy_tags
                           ]  # get list of tagged columns from dictionary
      # filter only columns that tagged
      # iterate schema and set policy tags
      for i in range(len(table_schema_definition)):
        cn = table_schema_definition[i]['name']
        if cn in tagged_column_list:
          table_schema_definition[i]['policyTags'] = {
              'names': [self.column_policy_tags[cn]]
          }
      # patch target table with updated fields
      self.execution_context.bq_cursor.patch_table(
          dataset_id=target_table['dataset_id'],
          table_id=target_table['table_id'],
          schema=table_schema_definition)
    return

  def set_table_tags(self, target_table: str) -> None:
    """Set DataCatalog tags on a table and table columns.

    Apply tags from self.datacatalog_tags. All tags that were not defined in
    JSON tag configuration file will be removed.

    Args:
      target_table (string): Target table  for which data catalog tags should
        be assigned.

    Raises:
      Exception: Exception raised in case if Rest API does not return Data
        Catalog EntityId for requested table.
      AirflowException: Also exception raised in case if application is not
        able to delete or create tags due some security restriction or other
        issues.
    """
    if self.datacatalog_tags:
      # get entry_id for target_table
      entry_id = self.__get_table_entry_id(target_table)
      # parse entry_id
      entry_id_parsed = re.match(
          (r'^projects/(?P<project_id>.+)/locations/(?P<location>.+)/'
           r'entryGroups/(?P<entry_group>.+)/entries/(?P<entry_id>.+)$'),
          entry_id.name)
      if not entry_id_parsed:
        raise AirflowException(
            f'Could not extract entity_id for [{target_table}].')
      # get a list of tags already assigned to table
      existing_table_tags = self.dc_hook.list_tags(
          location=entry_id_parsed['location'],
          entry_group=entry_id_parsed['entry_group'],
          entry=entry_id_parsed['entry_id'],
          project_id=entry_id_parsed['project_id'],
          page_size=500)
      # construct a list of (template, column) for requested tags
      requested_tags = [
          (t['template'], t.get('column', '')) for t in self.datacatalog_tags
      ]
      # drop existing tags in case of importance
      for et in existing_table_tags:
        tag_name = et.name
        tag_template = et.template
        tag_column = getattr(et, 'column', '')

        if (tag_template, tag_column) in requested_tags:
          # drop existing tag first for avoid ERROR 409
          api_call = f'{tag_name}'
          session_url = self.base_api_url.format(api_call=api_call)
          r = self.authed_http.urlopen(method='DELETE', url=session_url)
          if r.status != 200:
            raise AirflowException(
                (f'Could not delete tag from table table.\n'
                 f'ERROR:  {r.status} - {r.data}')
            )

      for tag in self.datacatalog_tags:
        api_call = f'{entry_id.name}/tags'
        session_url = self.base_api_url.format(api_call=api_call)
        session_body = json.dumps(tag)
        r = self.authed_http.urlopen(
            method='POST', url=session_url, body=session_body)
        if r.status != 200:
          raise AirflowException(
              (f'Could not create new tag on target table. {tag} \n'
               f'ERROR:  {r.status} - {r.data}')
          )
    return


import sys
from pathlib import Path
from shutil import copy, copytree, ignore_patterns

# This script initializes new pytorch project with the template files.
# Run `python3 new_project.py ../MyNewProject` then new project named
# MyNewProject will be made
current_dir = Path()
assert (
    current_dir / "new_project.py"
).is_file(), "Script should be executed in the pytorch-template directory"
assert (
    len(sys.argv) == 2
), "Specify a name for the new project. Example: python3 new_project.py MyNewProject"

project_name = Path(sys.argv[1])
target_dir = current_dir / project_name
package_dir = target_dir / "src"
package_dir.mkdir(parents=True)

ignore = [
    ".git",
    "data",
    "saved",
    "new_project.py",
    "LICENSE",
    "README.md",
    "__pycache__",
    ".mypy_cache",
]

copytree(
    current_dir / "src",
    package_dir / project_name.name,
    ignore=ignore_patterns(*ignore),
)
(target_dir / "config").mkdir()
copy(current_dir / "config.json", target_dir / "config")
(target_dir / "datasets").mkdir()
(target_dir / "saved").mkdir()
copy(current_dir / ".gitignore", target_dir / "config")
copy(current_dir / ".flake8", target_dir / "config")

print("New project initialized at", target_dir.absolute().resolve())


from __future__ import print_function

import io
import logging
import logging.handlers
import sys
import threading
import time

try:
    import argparse
except ImportError:
    sys.stderr.write("""
ntploggps: can't find the Python argparse module
         If your Python version is < 2.7, then manual installation is needed:
         # pip install argparse
""")
    sys.exit(1)

try:
    import gps
except ImportError as e:
    sys.stderr.write("ntploggps: can't find Python GPSD library.\n")
    sys.stderr.write("%s\n" % e)
    sys.exit(1)

class logfile_header_class(logging.handlers.TimedRotatingFileHandler):
    'A class to modify the file logging handler.'
    def doRollover(self):
        'function to add header to new file on rotation.'
        if str is bytes:
            super(logfile_header_class, self).doRollover()
        else:
            super().doRollover()
        self.stream.write('# Time       Device     TDOP     nSat\n')

def logging_setup():
    "Create logging object"
    logFormat = logging.Formatter('%(message)s')
    # Create logger for gpsd
    Logger = logging.getLogger()
    Logger.setLevel(logging.INFO)
    # Create file handler
    if args.logfile:
        # log to logfile
        file = logfile_header_class(
            args.logfile[0],
            utc=True,
            when='midnight',
            interval=1)
    else:
        # log to stdout
        file = logging.StreamHandler(sys.stdout)

    file.setLevel(logging.INFO)
    # Create the formatter and add it to the handler
    file.setFormatter(logFormat)
    # Add the handler to the logger
    Logger.addHandler(file)
    return Logger

parser = argparse.ArgumentParser(description="gpsd log file generator",
                                 epilog="""
See the manual page for details.
""")

parser.add_argument('-l', '--logfile',
                    dest='logfile',
                    help="append log data to LOGFILE instead of stdout",
                    nargs=1)

parser.add_argument('-o', '--once',
                    action="store_true",
                    dest='once',
                    help="log one line, then exit")

parser.add_argument('-w', '--wait',
                    default=[5],
                    dest='wait',
                    help="wait WAIT seconds after each log line, default 5",
                    nargs=1,
                    type=int)

parser.add_argument('-v', '--verbose',
                    action="store_true",
                    dest='verbose',
                    help="be verbose")

parser.add_argument('-V', '--version',
                    action="version",
                    version="ntploggps ntpsec-@NTPSEC_VERSION_EXTENDED@")

args = parser.parse_args()

if args.verbose:
    print("ntploggps: arguments:")
    print(args)

if args.logfile:
    # log to logfile
    try:
        out = open(args.logfile[0], mode='a')
    except io.UnsupportedOperation as e:
        sys.stderr.write("ntploggps: can't open logfile %s\n" % args.logfile)
        sys.stderr.write("%s\n" % e)
        sys.exit(1)

    if args.verbose:
        print("ntploggps: opened log file %s" % args.logfile[0])

else:
    # log to stdout
    out = sys.stdout

class GpsPoller(threading.Thread):
    running = False       # True when thread is running. Quit when set False

    def __init__(self):
        threading.Thread.__init__(self)
        self.device = None
        self.satellites_used = None
        self.tdop = None
        # start the streaming of gps data
        try:
            self.gpsd = gps.gps(mode=gps.WATCH_ENABLE)
        except BaseException as e:
            sys.stderr.write("ntploggps: Can't connect to gpsd, %s\n"
                             "         Is gpsd running?\n" % e)
            sys.exit(1)
        self.running = True

    def run(self):
        while gpsp.running:
            if self.gpsd.read() == -1:
                self.running = False
                break
            if not hasattr(self.gpsd, "data"):
                continue
            if self.gpsd.data.get("class", None) != "SKY":
                continue
            satellite_list = self.gpsd.data.get(
                "satellites", None
            )
            count_used_satellites = None
            if satellite_list is not None:
                count_used_satellites = sum(
                    map(lambda x: x.used, satellite_list)
                )
            time_dilution = self.gpsd.data.get("tdop", None)
            device_path = self.gpsd.data.get("device", None)
            if count_used_satellites is None:
                count_used_satellites = self.gpsd.data.get(
                    "uSat", None
                )
            if None not in [
                count_used_satellites,
                time_dilution,
                device_path,
            ]:
                self.satellites_used = count_used_satellites
                self.tdop = time_dilution
                self.device = device_path

    @property
    def time(self):
        "Return the gpsd time fix"
        t = self.gpsd.fix.time
        if isinstance(t, int):
            return t
        if isinstance(t, float):
            if not gps.isfinite(t):
                return None
            return t
        return gps.isotime(t)

if __name__ == '__main__':
    # this is the main thread
    if args.verbose:
        print("ntploggps: creating poll thread")

    gpsp = GpsPoller()    # create the thread
    try:
        # Create the logger instance
        Logger = logging_setup()

        # Create data layout
        Logger.info("# Time       Device     TDOP     nSat")

        gpsp.start()      # start it up
        last_time = 0
        while gpsp.running:
            # It may take a second or two to get good data

            try:
                current_time = gpsp.time
                device = gpsp.device
                tdop = gpsp.tdop
                satellites_used = gpsp.satellites_used

                if current_time is not None and \
                   device is not None and \
                   satellites_used is not None and \
                   tdop is not None:
                    if last_time != current_time:
                        s = '%i %s %f %d' % (current_time, device, tdop,
                                             satellites_used)
                        Logger.info(s)
                        last_time = current_time
                    if args.once:
                        # just once
                        break

            except AttributeError as e:
                print('parse error\n')

            # wait a bit before next log
            time.sleep(args.wait[0])

    except (KeyboardInterrupt, SystemExit):    # when you press ctrl+c
        args.once = True        # stop the retry loop
        if args.verbose:
            print("\nKilling Thread...")
        else:
            # print a blank line to make bash happy
            print("")
    except Exception as e:       # any error, signal
        print(e)

    # tell the thread to die
    gpsp.running = False

    # wait for the thread to finish what it's doing
    gpsp.join()

    if args.verbose:
        print("ntploggps: Done -- Exiting.")


import mysql.connector
import socket
import logging

from logging.config import fileConfig

fileConfig('log.ini', defaults={'logfilename': 'bee.log'})
logger = logging.getLogger('database')

mydb = mysql.connector.connect(
  host="45.76.113.79",
  database="hivekeeper",
  user="pi_write",
  password=")b*I/j3s,umyp0-8"
)

def upload_wx(wx, verbose=False):

    mycursor = mydb.cursor()

    sql = "INSERT INTO `weather` (dt, location, wind_deg, wind_gust, wind_speed, temp, temp_min, temp_max, temp_feels_like, humidity, pressure, clouds, sunrise, sunset, visibility, description) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"
    val = (
        wx['calc_time'],
        wx['location'],
        wx['wind_deg'],
        wx['wind_gust'],
        wx['wind_speed'],
        wx['temp'],
        wx['temp_min'],
        wx['temp_max'],
        wx['temp_feels_like'],
        wx['humidity'],
        wx['pressure'],
        wx['clouds'],
        wx['sunrise'],
        wx['sunset'],
        wx['visibility'],
        wx['wx_description'],
    )

    mycursor.execute(sql, val)
    mydb.commit()

    if verbose:
        logger.debug (str(mycursor.rowcount) + " record inserted.")
    return True

def get_host_name():
    return socket.gethostname()

def send_data(sensor_id, sensor_value, table=u'raw_data', verbose=False):

    mycursor = mydb.cursor()

    sql = "INSERT INTO `" + table + "` (host, sensor_id, value) VALUES (%s, %s, %s)"
    val = (socket.gethostname(), sensor_id, sensor_value)
    mycursor.execute(sql, val)
    mydb.commit()

    if verbose:
        logger.debug (str(mycursor.rowcount) + " record inserted.")
    return True


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

from PyQt5.QtWidgets import QDialog, QTreeWidgetItem, QMenu
from PyQt5.QtCore import pyqtSlot, QPoint

from labrecord.controllers.labrecordscontroller import LabrecordsController
from labrecord.modules.editobservationmodule import EditObservationModule
from labrecord.modules.checkreportmodule import CheckreportModule
from labrecord.views.editsamplerecorddetail import Ui_Dialog
from labrecord.modules.applycheckmodule import ApplycheckModule

from product.controllers.productcontroller import ProductController

import decimal
import user

class EditSampleRecordDetailModule(QDialog, Ui_Dialog):

    def __init__(self, autoid, parent=None):
        super(EditSampleRecordDetailModule, self).__init__(parent)
        self.setupUi(self)
        if '50' not in user.powers:
            self.close()
        if user.powers['10'] == 0:
            self.close()
        self.power = '{:03b}'.format(user.powers['10'])
        if self.power[1] == '0':
            self.pushButton_accept.setVisible(False)
            self.pushButton_cancel.setVisible(False)
        self.autoid = autoid
        self.checkitem_id = None
        self.ori_detail = object
        self.new_detail = {}
        self.lr_list = []
        self.LC = LabrecordsController()
        self.PC = ProductController()

        self.get_detail()
        self.get_observation_record()
        self.get_labrecord_list()

    def get_detail(self):
        condition = {'autoid': self.autoid}
        res = self.LC.get_data(6, False, **condition)
        if len(res) != 1:
            self.pushButton_accept.setEnabled(False)
            self.pushButton_cancel.setEnabled(False)
            return
        self.ori_detail = res[0]
        self.lineEdit_product.setText(
            self.ori_detail.ppid.prodid + ' ' + self.ori_detail.ppid.prodname
        )
        self.lineEdit_commonname.setText(self.ori_detail.ppid.commonname)
        self.lineEdit_batchno.setText(self.ori_detail.ppid.batchno)
        self.lineEdit_spec.setText(self.ori_detail.ppid.spec)
        self.lineEdit_package.setText(self.ori_detail.ppid.package)
        self.lineEdit_makedate.setText(str(self.ori_detail.ppid.makedate))
        self.lineEdit_samplequantity.setText(str(self.ori_detail.samplequantity))
        self.lineEdit_unit.setText(self.ori_detail.unit)
        self.comboBox_kind.setCurrentIndex(self.ori_detail.kind)
        if self.ori_detail.status != 0:
            self.pushButton_accept.setEnabled(False)
            self.pushButton_cancel.setEnabled(False)

    def get_observation_record(self):
        self.treeWidget_observation.clear()
        condition = {'srid': self.autoid}
        res = self.LC.get_data(7, False, **condition)

        if not len(res):
            return
        lrid_list = res.values_list(*VALUES_TUPLE_LRID, flat=True)
        condition_lr={'ciid__in': lrid_list, 'labtype':6}
        self.lr_list = self.LC.get_data(
            0, False, *VALUES_TUPLE_LR, **(condition_lr)
        )

        for item in res.values(*VALUES_TUPLE_OB):
            qtreeitem = QTreeWidgetItem(self.treeWidget_observation)
            qtreeitem.setText(0, str(item['autoid']))
            qtreeitem.setText(2, item['obsperiod'])
            qtreeitem.setText(3, str(item['obsdate']))
            qtreeitem.setText(4, str(item['samplequantity']))
            qtreeitem.setText(5, item['unit'])
            qtreeitem.setText(6, item['conclusion'])
            for it in self.lr_list:
                if it['ciid'] == item['autoid']:
                    qtreeitem.setText(1, str(it['autoid']))
                    qtreeitem.setText(7, STATUS[it['status']])
                    break
        for i in range(2, 8):
            self.treeWidget_observation.resizeColumnToContents(i)

    def get_labrecord_list(self):
        self.treeWidget_labrecord.clear()
        if self.ori_detail is None:
            return
        for item in self.lr_list:
            qtreeitem = QTreeWidgetItem(self.treeWidget_labrecord)
            qtreeitem.setText(0, str(item['autoid']))
            qtreeitem.setText(1, item['paperno'])
            qtreeitem.setText(2, str(item['reportdate']))
            qtreeitem.setText(3, STATUS[item['status']])

    @pyqtSlot(QPoint)
    def on_treeWidget_observation_customContextMenuRequested(self, pos):
        if self.ori_detail is None:
            return
        if self.ori_detail.status != 0:
            return
        current_item = self.treeWidget_observation.currentItem()
        menu = QMenu()
        action_1 = menu.addAction("增加")
        action_2 = menu.addAction("修改")
        action_3 = menu.addAction("删除")
        menu.addSeparator()
        action_4 = menu.addAction("提交请验")
        action_5 = menu.addAction("取消请验")
        global_pos = self.treeWidget_observation.mapToGlobal(pos)
        action = menu.exec(global_pos)
        if action == action_1:
            unit = self.lineEdit_unit.text()
            detail = EditObservationModule(
                srid=self.autoid, unit=unit, parent=self
            )
            detail.accepted.connect(self.get_observation_record)
            detail.show()
        elif action == action_2:
            if current_item is None:
                return
            id = int(current_item.text(0))
            detail = EditObservationModule(autoid=id, parent=self)
            detail.accepted.connect(self.get_observation_record)
            detail.show()
        elif action == action_3:
            if current_item is None:
                return
            condition = {'autoid': int(current_item.text(0))}
            self.LC.delete_data(7, condition)
            lrid = current_item.text(1)
            if lrid != '':
                self.LC.delete_labrecord_and_detail(int(lrid))
            self.get_observation_record()
        elif action == action_4:
            if self.ori_detail is None or current_item is None:
                return
            if current_item.text(1) == '':
                if self.checkitem_id is None:
                    prodid = self.ori_detail.ppid.prodid
                    condition = {'prodid': prodid}
                    res = self.PC.get_data(1, True, *VALUES_TUPLE_PD, **condition)
                    if not len(res):
                        return
                    self.checkitem_id = res[0]
                kwargs = {
                    'labtype': 6,
                    'chkid': self.ori_detail.ppid.prodid,
                    'chkname': self.ori_detail.ppid.prodname,
                    'batchno': self.ori_detail.ppid.batchno,
                    'spec': self.ori_detail.ppid.spec,
                    'package': self.ori_detail.ppid.package,
                    'ciid': int(current_item.text(0)),
                    'createdate': user.now_date,
                    'checkamount': self.ori_detail.samplequantity,
                    'caunit': self.ori_detail.unit,
                    'sampleamount': decimal.Decimal(current_item.text(4)),
                    'sampleunit': current_item.text(5),
                }
                lrid = self.LC.create_labrecord(
                    self.checkitem_id, 6, user.now_date, **kwargs
                )
            else:
                lrid = int(current_item.text(1))
            detail = ApplycheckModule(lrid, 6, self)
            detail.rejected.connect(lambda: self.delete_check_report(lrid))
            detail.applyed.connect(detail.accept)
            detail.accepted.connect(self.get_observation_record)
            detail.accepted.connect(self.get_labrecord_list)
            detail.show()
        elif action == action_5:
            if current_item is None:
                return
            lrid = current_item.text(1)
            if lrid != '':
                self.LC.delete_labrecord(int(lrid))
                self.get_observation_record()
        else:
            pass

    def delete_check_report(self, lrid):
        self.LC.delete_labrecord(lrid)
        self.get_observation_record()

    @pyqtSlot(QTreeWidgetItem, int)
    def on_treeWidget_observation_itemDoubleClicked(self, qtreeitem, p_int):
        id = int(qtreeitem.text(0))
        detail = EditObservationModule(autoid=id, parent=self)
        detail.accepted.connect(self.get_observation_record)
        detail.show()

    @pyqtSlot(QTreeWidgetItem, int)
    def on_treeWidget_labrecord_itemDoubleClicked(self, qtreeitem, p_int):
        if self.power[1] == '0':
            return
        id = int(qtreeitem.text(0))
        detail = CheckreportModule(id, True, self)
        detail.show()

    @pyqtSlot(str)
    def on_lineEdit_samplequantity_textChanged(self, p_str):
        p_data = decimal.Decimal(p_str)
        try:
            if p_data != self.ori_detail.samplequantity:
                self.new_detail['samplequantity'] = p_data
            else:
                try:
                    del self.new_detail['samplequantity']
                except KeyError:
                    pass
        except ValueError:
            self.new_detail['samplequantity'] = p_data

    @pyqtSlot(str)
    def on_lineEdit_unit_textChanged(self, p_str):
        try:
            if p_str != self.ori_detail.unit:
                self.new_detail['unit'] = p_str
            else:
                try:
                    del self.new_detail['unit']
                except KeyError:
                    pass
        except ValueError:
            self.new_detail['unit'] = p_str

    @pyqtSlot(int)
    def on_comboBox_kind_currentIndexChanged(self, p_int):
        try:
            if p_int != self.ori_detail.kind:
                self.new_detail['kind'] = p_int
            else:
                try:
                    del self.new_detail['kind']
                except KeyError:
                    pass
        except ValueError:
            self.new_detail['kind'] = p_int

    @pyqtSlot()
    def on_pushButton_accept_clicked(self):
        if not len(self.new_detail):
            return
        condiition = {'autoid': self.autoid}
        self.LC.update_data(6, condiition, **self.new_detail)
        self.accept()

    @pyqtSlot()
    def on_pushButton_cancel_clicked(self):
        self.close()

STATUS = ("待请验", "取样中", "检验中", "合格", "不合格")

VALUES_TUPLE_LRID = ('autoid',)
VALUES_TUPLE_OB = (
    'autoid', 'obsperiod', 'obsdate', 'samplequantity', 'unit', 'conclusion'
)
VALUES_TUPLE_LR = ('autoid', 'ciid', 'paperno', 'reportdate', 'status')

VALUES_TUPLE_PD = ('autoid', )


"""
Created on Thu Mar 17 16:34:46 2022

@author: svein
"""
import speech_recognition as sr
import sounddevice as sd
from scipy.io.wavfile import write
import os
import ffmpeg
from scipy.io import wavfile
import numpy as np

def Speech_to_text():
    myfile="output.wav"

    ## If file exists, delete it ##
    if os.path.isfile(myfile):
        os.remove(myfile)
    else:    ## Show an error ##
        print("Error: %s file not found" % myfile)
 ##
    print("recording start")
    fs = 44100  # Sample rate
    seconds = 4  # Duration of recording

    sd.default.dtype='int32', 'int32'

    myrecording = sd.rec(int(seconds * fs), samplerate=fs, channels=2)
    sd.wait()  # Wait until recording is finished
    print("recording ended")
    wavfile.write("output.wav", fs, myrecording)  # Save as WAV file

    def SpeechToText():
        r = sr.Recognizer()   #Speech recognition
        audio = sr.AudioFile("output.wav")
        with audio as source:
            print("Wait. Program Starting")
            audio = r.record(source)
            message = r.recognize_google(audio)
            print("Check: "+message)
        return message
    Ord=SpeechToText()
    return Ord

if __name__ == "__main__":
    print(Speech_to_text())


import numpy as np
import torch
import torch.nn as nn

from pytorch_lightning.utilities.rank_zero import _get_rank

import models
from models.base import BaseModel
from models.utils import scale_anything, get_activation, cleanup, chunk_batch
from models.network_utils import get_encoding, get_mlp, get_encoding_with_network

class MarchingCubeHelper(nn.Module):
    def __init__(self, resolution, use_torch=True):
        super().__init__()
        self.resolution = resolution
        self.use_torch = use_torch
        self.points_range = (0, 1)
        if self.use_torch:
            import torchmcubes
            self.mc_func = torchmcubes.marching_cubes
        else:
            import mcubes
            self.mc_func = mcubes.marching_cubes
        self.verts = None

    def grid_vertices(self):
        if self.verts is None:
            x, y, z = torch.linspace(*self.points_range, self.resolution), torch.linspace(*self.points_range, self.resolution), torch.linspace(*self.points_range, self.resolution)
            x, y, z = torch.meshgrid(x, y, z)
            verts = torch.cat([x.reshape(-1, 1), y.reshape(-1, 1), z.reshape(-1, 1)], dim=-1).reshape(-1, 3)
            self.verts = verts.to(_get_rank())
        return self.verts

    def forward(self, level, threshold=0.):
        level = level.float().view(self.resolution, self.resolution, self.resolution)
        if self.use_torch:
            verts, faces = self.mc_func(level.to(_get_rank()), threshold)
            verts, faces = verts.cpu(), faces.cpu().long()
        else:
            verts, faces = self.mc_func(-level.numpy(), threshold) # transform to numpy
            verts, faces = torch.from_numpy(verts.astype(np.float32)), torch.from_numpy(faces.astype(np.int64)) # transform back to pytorch
        verts = verts / (self.resolution - 1.)

        return {
            'v_pos': verts,
            't_pos_idx': faces
        }

class BaseImplicitGeometry(BaseModel):
    def __init__(self, config):
        super().__init__(config)
        if self.config.isosurface is not None:
            assert self.config.isosurface.method in ['mc', 'mc-torch']
            if self.config.isosurface.method == 'mc-torch':
                raise NotImplementedError("Please do not use mc-torch. It currently has some scaling issues I haven't fixed yet.")
            self.helper = MarchingCubeHelper(self.config.isosurface.resolution, use_torch=self.config.isosurface.method=='mc-torch')

    def forward_level(self, points):
        raise NotImplementedError

    def isosurface_(self, vmin, vmax):
        grid_verts = self.helper.grid_vertices()
        grid_verts = torch.stack([
            scale_anything(grid_verts[...,0], (0, 1), (vmin[0], vmax[0])),
            scale_anything(grid_verts[...,1], (0, 1), (vmin[1], vmax[1])),
            scale_anything(grid_verts[...,2], (0, 1), (vmin[2], vmax[2]))
        ], dim=-1)

        def batch_func(x):
            rv = self.forward_level(x).cpu()
            cleanup()
            return rv

        level = chunk_batch(batch_func, self.config.isosurface.chunk, grid_verts)
        mesh = self.helper(level, threshold=self.config.isosurface.threshold)
        mesh['v_pos'] = torch.stack([
            scale_anything(mesh['v_pos'][...,0], (0, 1), (vmin[0], vmax[0])),
            scale_anything(mesh['v_pos'][...,1], (0, 1), (vmin[1], vmax[1])),
            scale_anything(mesh['v_pos'][...,2], (0, 1), (vmin[2], vmax[2]))
        ], dim=-1)
        return mesh

    @torch.no_grad()
    def isosurface(self):
        if self.config.isosurface is None:
            raise NotImplementedError
        # coarse to fine extraction
        # mesh_coarse = self.isosurface_((-self.radius, -self.radius, -self.radius), (self.radius, self.radius, self.radius))
        # if mesh_coarse['v_pos'].shape[0] == 0:
        #     return mesh_coarse
        # vmin, vmax = mesh_coarse['v_pos'].amin(dim=0), mesh_coarse['v_pos'].amax(dim=0)
        # vmin_ = (vmin - (vmax - vmin) * 0.1).clamp(-self.radius, self.radius)
        # vmax_ = (vmax + (vmax - vmin) * 0.1).clamp(-self.radius, self.radius)
        # mesh_fine = self.isosurface_(vmin_, vmax_)
        # extract in a fixed scale
        # mesh_fine = self.isosurface_((-self.radius, -self.radius, -self.radius), (self.radius, self.radius, self.radius))
        mesh_fine = self.isosurface_((-self.radius + 0.2, -self.radius+ 0.2, -self.radius+ 0.2), (self.radius - 0.2, self.radius - 0.2, self.radius - 0.2))

        return mesh_fine

@models.register('volume-density')
class VolumeDensity(BaseImplicitGeometry):
    def setup(self):
        self.n_input_dims = self.config.get('n_input_dims', 3)
        self.n_output_dims = self.config.feature_dim
        self.encoding_with_network = get_encoding_with_network(self.n_input_dims, self.n_output_dims, self.config.xyz_encoding_config, self.config.mlp_network_config)
        self.radius = self.config.radius
        self.noises = 0.
        self.raw_noise_std = self.config.get('raw_noise_std', 0.)

    def forward(self, points):
        points = scale_anything(points, (-self.radius, self.radius), (0, 1))
        out = self.encoding_with_network(points.view(-1, self.n_input_dims)).view(*points.shape[:-1], self.n_output_dims).float()

        density, feature = out[...,0], out
        if 'density_activation' in self.config:
            if self.raw_noise_std > 0.:
                self.noises = (torch.randn(density.shape) * self.raw_noise_std).to(density)
            density = get_activation(self.config.density_activation)(density + self.noises + float(self.config.density_bias))
        if 'feature_activation' in self.config:
            feature = get_activation(self.config.feature_activation)(feature)
        return density, feature

    def forward_level(self, points):
        points = scale_anything(points, (-self.radius, self.radius), (0, 1))
        density = self.encoding_with_network(points.reshape(-1, self.n_input_dims)).reshape(*points.shape[:-1], self.n_output_dims)[...,0].float()
        if 'density_activation' in self.config:
            density = get_activation(self.config.density_activation)(density + float(self.config.density_bias))
        return -density # caution!!!

    @torch.no_grad()
    def extract_volume(self, res=128):
        x = torch.linspace(0.02, 0.98, steps=res)
        y = torch.linspace(0.02, 0.98, steps=res)
        z = torch.linspace(0.02, 0.98, steps=res)
        grid_x, grid_y, grid_z = torch.meshgrid(x, y, z, indexing='ij')
        points = torch.cat((grid_x[..., None], grid_y[..., None], grid_z[..., None]), dim=3).to(self.rank) # (res, res, res, 3)
        density = self.encoding_with_network(points.reshape(-1, self.n_input_dims)).reshape(*points.shape[:-1], self.n_output_dims)[...,0].float()
        if 'density_activation' in self.config:
            density = get_activation(self.config.density_activation)(density + float(self.config.density_bias))
        return points, density

@models.register('volume-sdf')
class VolumeSDF(BaseImplicitGeometry):
    def setup(self):
        self.n_output_dims = self.config.feature_dim
        encoding = get_encoding(3, self.config.xyz_encoding_config)
        network = get_mlp(encoding.n_output_dims, self.n_output_dims, self.config.mlp_network_config)
        self.encoding, self.network = encoding, network
        self.radius = self.config.radius
        self.grad_type = self.config.grad_type

    # def forward(self, points, with_grad=True, with_feature=True):
    #     points = scale_anything(points, (-self.radius, self.radius), (0, 1))
    #     with torch.inference_mode(torch.is_inference_mode_enabled() and not (with_grad and self.grad_type == 'analytic')):
    #         with torch.set_grad_enabled(self.training or (with_grad and self.grad_type == 'analytic')):
    #             if with_grad and self.grad_type == 'analytic':
    #                 if not self.training:
    #                     points = points.clone() # points may be in inference mode, get a copy to enable grad
    #                 points.requires_grad_(True)
    #             out = self.network(self.encoding(points.view(-1, 3))).view(*points.shape[:-1], self.n_output_dims).float()
    #             sdf, feature = out[...,0], out
    #             if 'sdf_activation' in self.config:
    #                 sdf = get_activation(self.config.sdf_activation)(sdf + float(self.config.sdf_bias))
    #             if 'feature_activation' in self.config:
    #                 feature = get_activation(self.config.feature_activation)(feature)
    #             if with_grad:
    #                 if self.grad_type == 'analytic':
    #                     grad = torch.autograd.grad(
    #                         sdf, points, grad_outputs=torch.ones_like(sdf),
    #                         create_graph=True, retain_graph=True, only_inputs=True
    #                     )[0]
    #                 elif self.grad_type == 'finite_difference':
    #                     eps = 0.001
    #                     points_d = torch.stack([
    #                         points + torch.as_tensor([eps, 0.0, 0.0]).to(points),
    #                         points + torch.as_tensor([-eps, 0.0, 0.0]).to(points),
    #                         points + torch.as_tensor([0.0, eps, 0.0]).to(points),
    #                         points + torch.as_tensor([0.0, -eps, 0.0]).to(points),
    #                         points + torch.as_tensor([0.0, 0.0, eps]).to(points),
    #                         points + torch.as_tensor([0.0, 0.0, -eps]).to(points)
    #                     ], dim=0).clamp(0, 1)
    #                     points_d_sdf = self.network(self.encoding(points_d.view(-1, 3)))[...,0].view(6, *points.shape[:-1]).float()
    #                     grad = torch.stack([
    #                         0.5 * (points_d_sdf[0] - points_d_sdf[1]) / eps,
    #                         0.5 * (points_d_sdf[2] - points_d_sdf[3]) / eps,
    #                         0.5 * (points_d_sdf[4] - points_d_sdf[5]) / eps,
    #                     ], dim=-1)

    #     rv = [sdf]
    #     if with_grad:
    #         rv.append(grad)
    #     if with_feature:
    #         rv.append(feature)
    #     rv = [v if self.training else v.detach() for v in rv]
    #     return rv[0] if len(rv) == 1 else rv

    def forward(self, points, with_grad=True, with_feature=True):
        with torch.inference_mode(torch.is_inference_mode_enabled() and not (with_grad and self.grad_type == 'analytic')):
            with torch.set_grad_enabled(self.training or (with_grad and self.grad_type == 'analytic')):
                if with_grad and self.grad_type == 'analytic':
                    if not self.training:
                        points = points.clone() # points may be in inference mode, get a copy to enable grad
                    points.requires_grad_(True)

                points_ = points # points in the original scale
                points = scale_anything(points_, (-self.radius, self.radius), (0, 1)) # points normalized to (0, 1)

                out = self.network(self.encoding(points.view(-1, 3))).view(*points.shape[:-1], self.n_output_dims).float()
                sdf, feature = out[...,0], out
                if 'sdf_activation' in self.config:
                    sdf = get_activation(self.config.sdf_activation)(sdf + float(self.config.sdf_bias))
                if 'feature_activation' in self.config:
                    feature = get_activation(self.config.feature_activation)(feature)
                if with_grad:
                    if self.grad_type == 'analytic':
                        grad = torch.autograd.grad(
                            sdf, points_, grad_outputs=torch.ones_like(sdf),
                            create_graph=True, retain_graph=True, only_inputs=True
                        )[0]
                    elif self.grad_type == 'finite_difference':
                        eps = 0.001
                        points_d_ = torch.stack([
                            points_ + torch.as_tensor([eps, 0.0, 0.0]).to(points_),
                            points_ + torch.as_tensor([-eps, 0.0, 0.0]).to(points_),
                            points_ + torch.as_tensor([0.0, eps, 0.0]).to(points_),
                            points_ + torch.as_tensor([0.0, -eps, 0.0]).to(points_),
                            points_ + torch.as_tensor([0.0, 0.0, eps]).to(points_),
                            points_ + torch.as_tensor([0.0, 0.0, -eps]).to(points_)
                        ], dim=0).clamp(0, 1)
                        points_d = scale_anything(points_d_, (-self.radius, self.radius), (0, 1))
                        points_d_sdf = self.network(self.encoding(points_d.view(-1, 3)))[...,0].view(6, *points.shape[:-1]).float()
                        grad = torch.stack([
                            0.5 * (points_d_sdf[0] - points_d_sdf[1]) / eps,
                            0.5 * (points_d_sdf[2] - points_d_sdf[3]) / eps,
                            0.5 * (points_d_sdf[4] - points_d_sdf[5]) / eps,
                        ], dim=-1)

        rv = [sdf]
        if with_grad:
            rv.append(grad)
        if with_feature:
            rv.append(feature)
        rv = [v if self.training else v.detach() for v in rv]
        return rv[0] if len(rv) == 1 else rv

    def forward_level(self, points):
        points = scale_anything(points, (-self.radius, self.radius), (0, 1))
        sdf = self.network(self.encoding(points.view(-1, 3))).view(*points.shape[:-1], self.n_output_dims)[...,0].float()
        if 'sdf_activation' in self.config:
            sdf = get_activation(self.config.sdf_activation)(sdf + float(self.config.sdf_bias))
        return sdf


from collections import defaultdict
def solution(genres, plays):
    answer = []
    stream = defaultdict(list)
    # 같은 장르내에서는 plays수가 같을 수 있지만
    # 장르 합은 다른 장르의 합과 다르다
    for g,p in zip(genres, plays):
        stream[g].append(p)
    answer = []
    stream = sorted(stream.items(), key = lambda x:-sum(x[1])) # list
    # 인덱스는 앞에것부터 찾음
    for i,j in stream:
        j.sort(reverse=True)
    for i in range(len(stream)): #장르가 2개 이상 가능
        if len(stream[i][1]) == 1: answer.append(plays.index(stream[i][1][0]))
        else: # 길이가 2이상 (2개 다 넣일 수 있음)
            answer.append(plays.index(stream[i][1][0]))
            plays[plays.index(stream[i][1][0])] = -1
            answer.append(plays.index(stream[i][1][1]))
    return answer


import argparse

# Parse arguments
parser = argparse.ArgumentParser()
parser.add_argument("text")
parser.add_argument("repetitions")
args = parser.parse_args()

# Convert repetitions to integer
try:
    text = args.text
    repetitions = int(args.repetitions)
except:
    quit(1)

# Create repeated repeated input text and write this to a file
if repetitions > 0 and len(text) > 0:
    output_text = text * repetitions

    with open("output.txt", "w") as outfile:
        outfile.write(output_text)
else:
    quit(1)