import re
import keyboard
import webbrowser
import urllib

def main():
	text = keyboard.get_selected_text()

	if re.search("^[^A-Za-z]+$", text):
		task = urllib.parse.quote(text.encode('utf-8'))

		webbrowser.open('icabmobile://www.cantonese.sheik.co.uk/dictionary/search/?searchtype=1&text=' + task)
	else:
		text = re.sub("^
|
$|^ |
$|
$|^
||","",text, re.MULTILINE)

		text = re.sub("|	|
|
|
|
|
|
|{|}| ","",text)

		'''a little trick so we don't need to use two separate scripts'''
		if len(text) <= 40:
			text = re.sub(r"(\D)(\d|\d\S\d|\d\S\S\S\d)(\s|$| |,\D|;|<)",r"\1\2\3" ,text)
			text = re.sub(" | ","",text)
		else:
			text = re.sub(r"(\D)(\d|\d\S\d|\d\S\S\S\d)(\s|$| |,\D|;|<)",r"\1\2\3" ,text)

		text = re.sub(" - | -- | –– ", " — ",text)
		text = re.sub("--|––", "—",text)
		text = text.replace("-", "–")
		text = text.replace("...", "…")

		text = re.sub("
","
",text,1)

		text = re.sub(r"(\S\D)(c|d|g|h|l|m|n|r|t|v)iz(e|a)", r"\1\2is\3",text)
		text = text.replace("avor", "avour")
		text = text.replace("honor", "honour")
		text = text.replace("color", "colour")
		text = text.replace("成语 saw", "idiom")

		text = re.sub("

|
|
|

|
|
", "
",text)

		text = re.sub("
|
","",text)

		text = text.replace("  ", " ")
		text = text.replace(" / ", "/")
		text = re.sub(r"( |^)'(\b|<)",r"\1‘\2",text)
		text = re.sub(r"(\b|>)'(\s|\.|,|:|;|\))",r"\1’\2",text)
		text = text.replace("'", "’")
		text = re.sub(r"( |^)\"(\b|<)",r"\1“\2",text)
		text = re.sub(r"(\b|>|\?|!)\"(\s|\.|,|:|;|<|\)|$)",r"\1”\2",text)
		text = re.sub("\(Jyutping\)|\(jyutping\)|Jyutping|jyutping", "[粵]",text)
		text = re.sub("\(Pinyin\)|\(pinyin\)|Pinyin|pinyin", "[國]",text)

		text = text.replace("msg–", "msg-")
		text = re.sub("
$|^
| $","",text, re.MULTILINE)
		text = re.sub("
$|^
| $","",text, re.MULTILINE)
		text = re.sub("","",text)
		text = re.sub("","",text)
		text = re.sub(" "," ",text)
		text = text.replace("lit.,", "lit.")

		'''prep for pasting'''
		text = text.replace("\n\n","

")
		text = text.replace("\n","
")
		text = text.replace("

", "

")
		text = re.sub("
$|^
|^ ","",text, re.MULTILINE)
		text = re.sub("
$|^
|^ ","",text, re.MULTILINE)

	if keyboard.is_keyboard():
		keyboard.play_input_click()
		keyboard.insert_text(text)
	else:
		# For debugging in the main app:
		print(f'Keyboard input: {text}')

if __name__ == '__main__':
	main()
	quit()


import numpy as np
import functools
from activation import relu, softmax

class _Neuron():
    """
        shape of neuron given as feature_count = fc
        a = [w.T] x [X]
        w : shape of (fc,1) # fc = feature count
        X : shape of (fc,any)
        b : int
    """
    def __init__(self, **kwargs):
        self.weights = np.random.rand(kwargs["feature_count"], 1) # w
        self.inputs = None                                        # X
        self.bias = np.zeros((1,))                                # b

    def feed(self, X):
        self.inputs = X

class _Layer:
    """
        shape of Layer given as feature_count = fc, neuron_count = nc
        A = [W.T] x [X]
        W : shape of (fc,nc) # fc = feature count, nc = neuron count
        X : shape of (fc,any)
        b : shape of (nc,1)
    """
    def __init__(self, **kwargs):
        neurons = [_Neuron(feature_count=kwargs["feature_count"]) for i in range(kwargs["neuron_count"])]
        self.W = functools.reduce(lambda a,b : np.append(a, b, axis=1), map(lambda neuron:neuron.weights, neurons))
        self.b = functools.reduce(lambda a,b : np.append(a, b, axis=0), map(lambda neuron:neuron.bias, neurons))
        self.layer_type = kwargs["layer_type"]

    def forward_prop(self, X):
        if self.layer_type is "output":
            return softmax( np.dot(self.W.T, X) )
        else:
            return relu( np.dot(self.W.T, X) )

class NN:
    """
        shape of Neural Network as input_shape=ic, dense_shapes=[], output_shape=oc
    """
    def __init__(self, **kwargs):
        self.layers = [
                _Layer(
                    feature_count=kwargs["input_shape"][0],
                    neuron_count=kwargs["input_shape"][1],
                    layer_type="input"
                )
            ]+[
                _Layer(
                    feature_count=shape[0],
                    neuron_count=shape[1],
                    layer_type="dense"
                ) for shape in kwargs["dense_shapes"]
            ]+[
                _Layer(
                    feature_count=kwargs["output_shape"][0],
                    neuron_count=kwargs["output_shape"][1],
                    layer_type="output"
                )
            ]
        print("------- Generating NN -------")
        for index in range(len(self.layers)):
            print("layer: ",index," shape: ",self.layers[index].W.shape," layer type: ",self.layers[index].layer_type)
        print("_____________________________\n")

    def prediction(self, A):
        for layer in self.layers:
            A = layer.forward_prop(A)
        return np.argmax(A)

    def deploy(self):
        return [layer.W for layer in self.layers]

"""
    takes: [[],[],[]]
    returns: np array as appended column by column
"""
def parse_input_stream(input_stream):
    return functools.reduce(lambda a,b:np.append(a,b,axis=1), map(lambda data:np.array(data).reshape(len(data),1),input_stream))

if __name__ == '__main__':
    ga = NN(input_shape=(4,2), dense_shapes=[(2,5),(5,5)], output_shape=(5,3))
    input_stream = [[10.0,10.0,6.5,3],[10.0,10.0,10.0,5.3]]
    input_stream = functools.reduce(lambda a,b:np.append(a,b,axis=1), map(lambda data:np.array(data).reshape(len(data),1),input_stream))
    choice = ga.prediction( input_stream )
    input_stream = [[10.0,10.0,6.5,3],[10.0,1.1,3.0,3.5]]
    input_stream = functools.reduce(lambda a,b:np.append(a,b,axis=1), map(lambda data:np.array(data).reshape(len(data),1),input_stream))
    choice2 = ga.prediction( input_stream )
    print(choice,"\n")
    print(choice2)


from datetime import datetime
import copy

fileName = '/tmp/fridge.txt'
foods = {'Turkey': '12/01/2018', 'spaghetti': '12/02/2018', 'yogurt': '11/29/2018', 'chicken': '12/08/2018',
         'cake': '12/06/2018', 'soup': '12/07/2018', 'milk': '12/01/2018'}
CardTitlePrefix = "My Fridge"  # this is what will show up on the title for the Alexa user interface when using the skill

# code for the build responses and event handlers was borrowed from the following tutorial blueprint:
# http://www.auctoris.co.uk/2017/04/21/simple-python-hello-world-with-alexa/
def build_speechlet_response(title, output, reprompt_text, should_end_session):
    """
    Build a speechlet JSON representation of the title, output text,
    reprompt text & end of session
    """
    return {
        'outputSpeech': {
            'type': 'PlainText',
            'text': output
        },
        'card': {
            'type': 'Simple',
            'title': CardTitlePrefix + " - " + title,
            'content': output
        },
        'reprompt': {
            'outputSpeech': {
                'type': 'PlainText',
                'text': reprompt_text
            }
        },
        'shouldEndSession': should_end_session
    }

def build_response(session_attributes, speechlet_response):
    """
    Build the full response JSON from the speechlet response
    """
    return {
        'version': '1.0',
        'sessionAttributes': session_attributes,
        'response': speechlet_response
    }

# --------------- Functions that control the skill's behavior ------------------

# function that is called on_launch when the user says the skill's invocation name, "my fridge."
def get_welcome_response():
    session_attributes = copy.deepcopy(foods)
    print("session attributes: \n")
    for attribute in session_attributes.keys():
        print(attribute + ":" + session_attributes.get(attribute))
    card_title = "Hello"
    speech_output = "Your fridge is open...Ask me what's in your fridge or how old the food is.."
    # If the user either does not reply to the welcome message or says something
    # that is not understood, they will be prompted again with this text.
    reprompt_text = "I'm sorry - I didn't understand. You should ask me what's in your fridge or how old a food is..."
    should_end_session = False
    return build_response(session_attributes,
                          build_speechlet_response(card_title, speech_output, reprompt_text, should_end_session))

# function that is called during SessionEndRequest, but is not currently being used
def handle_session_end_request():
    card_title = "Session Ended"
    speech_output = "Have a nice day! "
    # Setting this to true ends the session and exits the skill.
    should_end_session = True
    return build_response({}, build_speechlet_response(
        card_title, speech_output, None, should_end_session))

# function that is called on_launch and reads food:date from a file into a dictionary
def open_fridge():
    print("Opening " + fileName)
    with open(fileName, 'w+') as f:
        for f_contents in f.readlines():
            fridge_item = f_contents.split(":")
            if fridge_item.__len__() == 2:
                food = fridge_item[0]
                date = fridge_item[1]
                formatted_date = date.rstrip()
                foods.update({food: formatted_date})
    print("Loaded the following foods from " + fileName + "\n")
    for food in foods:
        print(food + ": " + str(foods.get(food)) + "\n")

# function that reads from foods dictionary into dictionary session_attributes and outputs the contents.
def whats_in_fridge():
    session_attributes = copy.deepcopy(foods)
    card_title = "Fridge Contents"
    speech_output = ""
    print("number of foods: " + str(len(foods)))
    if len(foods) == 0:
        speech_output = "Your fridge is empty. Would you like to add some food?"
    elif len(foods) >= 1:
        speech_output = "Your fridge has "
        for food in foods.keys():
            speech_output += food + ", "
    # If the user either does not reply to the welcome message or says something
    # that is not understood, they will be prompted again with this text.
    reprompt_text = "I'm sorry - I didn't understand. You should ask me what's in your fridge or how old a food is..."
    should_end_session = False
    return build_response(session_attributes,
                          build_speechlet_response(card_title, speech_output, reprompt_text, should_end_session))

# function that modifies the contents of foods dictionary and copies to session_attributes dictionary, when the user adds a food to their fridge
def put_food_in(food, date):
    foods.update({food: date})
    session_attributes = copy.deepcopy(foods)
    card_title = "Put Food In"
    speech_output = "Okay, I have added the " + food + " to your fridge...Is there anything else I can help you with?"
    # If the user either does not reply to the welcome message or says something
    # that is not understood, they will be prompted again with this text.
    reprompt_text = "I'm sorry - I didn't understand. You should ask me what's in your fridge or how old a food is..."
    should_end_session = False
    return build_response(session_attributes,
                          build_speechlet_response(card_title, speech_output, reprompt_text, should_end_session))

# function that modifies the contents of foods dictionary and copies to session_attributes dictionary, when user removes a food item
def take_food_out(food):
    if food in foods:
        del foods[food]
        speech_output = "Okay, I have removed the " + food + " from your fridge."
    else:
        speech_output = "You don't have any " + food + " in your fridge...Perhaps I misunderstood?"
    session_attributes = copy.deepcopy(foods)
    card_title = "Take Food Out"
    # If the user either does not reply to the welcome message or says something
    # that is not understood, they will be prompted again with this text.
    reprompt_text = "I'm sorry - I didn't understand. You should ask me what's in your fridge or how old a food is..."
    should_end_session = False
    return build_response(session_attributes,
                          build_speechlet_response(card_title, speech_output, reprompt_text, should_end_session))

# this function outputs the age of the food in days
def how_old(food):
    card_title = "Food Age"
    if food in foods:  # first verify the food is in the fridge
        today = datetime.now()  # variable created to store current date
        day_added = datetime.strptime(foods.get(food), "%m/%d/%Y")  # variable created to store date when food was added
        delta_days = today - day_added  # calculates days since food was added
        age = str(delta_days.days)  # stores age of the food into string variable
        if delta_days.days == 0:  # food stored today
            speech_output = "The " + food + " was stored today. "
        else:
            if (delta_days.days <= 7):  # food is fresh
                speech_output = "The " + food + " is " + age + " days old."
            else:  # else yuck, the food is old
                speech_output = "The " + food + " is " + age + " days old. That might not be safe to eat. I recommend you throw it away."
    else:
        speech_output = "You do not have any " + food + " stored in your fridge...Perhaps I misunderstood?"
    # If the user either does not reply to the welcome message or says something
    # that is not understood, they will be prompted again with this text.
    reprompt_text = "I'm sorry - I didn't understand. You should ask me what's in your fridge or how old a food is..."
    should_end_session = False
    session_attributes = copy.deepcopy(foods)
    return build_response(session_attributes,
                          build_speechlet_response(card_title, speech_output, reprompt_text, should_end_session))

# this function updates the file with any changes made to the foods dictionary during the program, and also ends the session when called
def close_fridge():
    with open(fileName, 'w+') as f:
        for food, date in foods.items():
            print(str(food) + ":" + str(date) + "\n")
            f.write(str(food) + ":" + str(date) + "\n")
    session_attributes = {}
    card_title = "Close Fridge"
    speech_output = "Okay, your fridge is closed...Have a nice day!"
    # If the user either does not reply to the welcome message or says something
    # that is not understood, they will be prompted again with this text.
    reprompt_text = "I'm sorry - I didn't understand. You should ask me what's in your fridge or how old a food is..."
    should_end_session = True
    return build_response(session_attributes,
                          build_speechlet_response(card_title, speech_output, reprompt_text, should_end_session))

# --------------- Events ------------------

def on_session_started(session_started_request, session):
    """ Called when the session starts """

    print("on_session_started requestId=" + session_started_request['requestId']
          + ", sessionId=" + session['sessionId'])

def on_launch(launch_request, session):
    """ Called when the user launches the skill without specifying what they want """

    print("on_launch requestId=" + launch_request['requestId'] +
          ", sessionId=" + session['sessionId'])
    # Dispatch to your skill's launch
    open_fridge()
    return get_welcome_response()

def on_intent(intent_request, session):
    """ Called when the user specifies an intent for this skill """

    print("on_intent requestId=" + intent_request['requestId'] +
          ", sessionId=" + session['sessionId'])

    intent_name = intent_request['intent']['name']
    if 'sessionAttributes' in session:
        foods = copy.deepcopy(session['sessionAttributes'])
    # Dispatch to the skill's intent handlers
    if intent_name == "how_old":
        food = intent_request['intent']['slots']['food']['value']
        return how_old(food)
    elif intent_name == "whats_in_fridge":
        return whats_in_fridge()
    elif intent_name == "put_food_in":
        date = datetime.strftime(datetime.today(), "%m/%d/%Y")
        food = intent_request['intent']['slots']['food']['value']
        return put_food_in(food, date)
    elif intent_name == "take_food_out":
        food = intent_request['intent']['slots']['food']['value']
        return take_food_out(food)
    elif intent_name == "close_fridge":
        return close_fridge()
    elif intent_name == "AMAZON.HelpIntent":
        return get_welcome_response()
    elif intent_name == "AMAZON.CancelIntent" or intent_name == "AMAZON.StopIntent":
        return handle_session_end_request()
    else:
        raise ValueError("Invalid intent")

def on_session_ended(session_ended_request, session):
    """ Called when the user ends the session. Is not called when the skill returns should_end_session=true """
    print("on_session_ended requestId=" + session_ended_request['requestId'] +
          ", sessionId=" + session['sessionId'])

# --------------- Main handler ------------------

def lambda_handler(event, context):
    """ Route the incoming request based on type (LaunchRequest, IntentRequest,
    etc.) The JSON body of the request is provided in the event parameter.
    """
    print("event.session.application.applicationId=" +
          event['session']['application']['applicationId'])

    if event['session']['new']:
        on_session_started({'requestId': event['request']['requestId']},
                           event['session'])

    if event['request']['type'] == "LaunchRequest":
        return on_launch(event['request'], event['session'])
    elif event['request']['type'] == "IntentRequest":
        return on_intent(event['request'], event['session'])
    elif event['request']['type'] == "SessionEndedRequest":
        return on_session_ended(event['request'],
                                event['session'])


""" Constants for hass-AMS package"""

import serial

AIDON_METER_SEQ = [65, 73, 68, 79, 78, 95]
AMS_NEW_SENSORS = "ams_new_sensors"
AMS_SENSORS = "ams_sensors"
# Devices that we have read from the serial connection.
AMS_DEVICES = set()
AMS_SENSOR_CREATED_BUT_NOT_READ = set()

CONF_BAUDRATE = "baudrate"
CONF_METER_MANUFACTURER = "meter_manufacturer"
CONF_PARITY = "parity"
CONF_SERIAL_PORT = "serial_port"

DATA_FLAG = [230, 231, 0, 15]
DOMAIN = "ams"

DEFAULT_SERIAL_PORT = "/dev/ttyUSB0"
DEFAULT_BAUDRATE = 2400
DEFAULT_METER_MANUFACTURER = "auto"
DEFAULT_PARITY = serial.PARITY_NONE
DEFAULT_TIMEOUT = 0.1

FRAME_FLAG = b"\x7e"

KAIFA_METER_SEQ = [75, 102, 109, 95]
KAMSTRUP_METER_SEQ = [75, 97, 109, 115, 116, 114, 117, 112, 95]
LIST_TYPE_MINI = 1
LIST_TYPE_SHORT_1PH = 9
LIST_TYPE_LONG_1PH = 14
LIST_TYPE_SHORT_3PH = 13
LIST_TYPE_LONG_3PH = 18

HOURLY_SENSORS = [
    "ams_active_energy_import",
    "ams_active_energy_export",
    "ams_reactive_energy_import",
    "ams_reactive_energy_export",
]

ALL_SENSORS = [
    "ams_reactive_power_export",
    "ams_voltage_l3",
    "ams_active_power_export",
    "ams_voltage_l2",
    "ams_reactive_power_import",
    "ams_current_l1",
    "ams_voltage_l1",
    "ams_current_l2",
    "ams_active_power_import",
    "ams_current_l3",
] + HOURLY_SENSORS

MANUFACTURER_OPTIONS = ["auto", "aidon", "kaifa", "kamstrup"]

SIGNAL_UPDATE_AMS = "ams_update"
SIGNAL_NEW_AMS_SENSOR = "ams_new_sensor"

WEEKDAY_MAPPING = {
    1: "Monday",
    2: "Tuesday",
    3: "Wednesday",
    4: "Thursday",
    5: "Friday",
    6: "Saturday",
    7: "Sunday",
}


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

from horch.models.modules import get_norm_layer, Conv2d, get_activation

from horch.nas.darts.operations import OPS, FactorizedReduce, ReLUConvBN
from horch.nas.darts.genotypes import PRIMITIVES, Genotype

class MixedOp(nn.Module):

    def __init__(self, C):
        super().__init__()
        self._ops = nn.ModuleList()
        for primitive in PRIMITIVES:
            op = OPS[primitive](C, 1)
            if 'pool' in primitive:
                op = nn.Sequential(op, get_norm_layer(C))
            self._ops.append(op)

    def forward(self, x, hardwts, index):
        return sum(hardwts[i] * op(x) if i == index else hardwts[i] for i, op in enumerate(self._ops))

class NormalCell(nn.Module):

    def __init__(self, steps, multiplier, C_prev_prev, C_prev, C, reduction_prev):
        super().__init__()

        if reduction_prev:
            self.preprocess0 = FactorizedReduce(C_prev_prev, C)
        else:
            self.preprocess0 = ReLUConvBN(C_prev_prev, C, 1)
        self.preprocess1 = ReLUConvBN(C_prev, C, 1)
        self._steps = steps
        self._multiplier = multiplier

        self._ops = nn.ModuleList()
        for i in range(self._steps):
            ops = nn.ModuleList()
            for j in range(2 + i):
                op = MixedOp(C)
                ops.append(op)
            self._ops.append(ops)

    def forward(self, s0, s1, hardwts, indices):
        s0 = self.preprocess0(s0)
        s1 = self.preprocess1(s1)

        states = [s0, s1]
        for i in range(self._steps):
            s = sum(self._ops[i][j](h, hardwts[i][j], int(indices[i][j])) for j, h in enumerate(states))
            states.append(s)

        return torch.cat(states[-self._multiplier:], dim=1)

class ReductionCell(nn.Module):

    def __init__(self, C_prev_prev, C_prev, C):
        super().__init__()
        self.preprocess0 = ReLUConvBN(C_prev_prev, C, 1)
        self.preprocess1 = ReLUConvBN(C_prev, C, 1)

        self.branch_a1 = nn.Sequential(
            get_activation(),
            Conv2d(C, C, (1, 3), stride=(1, 2), groups=8, bias=False),
            Conv2d(C, C, (3, 1), stride=(2, 1), groups=8, bias=False),
            get_norm_layer(C, affine=True),
            get_activation(),
            Conv2d(C, C, 1),
            get_norm_layer(C, affine=True),
        )
        self.branch_a2 = nn.Sequential(
            nn.MaxPool2d(3, stride=2, padding=1),
            get_norm_layer(C, affine=True)
        )
        self.branch_b1 = nn.Sequential(
            get_activation(),
            Conv2d(C, C, (1, 3), stride=(1, 2), groups=8, bias=False),
            Conv2d(C, C, (3, 1), stride=(2, 1), groups=8, bias=False),
            get_norm_layer(C, affine=True),
            get_activation(),
            Conv2d(C, C, 1),
            get_norm_layer(C, affine=True),
        )
        self.branch_b2 = nn.Sequential(
            nn.MaxPool2d(3, stride=2, padding=1),
            get_norm_layer(C, affine=True)
        )

    def forward(self, s0, s1, *args):
        s0 = self.preprocess0(s0)
        s1 = self.preprocess1(s1)

        x0 = self.branch_a1(s0)
        x1 = self.branch_a2(s1)
        # if self.training and drop_prob > 0.:
        #     X0, X1 = drop_path(X0, drop_prob), drop_path(X1, drop_prob)

        x2 = self.branch_b1(s0)
        x3 = self.branch_b2(s1)
        # if self.training and drop_prob > 0.:
        #     X2, X3 = drop_path(X2, drop_prob), drop_path(X3, drop_prob)

        return torch.cat([x0, x1, x2, x3], dim=1)

def gumbel_sample(a, tau):
    while True:
        gumbels = -torch.empty_like(a).exponential_().log()
        logits = (a.log_softmax(dim=1) + gumbels) / tau
        probs = nn.functional.softmax(logits, dim=1)
        index = probs.max(-1, keepdim=True)[1]
        one_h = torch.zeros_like(logits).scatter_(-1, index, 1.0)
        hardwts = one_h - probs.detach() + probs
        if (torch.isinf(gumbels).any()) or (torch.isinf(probs).any()) or (torch.isnan(probs).any()):
            continue
        else:
            return hardwts, [int(i) for i in index.cpu().numpy()]

class Network(nn.Module):

    def __init__(self, C, layers, steps=4, multiplier=4, stem_multiplier=3, num_classes=10, tau=10.0):
        super().__init__()
        self.C = C
        self.num_classes = num_classes
        self.layers = layers
        self.steps = steps
        self.multiplier = multiplier
        self.tau = tau

        C_curr = stem_multiplier * C
        self.stem = nn.Sequential(
            Conv2d(3, C_curr, kernel_size=3, bias=False),
            get_norm_layer(C_curr),
        )

        C_prev_prev, C_prev, C_curr = C_curr, C_curr, C
        self.cells = nn.ModuleList()
        reduction_prev = False
        for i in range(layers):
            if i in [layers // 3, 2 * layers // 3]:
                C_curr *= 2
                reduction = True
            else:
                reduction = False
            if reduction:
                cell = ReductionCell(C_prev_prev, C_prev, C_curr)
            else:
                cell = NormalCell(steps, multiplier, C_prev_prev, C_prev, C_curr, reduction_prev)
            reduction_prev = reduction
            self.cells.append(cell)
            C_prev_prev, C_prev = C_prev, multiplier * C_curr

        self.post_activ = nn.Sequential(
            get_norm_layer(C_prev),
            get_activation(),
        )
        self.avg_pool = nn.AdaptiveAvgPool2d(1)
        self.classifier = nn.Linear(C_prev, num_classes)

        self._initialize_alphas()

    def forward(self, x):
        hardwts, indices = zip(*[ gumbel_sample(a, self.tau) for a in self.alphas ])
        s0 = s1 = self.stem(x)
        for cell in self.cells:
            s0, s1 = s1, cell(s0, s1, hardwts, indices)
        s1 = self.post_activ(s1)
        out = self.avg_pool(s1)
        logits = self.classifier(out.view(out.size(0), -1))
        return logits

    def _initialize_alphas(self):
        num_ops = len(PRIMITIVES)

        self.alphas = nn.ParameterList([
            nn.Parameter(1e-3 * torch.randn(i + 2, num_ops), requires_grad=True)
            for i in range(self.steps)
        ])

    def model_parameters(self):
        ids = set(id(p) for p in self.arch_parameters())
        for p in self.parameters():
            if id(p) not in ids:
                yield p

    def arch_parameters(self):
        return self.alphas.parameters()

    def genotype(self):

        def _parse(weights):
            gene = []
            for i in range(self.steps):
                W = weights[i].copy()
                edges = sorted(
                    range(i + 2),
                    key=lambda x: -max(W[x][k] for k in range(len(W[x])) if k != PRIMITIVES.index('none')))[:2]
                for j in edges:
                    k_best = None
                    for k in range(len(W[j])):
                        if k != PRIMITIVES.index('none'):
                            if k_best is None or W[j][k] > W[j][k_best]:
                                k_best = k
                    gene.append((PRIMITIVES[k_best], j))
            return gene

        gene_normal = _parse([F.softmax(w.detach().cpu(), dim=0).numpy() for w in self.alphas])

        concat = range(2 + self.steps - self.multiplier, self.steps + 2)
        genotype = Genotype(
            normal=gene_normal, normal_concat=concat,
        )
        return genotype


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

from .misc import (NestedTensor, nested_tensor_from_tensor_list,
                   accuracy, get_world_size, interpolate,
                   is_dist_avail_and_initialized)
# from models.py_utils import box_ops
# from .segmentation import (DETRsegm, PostProcessPanoptic, PostProcessSegm,
#                            dice_loss, sigmoid_focal_loss)

class SetCriterion(nn.Module):
    """ This class computes the loss for DETR.
    The process happens in two steps:
        1) we compute hungarian assignment between ground truth boxes and the outputs of the model
        2) we supervise each pair of matched ground-truth / prediction (supervise class and box)
    """
    def __init__(self, num_classes, matcher, weight_dict, eos_coef, losses, seq_len, db=None):
        """ Create the criterion.
        Parameters:
            num_classes: number of object categories, omitting the special no-object category
            matcher: module able to compute a matching between targets and proposals
            weight_dict: dict containing as key the names of the losses and as values their relative weight.
            eos_coef: relative classification weight applied to the no-object category
            losses: list of all the losses to be applied. See get_loss for list of available losses.
        """
        super().__init__()
        self.num_classes = num_classes
        self.matcher = matcher
        self.weight_dict = weight_dict
        self.eos_coef = eos_coef
        self.losses = losses
        # threshold = 15 / 720.
        # self.threshold = nn.Threshold(threshold**2, 0.)
        empty_weight = torch.ones(self.num_classes + 1)
        # print('empty_weight: {}'.format(empty_weight))
        empty_weight[-1] = self.eos_coef
        # print('empty_weight: {}'.format(empty_weight))
        # exit()
        self.seq_len = seq_len
        self.db = db

        self.register_buffer('empty_weight', empty_weight)

    def loss_labels(self, outputs, targets, indices, num_boxes, target_flags, heights, pitches, log=True):
        """Classification loss (NLL)
        targets dicts must contain the key "labels" containing a tensor of dim [nb_target_boxes]
        """
        assert 'pred_logits' in outputs
        src_logits = outputs['pred_logits']
        idx = self._get_src_permutation_idx(indices)
        target_classes_o = torch.cat([tgt[:, 0][J].long() for tgt, (_, J) in zip (targets, indices)])
        target_classes = torch.full(src_logits.shape[:2], self.num_classes, dtype=torch.int64, device=src_logits.device)
        target_classes[idx] = target_classes_o
        loss_ce = F.cross_entropy(src_logits.transpose(1, 2), target_classes, self.empty_weight)
        losses = {'loss_ce': loss_ce}

        if log:
            # TODO this should probably be a separate loss, not hacked in this one here
            losses['class_error'] = 100 - accuracy(src_logits[idx], target_classes_o)[0]
        return losses

    @torch.no_grad()
    def loss_cardinality(self, outputs, targets, indices, num_boxes, target_flags, heights, pitches):
        """ Compute the cardinality error, ie the absolute error in the number of predicted non-empty boxes
        This is not really a loss, it is intended for logging purposes only. It doesn't propagate gradients
        """
        pred_logits = outputs['pred_logits']
        device = pred_logits.device
        tgt_lengths = torch.as_tensor([tgt.shape[0] for tgt in targets], device=device)
        card_pred = (pred_logits.argmax(-1) != pred_logits.shape[-1] - 1).sum(1)
        card_err = F.l1_loss(card_pred.float(), tgt_lengths.float())
        losses = {'cardinality_error': card_err}
        return losses

    def loss_boxes(self, outputs, targets, indices, num_boxes, target_flags, heights, pitches):
        """
        Will released after acceptance
        """
        losses = {}

        losses['loss_3dspace_XS'] = 0
        losses['loss_3dspace_ZS'] = 0

        losses['loss_3dspace_lowers'] = 0
        losses['loss_3dspace_uppers'] = 0

        losses['loss_gflat_XS'] = 0
        losses['loss_gflat_YS'] = 0

        losses['loss_polys'] = 0
        losses['loss_ys'] = 0

        losses['loss_cam_heights'] = 0
        losses['loss_cam_pitches'] = 0

        return losses

    def _get_src_permutation_idx(self, indices):
        # permute predictions following indices
        batch_idx = torch.cat([torch.full_like(src, i) for i, (src, _) in enumerate(indices)])
        src_idx = torch.cat([src for (src, _) in indices])

        return batch_idx, src_idx

    def _get_tgt_permutation_idx(self, indices):
        # permute targets following indices
        batch_idx = torch.cat([torch.full_like(tgt, i) for i, (_, tgt) in enumerate(indices)])
        tgt_idx = torch.cat([tgt for (_, tgt) in indices])
        return batch_idx, tgt_idx

    def get_loss(self, loss, outputs, targets, indices, num_boxes, target_flags, heights, pitches, **kwargs):
        loss_map = {
            'labels': self.loss_labels,
            'cardinality': self.loss_cardinality,
            'boxes': self.loss_boxes,
        }
        assert loss in loss_map, f'do you really want to compute {loss} loss?'
        return loss_map[loss](outputs, targets, indices, num_boxes, target_flags, heights, pitches, **kwargs)

    def forward(self, outputs, targets, targets_flag, heights, pitches):
        """ This performs the loss computation.
        Parameters:
             outputs: dict of tensors, see the output specification of the model for the format
             targets: list of dicts, such that len(targets) == batch_size.
                      The expected keys in each dict depends on the losses applied, see each loss' doc
        """
        outputs_without_aux = {k: v for k, v in outputs.items() if k != 'aux_outputs'}

        # Retrieve the matching between the outputs of the last layer and the targets
        indices = self.matcher(outputs_without_aux, targets, targets_flag)

        # Compute the average number of target boxes accross all nodes, for normalization purposes
        num_boxes = sum(tgt.shape[0] for tgt in targets)
        num_boxes = torch.as_tensor([num_boxes], dtype=torch.float, device=next(iter(outputs.values())).device)
        if is_dist_avail_and_initialized():
            torch.distributed.all_reduce(num_boxes)
        num_boxes = torch.clamp(num_boxes / get_world_size(), min=1).item()

        # Compute all the requested losses
        losses = {}
        for loss in self.losses:
            losses.update(self.get_loss(loss, outputs, targets, indices, num_boxes, targets_flag, heights, pitches))

        # In case of auxiliary losses, we repeat this process with the output of each intermediate layer.
        if 'aux_outputs' in outputs:
            for i, aux_outputs in enumerate(outputs['aux_outputs']):
                indices = self.matcher(aux_outputs, targets, targets_flag)
                for loss in self.losses:
                    if loss == 'masks':
                        # Intermediate masks losses are too costly to compute, we ignore them.
                        continue
                    kwargs = {}
                    if loss == 'labels':
                        # Logging is enabled only for the last layer
                        kwargs = {'log': False}
                    l_dict = self.get_loss(loss, aux_outputs, targets, indices, num_boxes, targets_flag, heights, pitches, **kwargs)
                    l_dict = {k + f'_{i}': v for k, v in l_dict.items()}
                    losses.update(l_dict)

        return losses, indices


import h5py
import numpy as np
import scipy.io as sio
from collections import defaultdict
import copy

def parse_h5py(path, file_name):
    """
    A function to parse h5py format .mat file (v7.3)
    """
    def arr_to_str(b):
        if isinstance(b, list) == 0:
           return ''.join([chr(int(each)) for each in b])
        else:
            b_ = []
            for each in b:
                b_.append(''.join([chr(c) for c in each]))
            return b_

    def parse_meta(raw_meta):
        meta = {}
        meta['ranBy'] = ''.join([chr(int(each)) for each in np.asarray(raw_meta['ranBy'])])
        meta['monkey'] = ''.join([chr(int(each)) for each in np.asarray(raw_meta['monkey'])])
        meta['array'] = ''.join([chr(int(each)) for each in np.asarray(raw_meta['array'])])
        meta['dateTime'] = ''.join([chr(int(each)) for each in np.asarray(raw_meta['dateTime'])])
        meta['processedTime'] = ''.join([chr(int(each)) for each in np.asarray(raw_meta['processedTime'])])
        meta['rawFileName'] = ''.join([chr(int(each)) for each in np.asarray(raw_meta['rawFileName'])])
        meta['task'] = ''.join([chr(int(each)) for each in np.asarray(raw_meta['task'])])
        meta['duration'] = np.asarray(raw_meta['duration'])[0][0]
        meta['lab'] = np.asarray(raw_meta['lab'])[0][0]
        meta['numTrials'] = np.asarray(raw_meta['numTrials'])[0][0]
        meta['numReward'] = np.asarray(raw_meta['numReward'])[0][0]
        meta['numAbort'] = np.asarray(raw_meta['numAbort'])[0][0]
        meta['numFail'] = np.asarray(raw_meta['numFail'])[0][0]
        meta['dataWindow'] = np.asarray(raw_meta['dataWindow'])
        return meta

    parsed = {}
    if path[-1] != '/':
        path = path + '/'
    read_data = h5py.File(path + file_name, 'r')
    xds = read_data['xds']

    parsed['has_EMG'] = np.asarray(xds['has_EMG'])[0][0]
    parsed['has_force'] = np.asarray(xds['has_force'])[0][0]
    parsed['has_kin'] = np.asarray(xds['has_kin'])[0][0]
    parsed['has_cursor'] = np.asarray(xds['has_kin'])[0][0]
    parsed['sorted'] = np.asarray(xds['sorted'])[0][0]
    parsed['bin_width'] = np.asarray(xds['bin_width'])[0][0]
    try:
        parsed['has_raw_EMG'] = np.asarray(xds['has_raw_EMG'])[0][0]
    except Exception:
        parsed['has_raw_EMG'] = 0
    try:
        parsed['has_raw_force'] = np.asarray(xds['has_raw_force'])[0][0]
    except Exception:
        parsed['has_raw_force'] = 0

    parsed['spikes'] = [read_data[xds['spikes'][i][0]][()].T for i in range(len(xds['spikes']))]
    parsed['spike_counts'] = np.asarray(xds['spike_counts'], dtype = np.uint8).T
    temp = [read_data[xds['unit_names'][i][0]][()] for i in range( len(xds['unit_names']) )]
    parsed['unit_names'] = [arr_to_str(each) for each in temp]
    parsed['time_frame'] = np.asarray(xds['time_frame']).reshape((-1, ))

    if 'spike_waveforms' in xds.keys():
        parsed['spike_waveforms'] = [read_data[xds['spike_waveforms'][i][0]][()].T for i in range(len(xds['spike_waveforms']))]
    if 'EMG' in xds.keys():
        parsed['EMG'] = np.asarray(xds['EMG']).T
        temp = [read_data[xds['EMG_names'][i][0]][()] for i in range( len(xds['EMG_names']) )]
        parsed['EMG_names'] = [arr_to_str(each) for each in temp]
    if 'raw_EMG' in xds.keys():
        parsed['raw_EMG'] = np.asarray(xds['raw_EMG']).T
        parsed['raw_EMG_time_frame'] = np.asarray(xds['raw_EMG_time_frame']).reshape((-1, ))
    if 'force' in xds.keys():
        parsed['force'] = np.asarray(xds['force']).T
    if 'raw_force' in xds.keys():
        parsed['raw_force'] = np.asarray(xds['raw_force']).T
        parsed['raw_force_time_frame'] = np.asarray(xds['raw_force_time_frame']).reshape((-1, ))
    if 'curs_p' in xds.keys():
        parsed['curs_p'] = np.asarray(xds['curs_p']).T
        parsed['curs_v'] = np.asarray(xds['curs_v']).T
        parsed['curs_a'] = np.asarray(xds['curs_a']).T
    elif 'kin_p' in xds.keys():
        parsed['curs_p'] = np.asarray(xds['kin_p']).T
        parsed['curs_v'] = np.asarray(xds['kin_v']).T
        parsed['curs_a'] = np.asarray(xds['kin_a']).T
    # -------- in some files this flag is not right, so we need to fix it -------- #
    if 'has_cursor' in parsed.keys():
        if parsed['has_cursor'] == 0:
            if 'curs_p' in parsed.keys():
                if len(parsed['curs_p'])>0:
                    parsed['has_cursor'] = 1

    # -------- handling trial timing related variables -------- #
    parsed['trial_start_time'] = np.asarray(xds['trial_start_time']).reshape((-1, ))
    parsed['trial_end_time'] = np.asarray(xds['trial_end_time']).reshape((-1, ))
    # -------- gocue_time may have different format from different tasks -------- #
    if xds['trial_gocue_time'].shape[0] == 1:
        parsed['trial_gocue_time'] = np.asarray(xds['trial_gocue_time']).reshape((-1, ))
    elif xds['trial_gocue_time'].shape[0] > 1:
        parsed['trial_gocue_time'] = np.asarray(xds['trial_gocue_time']).T
    else:
        print('something wrong with the gocue time')
    # -------- handling target related variables -------- #
    parsed['trial_target_dir'] = np.asarray(xds['trial_target_dir']).reshape((-1, ))
    parsed['trial_target_corners'] = np.asarray(xds['trial_target_corners']).T
    parsed['trial_result'] = np.asarray([chr(each) for each in np.asarray(xds['trial_result']).reshape((-1, ))])

    temp = [read_data[xds['trial_info_table_header'][0][i]][()] for i in range( xds['trial_info_table_header'].shape[1] )]
    parsed['trial_info_table_header'] = [arr_to_str(each) for each in temp]

    r, c = xds['trial_info_table'].shape
    trial_info_table = []
    for i in range(r):
        temp = []
        for j in range(c):
            temp.append(read_data[xds['trial_info_table'][i][j]][()])
        trial_info_table.append(temp)
    parsed['trial_info_table'] = trial_info_table

    parsed['meta'] = parse_meta(xds['meta'])

    read_data.close()
    return parsed

def parse_scipy(path, file_name):
    parsed = {}
    if path[-1] != '/':
        path = path + '/'
    read_data = sio.loadmat(path + file_name)
    xds = read_data['xds']

    # -------- meta information -------- #
    parsed['meta'] = {}
    parsed['meta']['monkey'] = xds['meta'][0][0]['monkey'][0][0][0]
    parsed['meta']['task'] = xds['meta'][0][0]['task'][0][0][0]
    parsed['meta']['duration'] = xds['meta'][0][0]['duration'][0][0][0][0]
    parsed['meta']['dateTime'] = xds['meta'][0][0]['dateTime'][0][0][0]
    parsed['meta']['rawFileName'] = xds['meta'][0][0]['rawFileName'][0][0][0]
    parsed['meta']['array'] = xds['meta'][0][0]['array'][0][0][0]
    parsed['meta']['processedTime'] = xds['meta'][0][0]['processedTime'][0][0][0]
    parsed['meta']['ranBy'] = xds['meta'][0][0]['ranBy'][0][0][0]
    parsed['meta']['lab'] = xds['meta'][0][0]['lab'][0][0][0][0]
    parsed['meta']['numTrials'] = xds['meta'][0][0]['numTrials'][0][0][0][0]
    parsed['meta']['numReward'] = xds['meta'][0][0]['numReward'][0][0][0][0]
    parsed['meta']['numAbort'] = xds['meta'][0][0]['numAbort'][0][0][0][0]
    parsed['meta']['numFail'] = xds['meta'][0][0]['numFail'][0][0][0][0]
    parsed['meta']['dataWindow'] = xds['meta'][0][0]['dataWindow'][0][0][0]

    # -------- flag variables -------- #
    parsed['has_EMG'] = xds['has_EMG'][0][0][0][0]
    parsed['has_kin'] = xds['has_kin'][0][0][0][0]
    parsed['has_cursor'] = parsed['has_kin']
    parsed['has_force'] = xds['has_force'][0][0][0][0]
    parsed['sorted'] = xds['sorted'][0][0][0][0]
    parsed['bin_width'] = xds['bin_width'][0][0][0][0]
    try:
        parsed['has_raw_force'] = xds['has_raw_force'][0][0][0][0]
    except Exception:
        parsed['has_raw_force'] = 0
    try:
        parsed['has_raw_EMG'] = xds['has_raw_EMG'][0][0][0][0]
    except Exception:
        parsed['has_raw_EMG'] = 0

    # -------- data -------- #
    parsed['time_frame'] = xds['time_frame'][0][0].reshape((-1, ))
    parsed['spike_counts'] = xds['spike_counts'][0][0]
    parsed['spikes'] = xds['spikes'][0][0][0].tolist()
    parsed['unit_names'] = [each.tolist()[0] for each in xds['unit_names'][0][0][0]]
    try:
        parsed['spike_waveforms'] = xds['spike_waveforms'][0][0][0].tolist()
    except Exception:
        pass
    try:
        parsed['EMG'] = xds['EMG'][0][0]
        parsed['EMG_names'] = [each.tolist()[0] for each in xds['EMG_names'][0][0][0]]
    except Exception:
        pass
    try:
        parsed['force'] = xds['force'][0][0]
    except Exception:
        pass
    try:
        parsed['curs_p'] = xds['curs_p'][0][0]
        parsed['curs_v'] = xds['curs_v'][0][0]
        parsed['curs_a'] = xds['curs_a'][0][0]
    except Exception:
        try:
           parsed['curs_p'] = xds['kin_p'][0][0]
           parsed['curs_v'] = xds['kin_v'][0][0]
           parsed['curs_a'] = xds['kin_a'][0][0]
        except Exception:
            pass
    # -------- in some files this flag is not right, so we need to fix it -------- #
    if parsed['has_cursor'] == 0:
        if 'curs_p' in parsed.keys():
            if len(parsed['curs_p'])>0:
                parsed['has_cursor'] = 1

    try:
        parsed['raw_EMG'] = xds['raw_EMG'][0][0]
        parsed['raw_EMG_time_frame'] = xds['raw_EMG_time_frame'][0][0]
    except Exception:
        pass
    try:
        parsed['raw_force'] = xds['raw_force'][0][0]
        parsed['raw_force_time_frame'] = xds['raw_force_time_frame'][0][0]
    except Exception:
        pass
    # -------- trial information -------- #
    parsed['trial_start_time'] = xds['trial_start_time'][0][0]
    parsed['trial_end_time'] = xds['trial_end_time'][0][0]
    parsed['trial_gocue_time'] = xds['trial_gocue_time'][0][0]
    parsed['trial_target_corners'] = xds['trial_target_corners'][0][0]
    parsed['trial_target_dir'] = xds['trial_target_dir'][0][0]
    parsed['trial_result'] = xds['trial_result'][0][0]
    parsed['trial_info_table'] = xds['trial_info_table'][0][0].T.tolist()
    parsed['trial_info_table_header'] = [str(each.tolist()[0][0]) for each in xds['trial_info_table_header'][0][0]]

    return parsed

def get_char_pos(string, char):
  chPos=[]
  try:
    chPos=list(((pos,char) for pos,val in enumerate(string) if(val == char)))
  except:
    pass
  return chPos

def get_paired_EMG_index(EMG_names_single):
    EMG_names = []
    EMG_index1 = []
    EMG_index2 = []
    for i in range(len(EMG_names_single)):
        temp_str = EMG_names_single[i][:-2]
        if temp_str in EMG_names:
            continue
        else:
            for j in range(i+1, len(EMG_names_single)):
                temp_str2 = EMG_names_single[j]
                if temp_str2.find(temp_str) != -1:
                    if (temp_str2[:-2] in EMG_names) == True:
                        EMG_names.append(''.join( (temp_str2[:-2], '-3') ))
                    else:
                        EMG_names.append(temp_str)
                    EMG_index1.append(EMG_names_single.index(EMG_names_single[i]))
                    EMG_index2.append(EMG_names_single.index(EMG_names_single[j]))
    return EMG_names, EMG_index1, EMG_index2

def find_bad_EMG_index_from_list(EMG_names_single, bad_EMG):
    bad_index = []
    paired_index = []
    for each in bad_EMG:
        temp = list(each)
        if each[-1] == '1':
           temp[-1] = '2'
        elif each[-1] == '2':
            temp[-1] = '1'
        elif each[-1] == '3':
            temp[-1] = '1'
        paired_name = ''.join(temp)
        # -------- Make sure the paired EMG channel can be found ---------- #
        if paired_name in EMG_names_single:
            bad_index.append(EMG_names_single.index(each))
            paired_index.append(EMG_names_single.index(paired_name))
    return bad_index, paired_index

def delete_paired_bad_channel(EMG_names_single, bad_EMG):
    """
    If both of the two single end channels are noise, then we need to get rid of both
    This function will find out the indices of them. Deleting will be done outside of this function
    """
    def list_duplicates(seq):
        tally = defaultdict(list)
        for i,item in enumerate(seq):
            tally[item].append(i)
        return ((key,locs) for key,locs in tally.items() if len(locs)>1)

    temp = []
    for each in bad_EMG:
        temp.append(each[:-1])
    bad_paired_channel = []
    names = []
    for dup in sorted(list_duplicates(temp)):
        print( 'The paired channels of %s will be deleted'%(dup[0]) )
        name1, name2 = bad_EMG[dup[1][0]], bad_EMG[dup[1][1]]
        names.append(name1)
        names.append(name2)
        bad_paired_channel.append(EMG_names_single.index(name1))
        bad_paired_channel.append(EMG_names_single.index(name2))
    bad_EMG_post = copy.deepcopy(bad_EMG)
    for each in names:
        bad_EMG_post.remove(each)
    print('The numbers of these bad channels are %s' % (bad_paired_channel))
    return bad_paired_channel, bad_EMG_post

def find_force_onset(force_list, ch, thr = 0.4):
    """
    This function is designed to find out the force onset time for each trial
    force_list: a list of force signals, each element corresponds to a trial
    ch: the number used to specify which force channel to use, typically 0 or 1, for Fx or Fy
    thr: the threshold to determine whether the force is on
    """
    onset_num = []
    for each in force_list:
        f = np.sqrt(each[:, 0]**2 + each[:, 1]**2)
        df = np.diff(f)
        temp = np.where(df >= thr*np.max(df))[0]
        if len(temp) == 0:
            onset_num.append(0)
        else:
            onset_num.append(temp[0])
    return onset_num

def find_movement_onset(var_list, ch, thr):
    """
    The design of this function is the same as the function above, but not just for force signals
    the var_list is supposed to be a list containing movement trajectories, or velocities
    """
    onset_num = []
    for each in var_list:
        f = np.sqrt(each[:, 0]**2 + each[:, 1]**2)
        df = np.diff(f)
        temp = np.where(df >= thr*np.max(df))[0]
        if len(temp) == 0:
            onset_num.append(0)
        else:
            onset_num.append(temp[0])
    return onset_num

def find_target_dir(trial_curs_p, target_list = [-135, -90, -45, 0, 45, 90, 135, 180]):
    """
    This function is used to find out the directions of trials, because sometimes they are wrong in origninal recordings
    curs_p: a list containing the cursor trajectories for each trial
    """
    dirs = []
    for each in trial_curs_p:
        s = each[-1, :] - each[0, :]
        x, y = s[0], s[1]
        if (x>0)&(y==0):
            dirs.append(0)
        elif (x<0)&(y==0):
            dirs.append(180)
        elif (x==0)&(y>0):
            dirs.append(90)
        elif (x==0)&(y<0):
            dirs.append(-90)
        elif (x>0)&(y!=0):
            dirs.append(np.arctan(y/x)*180/np.pi)
        elif (x<0)&(y!=0):
            dirs.append(np.arctan(y/x)*180/np.pi+y/abs(y)*180)
    dirs_ = []
    for each in dirs:
        if each<=-157.5:
            dirs_.append(180)
        else:
            idx = np.argmin(abs(target_list - each))
            dirs_.append(target_list[idx])
    return np.array(dirs_)


import numpy as np

class obj_from_dict:
    def __init__(self, dictto):
        for kk in dictto.keys():
            setattr(self, kk, dictto[kk])

def obj_to_dict(obj):
    dict_out={}
    members = dir(obj)
    for member in members:
        dict_out[member] = getattr(obj, member)
    return dict_out

def myloadmat(filename, squeeze = True):
    import scipy.io as sio
    dict_var=sio.loadmat(filename)
    if squeeze:
        for kk in dict_var.keys():
            try:
                dict_var[kk]=np.squeeze(dict_var[kk])
            except:
                pass
    return dict_var

def myloadmat_to_obj(filename, squeeze = True):
    return  obj_from_dict(myloadmat(filename, squeeze=squeeze))

def dict_of_arrays_and_scalar_from_h5(filename):
    import h5py
    with h5py.File(filename, 'r') as fid:
        f_dict = {}
        for kk in fid.keys():
            f_dict[kk] = np.array(fid[kk]).copy()
            if f_dict[kk].shape == ():
                f_dict[kk] = f_dict[kk].tolist()
    return  f_dict

def object_with_arrays_and_scalar_from_h5(filename):
    return  obj_from_dict(dict_of_arrays_and_scalar_from_h5(filename))

def monitorh5_to_dict(filename, key= 'Bunch'):
    import h5py
    with h5py.File(filename, 'r') as monitor_ev:
        monitor = monitor_ev[key]
        monitor_dict = {}
        for kk in monitor.keys():
            monitor_dict[kk] = np.array(monitor[kk]).copy()

    return monitor_dict

def monitorh5_to_obj(filename, key= 'Bunch'):
    return  obj_from_dict(monitorh5_to_dict(filename, key))

def monitorh5list_to_dict(filename_list, key='Bunch', permissive=False):
    monitor_dict = monitorh5_to_dict(filename_list[0], key=key)
    for i_file in xrange(1,len(filename_list)):
        print('Loading '+filename_list[i_file])
        try:
            monitor_dict_curr = monitorh5_to_dict(filename_list[i_file])
            for kk in monitor_dict.keys():
                monitor_dict[kk] = np.array(list(monitor_dict[kk])+list(monitor_dict_curr[kk]))
        except IOError as err:
            print('Got:')
            print(err)
            if not permissive:
                raise err

    return monitor_dict

def monitorh5list_to_obj(filename_list, key= 'Bunch', permissive=False):
    return  obj_from_dict(monitorh5list_to_dict(filename_list, key, permissive))

def dict_to_h5(dict_save, filename):
    import h5py
    with h5py.File(filename, 'w') as fid:
        for kk in dict_save.keys():
                fid[kk] = dict_save[kk]


"""
TARGET_URL に対して負荷テストを行う。
CONCURRENT_NUMで並行度を指定
Througput, Latency, Latencyの分布などが出力される
"""

import time
import random
import numpy as np
import urllib.request
import urllib
from urllib.error import HTTPError
import socket
from concurrent.futures import ThreadPoolExecutor
from urllib3 import PoolManager

CONCURRENT_NUM = 2
TARGET_URL = "http:/hoge.com"

HEADERS = {
    'Connection': 'Close',
}
manager = PoolManager(CONCURRENT_NUM, retries=False)

def request(query):
    param = urllib.parse.urlencode({"query": query})
    timeout = False
    try:
        begin = time.time()
        resp = manager.request('GET', TARGET_URL + '?' + param, headers=HEADERS)
        resp.close()
        end = time.time()
        status = 200
    except HTTPError as e:
        end = time.time()
        status = e.code
    except socket.timeout:
        end = time.time()
        status = 0
        timeout = True
    except Exception:
        end = time.time()
        status = 400
        timeout = True

    return (end - begin, status, timeout)

futures = []
cnt = 0
queries = []
for line in open("data/queries.txt"):
    queries.append(line.rstrip("\n"))

random.shuffle(queries)
all_begin = time.time()
with ThreadPoolExecutor(max_workers=CONCURRENT_NUM) as executor:
    for query in queries:
        future = executor.submit(request, query)
        futures.append(future)

num_timeout = 0
statuses = {}  # type: dict
_elapses = []
for future in futures:
    (elapsed, status, timeout) = future.result()
    _elapses.append(elapsed)
    statuses[status] = statuses.get(status, 0) + 1
    if timeout:
        num_timeout += 1
all_end = time.time()
query_num = len(queries)

elapses = np.array(_elapses)
elapses = elapses * 1000
print("Overall throuputs: {0:>3} query/sec".format(round(query_num / (all_end - all_begin)), 3))
print("Number of requests: {0}".format(len(elapses)))
for status in statuses:
    print("Status code {0} requests: {1}".format(status, statuses[status]))
print("Timeout requests: " + str(num_timeout))
print("Average latency (msec): " + str(round(np.sum(elapses) / len(elapses), 3)))
for i in [50, 66, 75, 80, 90, 95, 98, 99, 100]:
    latency = round(np.percentile(elapses, i), 3)
    print("{0:>3} th percentile latency (msec): {}".format(i, latency))

for i in range(11):
    if i == 0:
        counts = len(elapses[np.logical_and(elapses >= 0, elapses <= 10)])
        print("  0 -  10: {0}".format(counts))
    elif i == 10:
        counts = len(elapses[elapses > 100])
        print("101 -    : {0}".format(counts))
    else:
        counts = len(elapses[np.logical_and(elapses > (i * 10), elapses <= (i + 1) * 10)])
        print("{0:>3} - {1:>3}: {2}".format(i * 10, (i + 1) * 10, counts))


# -*- coding: utf-8 -*-
# Author: CEF PNM Team
# License: TBD
# Copyright (c) 2012

#from __future__ import print_function

"""
module __GenericGeometry__: Base class to construct pore networks
==================================================================

.. warning:: The classes of this module should be loaded through the 'Geometry.__init__.py' file.

"""

import OpenPNM
import scipy as sp
import scipy.io as spio
import os
from .__GenericNetwork__ import GenericNetwork

class MatFile(GenericNetwork):
    r"""
    MatFile - constructs a pore network from a perfectly formatted .mat file (MATLAB)

    This class contains the interface definition for the construction
    of networks

    Parameters
    ----------

    loglevel : int
        Level of the logger (10=Debug, 20=Info, 30=Warning, 40=Error, 50=Critical)
    all other parameters are in the generate() command

    """
    def __init__(self, **kwargs):

        r"""
        Initialize
        """
        super(MatFile,self).__init__(**kwargs)

    def generate(self,filename='standard_cubic_5x5x5.mat', path='LocalFiles', xtra_pore_data=None, xtra_throat_data=None):
        '''
        Create network from Matlab file. Returns OpenPNM.Network.GenericNetwork() object.

        Parameters
        ----------

        Critical\n
        filename : string
            filename = 'standard_cubic_5x5x5.mat' (default)\n
            Name of mat file\n
        path : string
            path='LocalFiles' (default)\n
            the location of the mat file on your computer \n
        xtra_pore_data : list of strings
            xtra_pore_data = ['type','shape','material']
            any additional props to look for in the dictionary
        xtra_throat_data : list of strings
            xtra_throat_data = ['type','shape','material']
            any additional props to look for in the dictionary

        Examples:
        ---------

        generate network using example mat file

        >>> import OpenPNM as PNM
        >>> pn=PNM.Geometry.MatFile(filename='standard_cubic_5x5x5.mat', path='LocalFiles')
        '''
        if path == 'LocalFiles':
            long_path = os.path.abspath(__file__)
            short_path, fname = os.path.split(long_path)
            short_path, foldername = os.path.split(short_path)
            path, foldername = os.path.split(short_path)
            path = os.path.join(path,'LocalFiles')
        self._path = path
        filepath = os.path.join(self._path,filename)
        self._xtra_pore_data=xtra_pore_data
        self._xtra_throat_data=xtra_throat_data
        self._dictionary=spio.loadmat(filepath)

        self._Np=sp.size(self._dictionary['pnumbering'])
        self._Nt=sp.size(self._dictionary['tnumbering'])

        #Run through generation steps
        self._add_pores()
        self._add_throats()
        self._add_geometry()
        self._add_xtra_pore_data()
        self._add_xtra_throat_data()

        return self

    def _add_pores(self):
        Pind = sp.arange(0,self._Np)
        self.set_pore_info(label='all',locations=sp.ones_like(Pind))
        self._logger.info('Writing pore data')
        self.set_pore_data(prop='coords',data=self._dictionary['pcoords'])

    def _add_throats(self):
        Tind = sp.arange(0,self._Nt)
        self.set_throat_info(label='all',locations=sp.ones_like(Tind))
        self._logger.info('Writing throat data')
        self.set_throat_data(prop='connections',data=self._dictionary['tconnections'])

    def _add_geometry(self):

        geom = OpenPNM.Geometry.GenericGeometry(network=self,name='imported')

        data = self._dictionary['pvolume']
        geom.add_method(prop='pore_volume',model='constant',value=data)
        data = self._dictionary['pdiameter']
        geom.add_method(prop='pore_diameter',model='constant',value=data)

        data = self._dictionary['tdiameter']
        geom.add_method(prop='throat_diameter',model='constant',value=data)

    def _add_xtra_pore_data(self):
        xpdata = self._xtra_pore_data
        if xpdata is not None:
            if type(xpdata) is type([]):
                for pdata in xpdata:
                    try:
                        self.set_pore_data(prop=pdata,data=self._dictionary['p'+pdata])
                    except:
                        self._logger.warning('Could not add pore data: '+pdata+' to network')
            else:
                try:
                    self.set_pore_data(prop=xpdata,data=self._dictionary['p'+xpdata])
                except:
                    self._logger.warning('Could not add pore data: '+xpdata+' to network')

    def _add_xtra_throat_data(self):
        xtdata = self._xtra_throat_data
        if xtdata is not None:
            if type(xtdata) is type([]):
                for tdata in xtdata:
                    try:
                        self.set_pore_data(prop=tdata,data=self._dictionary['t'+tdata])
                    except:
                        self._logger.warning('Could not add throat data: '+tdata+' to network')
            else:
                try:
                    self.set_pore_data(prop=xtdata,data=self._dictionary['t'+xtdata])
                except:
                    self._logger.warning('Could not add throat data: '+xtdata+' to network')


from flask import render_template
from app import app

@app.route('/')
@app.route('/index')
def index():
	user = { 'nickname' : 'Tim' } #replace this with db users
	return render_template("index.html",
			title = 'SpotterCam',
			user = user)


#!/usr/bin/env python3
from __future__ import print_function

import rospy
import cv2
from time import sleep
from std_msgs.msg import String
from sensor_msgs.msg import Image
from cv_bridge import CvBridge, CvBridgeError
from nav_msgs.msg import Odometry
#from tf.transformations import euler_from_quaternion
from geometry_msgs.msg import Twist
import math
from FSX_s import FSX
#from simple_pid import PID
#from parse import citireTXT
roll = pitch = yaw = 0.0
directie=[1,0,1,1,1,1,1,1,1,0]
nr= [1,2,3,4,5,2,4,5,4,0]
def miscareTask2(directie,nr):
  if directie==1:
    self.command.linear.x=0.1*nr
    self.command.angular.z=0.4   #intoarcere mid intoarcere
    self.pub.publish(self.command)
  elif directie==0:
    self.command.linear.x=0.1*nr
    self.command.angular.z=-0.4   #intoarcere mid intoarcere
    self.pub.publish(self.command)
class image_converter:

  def __init__(self):
    #self.image_pub = rospy.Publisher("image_topic_2",Image)

    self.bridge = CvBridge()
    self.image_sub = rospy.Subscriber("/front/image_raw",Image,self.callback)
    #self.odom_sub=rospy.Subscriber("/odometry/filtered",Odometry,self.get_rotation)
    self.pub = rospy.Publisher('/cmd_vel', Twist, queue_size=10)
    self.command=Twist()
    #self.pid = PID(1.2, 0.2, 0.1)
    #self.pid.sample_time = 0.1
    self.intoarcere=0
    self.decizie=0
    self.decizie1=0
    self.ok=0
    self.contorPentruOK=0
    self.contorGreen=0
    self.okdeintoar=0
    self.contorLane=0
  def callback(self,data):

    try:
      intoar=0
      time=rospy.Time()
      cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8") #frameul
      fs=FSX(cv_image,50)
      fs.PrepairFSV()
      frame,angle,accel,intoar,mid=fs.ClassifyFSV()
      target_angle=angle-90

      #print(theta,target_angle* math.pi/180 ,yaw )
      target_rad =target_angle * math.pi/180 #targhet angle il scoti tu

      if  (intoar or mid):# ori intoarcere ori mid ca plm te poti astepta la orice fel de noise
        if self.ok!=2 and intoar==1 :
          self.ok=1

          ###intoarcere
        #cv2.putText(frame,"Intoarcere",(320,240),cv2.FONT_HERSHEY_SIMPLEX, 0.8,(0,0,0),2,cv2.LINE_AA)

       # self.decizie=self.decizie+1
        #if self.decizie%2==1:

         # self.intoarcere=0
          #self.ref_yaw=yaw*180/math.pi
          #print(abs(self.ref_yaw-yaw))

        #if intoar:
          #self.command.linear.x=0.1
          #self.command.angular.z=0.4
          #self.pub.publish(self.command)

        #sleep(15)

        if(self.ok==1 and self.okdeintoar==1):################# GOING FORWARD A BIT ONLY ONCE ######################################
          cv2.putText(frame,"forward I+c:"+str(self.contorPentruOK),(320,240),cv2.FONT_HERSHEY_SIMPLEX, 0.8,(0,0,0),2,cv2.LINE_AA)
          self.contorPentruOK=self.contorPentruOK+1
          if self.contorPentruOK>6:
            if self.okdeintoar==1:
              self.decizie=directie[self.contorLane]
              self.nr=nr[self.contorLane]
              self.contorLane=self.contorLane+1

              self.okdeintoar=0#timpul de mers in fata 0.1ms~10fps
            self.contorGreen=0
            self.ok=2
            #self.okdeintoar=0
            if directie[self.contorLane]==1:
              self.command.linear.x=0.1*nr[self.contorLane]
              self.command.angular.z=0.4   #intoarcere mid intoarcere
              self.pub.publish(self.command)
            elif directie[self.contorLane]==0:
              self.command.linear.x=0.1*nr[self.contorLane]
              self.command.angular.z=-0.4   #intoarcere mid intoarcere
              self.pub.publish(self.command)
            #cv2.putText(frame,"ROtate1",(320,240),cv2.FONT_HERSHEY_SIMPLEX, 0.8,(0,0,0),2,cv2.LINE_AA)
          else:
            self.command.linear.x=1.1      #intoar prima data sa mearga in fata primele 5 iteratii
            self.command.angular.z=0
            self.pub.publish(self.command)
        elif mid and self.okdeintoar==1 and self.ok==2: #################### MID INTOARCERE CAND VEDE si frunze da il doare in pula
            #selfself..ok=2
          cv2.putText(frame,"mid",(320,240),cv2.FONT_HERSHEY_SIMPLEX, 0.8,(0,0,0),2,cv2.LINE_AA)
          if directie[self.contorLane]==1:
            self.command.linear.x=0.1*nr[self.contorLane]
            self.command.angular.z=0.4   #intoarcere mid intoarcere
            self.pub.publish(self.command)
          elif directie[self.contorLane]==0:
            self.command.linear.x=0.1*nr[self.contorLane]
            self.command.angular.z=-0.4   #intoarcere mid intoarcere
            self.pub.publish(self.command)
          else:
            if directie[self.contorLane]==1:
              self.command.linear.x=0.1*nr[self.contorLane]
              self.command.angular.z=0.4   #intoarcere mid intoarcere
              self.pub.publish(self.command)
            elif directie[self.contorLane]==0:

              self.command.linear.x=0.1*nr[self.contorLane]
              self.command.angular.z=-0.4   #intoarcere mid intoarcere
              self.pub.publish(self.command)
              #self.ok=1
              #self.contorGreen=0
            #if self.decizie==1:
        else:
          if directie[self.contorLane]==1:
            self.command.linear.x=0.1
            self.command.angular.z=0.4   #intoarcere mid intoarcere
            self.pub.publish(self.command)
          elif directie[self.contorLane]==0:
            self.command.linear.x=0.1
            self.command.angular.z=-0.4   #intoarcere mid intoarcere
            self.pub.publish(self.command)

      else:
        if self.ok==2: ############### PRE-LANE (pozitionare ######################
          cv2.putText(frame,"Prelane",(320,240),cv2.FONT_HERSHEY_SIMPLEX, 0.8,(0,0,0),2,cv2.LINE_AA)
          if (fs.StangaLim>fs.width/2-30 or fs.StangaLim1> fs.width/2-30 or fs.DreaptaLim<fs.width/2+30 or fs.DreaptaLim1<fs.width/2+30) and directie[self.contorLane]==1:
            self.okdeintoar=0
            #self.decizie=1
            self.command.linear.x=0.1 #si daca se fute intoarcerea , o redresam oleaca
            self.command.angular.z = 0.4
            self.pub.publish(self.command)
          elif(fs.StangaLim>fs.width/2-30 or fs.StangaLim1> fs.width/2-30 or fs.DreaptaLim<fs.width/2+30 or fs.DreaptaLim1<fs.width/2+30) and directie[self.contorLane]==0:
            #self.decizie=0
            self.command.linear.x=0.1 #si daca se fute intoarcerea , o redresam oleaca
            self.command.angular.z = -0.4
            self.pub.publish(self.command)
          else:
            self.ok=0
            #self.contorPentruOK=0

        #self.ok=0
        else:
          cv2.putText(frame,"LANE+ C:"+str(self.contorGreen),(320,240),cv2.FONT_HERSHEY_SIMPLEX, 0.8,(0,0,0),2,cv2.LINE_AA)
          self.contorPentruOK=0         ################ LANE #######################
          self.command.angular.z = 1*(target_rad-yaw) #unghiul la care sa se roteasa
          self.command.linear.x=10 #viteza de mers in fata
          self.pub.publish(self.command)
          self.contorGreen=self.contorGreen+1
          if self.contorGreen<30:
            self.okdeintoar=0
          if self.contorGreen>30:
            self.okdeintoar=1

            #contorPentruOK=0

          else:
            self.okdeintoar=0

          #if self.contorGreen>50:

      #print(self.command)
      print(self.decizie)
    except CvBridgeError as e:
      print(e)

    #cv2.imshow("Image window", frame)
    #key=cv2.waitKey(3)
    #if key:def get_rotation (self,msg):
    #glob
      #exit(0)
  #def get_rotation (self,msg):
  #  global roll, pitch, yaw
  #  q = msg.pose.pose.orientation
    #orientation_list = [orientation_q.x, orientation_q.y, orientation_q.z, orientation_q.w]
  #  yaw = math.atan2(2.0*(q.y*q.z + q.w*q.x),+1.0 - 2.0*(q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z))
    #print(yaw*180/math.pi)
    #print yaw
  #def Command(self):

def main():
  rospy.init_node('image_converter', anonymous=True)

  ic = image_converter()

  try:
    rospy.spin()
  except KeyboardInterrupt:
    print("Shutting down")
  cv2.destroyAllWindows()

if __name__ == '__main__':
    main()


import argparse

import pandas as pd
from matplotlib.cbook import boxplot_stats

from read_data.read_csv_sector import read_csv_sector
from sector.incident import write_stats_file
from settings_data import site_sectors, AVAILABLE_SITES, DEFAULT_START_DATE, DEFAULT_END_DATE, \
    DEFAULT_START_TIME, DEFAULT_END_TIME
from utils.logging_utils import logging_reconfig

logging_reconfig()

DEFAULT_STATS_COUNTERS = [
    "pmRrcConnEstabSucc",
    "pmRrcConnEstabAtt",
    "pmRrcConnEstabAttReatt",
    "pmPdcpVolDlDrb",
    "pmPdcpVolDlDrbLastTTI",
    "pmPdcpVolDlDrbTransUm",
    "pmUeThpTimeDl",
    "pmErabRelAbnormalEnbAct",
    "pmErabRelMmeAct",
    "pmErabRelAbnormalEnb",
    "pmErabRelNormalEnb",
    "pmErabRelMme",
    "pmS1SigConnEstabSucc",
    "pmS1SigConnEstabAtt",
    "pmErabEstabSuccInit",
    "pmErabEstabAttInit",
]

def parse_arguments():
    parser = argparse.ArgumentParser()
    parser.add_argument("sites", nargs="*", choices=AVAILABLE_SITES, help="A list of specific sites")
    parser.add_argument("-w", "--whis", type=float, default=2., help="reach of the whiskers")
    parser.add_argument("-c", "--counters", nargs="*", default=DEFAULT_STATS_COUNTERS,
                        help="A list of specific counters to process")
    args = parser.parse_args()
    return args.sites, args.whis, args.counters

def get_hourly_stats(series, whis):
    def series_filter(s, day_type):
        rng = [0, 1, 2, 3, 4] if day_type == "workday" else [5, 6]
        return s[s.index.weekday.isin(rng)]

    def get_stats(values, whis):
        r = boxplot_stats(values, whis=whis)[0]
        r.pop("fliers", [])
        return pd.Series(r).to_dict()

    ret = {}
    for day_typ in ("workday", "weekend"):
        filtered = series_filter(series, day_typ)
        ret[day_typ] = {int(hour): get_stats(group.values, whis)
                        for hour, group in filtered.groupby(filtered.index.hour)}
    return ret

def main():
    sites_names, whis, counters = parse_arguments()

    def get_data(sector_name):
        data = read_csv_sector(sector_name)
        return data.loc[DEFAULT_START_DATE:DEFAULT_END_DATE].between_time(DEFAULT_START_TIME, DEFAULT_END_TIME)

    def get_sector_stats(sector_name):
        data = get_data(sector_name)
        return {counter: get_hourly_stats(data[counter], whis) for counter in counters}

    stats = {site_name: {sector_name: get_sector_stats(sector_name) for sector_name in site_sectors[site_name]}
             for site_name in sites_names}

    write_stats_file(stats)

if __name__ == "__main__":
    main()


from django.urls import path
from lacar.views import Index, CourseDetail, LessonDetail

app_name = 'lacar'
urlpatterns = [
    path('', Index.as_view(), name='index'),
    path('<int:pk>', CourseDetail.as_view(), name='curso'),
    path('lesson/<int:pk>', LessonDetail.as_view(), name='lesson')
]


import os
import sys
import argparse
sys.path.append(os.getcwd())
from nas_lib.visualize.visualize_close_domain_reverse import draw_plot_nasbench_101, draw_plot_nasbench_201, \
    draw_plot_priori_scalar, draw_plot_evaluation_compare

model_lists_nasbench = ['Random', 'EA', 'BANANAS', 'BANANAS_F', 'NPENAS-BO', 'NPENAS-NP']
model_masks_nasbench = [True, True, True, True, True, True]

model_lists_scalar = ['scalar_10', 'scalar_30', 'scalar_50', 'scalar_70', 'scalar_100']

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Args for visualize darts architecture')
    parser.add_argument('--search_space', type=str, default='evaluation_compare',
                        choices=['nasbench_101', 'nasbench_201', 'scalar_prior', 'evaluation_compare'],
                        help='The algorithm output folder')
    parser.add_argument('--save_dir', type=str,
                        # default='/home/albert_wei/Disk_A/train_npenas_experiment_results/close_domain_npenas_case1_2020_6_training/',
                        help='The algorithm output folder')
    parser.add_argument('--draw_type', type=str, default='ERRORBAR', choices=['ERRORBAR', 'MEANERROR'],
                        help='Draw result with or without errorbar.')
    parser.add_argument('--show_all', type=str, default='1', help='Weather to show all results.')
    args = parser.parse_args()
    if args.search_space == 'nasbench_101':
        draw_plot_nasbench_101(args.save_dir, draw_type=args.draw_type, model_lists=model_lists_nasbench,
                               model_masks=model_masks_nasbench)
    elif args.search_space == 'nasbench_201':
        draw_plot_nasbench_201(args.save_dir, draw_type=args.draw_type, model_lists=model_lists_nasbench,
                               model_masks=model_masks_nasbench)
    elif args.search_space == 'scalar_prior':
        if args.show_all == '1':
            model_lists_scalar_mask = [True, True, True, True, True]
        else:
            model_lists_scalar_mask = [False, True, False, True, False]
        draw_plot_priori_scalar(args.save_dir, draw_type=args.draw_type, model_lists=model_lists_scalar,
                                model_masks=model_lists_scalar_mask)
    elif args.search_space == 'evaluation_compare':
        model_lists = ['1', '10', '20', '30']
        if args.show_all == '1':
            model_masks = [True, True, True, True]
            draw_plot_evaluation_compare(args.save_dir, draw_type=args.draw_type, model_lists=model_lists,
                                         model_masks=model_masks)
        else:
            model_masks = [True, False, False, True]
            draw_plot_evaluation_compare(args.save_dir, draw_type=args.draw_type, model_lists=model_lists,
                                         model_masks=model_masks)
    else:
        raise ValueError('This search space does not support!')


import json, time
from datetime import datetime
from flask import jsonify, make_response, escape, Blueprint, request, session, current_app as app
from sqlalchemy import text, desc
from main.extensions import *
from main.model import *

cafeteria_api = Blueprint('cafeteria', __name__, url_prefix='/cafeteria')

@cafeteria_api.route('/read', methods=['GET'])
@login_required
def get_read_cafeMenu():
    version = request.args.get('version')
    school_id = session['school_id']
    cafe = CafeteriaInfo.query.filter_by(schoolID=school_id, version=version).first()
    if cafe:
        if str(cafe.version).split(' ')[0] == version:
            return response_with_code('<fail>:2:no need to re-download it', {'curMonth':[], 'nextMonth':[], 'version':version})
    result = CafeteriaInfo.query.filter_by(schoolID=school_id).first()
    dict_row = convert_to_dict(result)
    dict_row.pop('schoolID')
    dict_row.pop('regionID')
    dict_row['curMonth'] = json.loads(dict_row.pop('curCafeMenu'))
    dict_row['nextMonth'] = json.loads(dict_row.pop('nextCafeMenu'))
    dict_row['version'] = str(dict_row['version']).split(' ')[0]
    # print(dict_row['nextMonth'])
    return response_with_code('<success>', dict_row)


import logging
import os
import re

from urlparse import urlsplit, urlunparse

from rbtools.clients import SCMClient, RepositoryInfo
from rbtools.clients.svn import SVNClient
from rbtools.utils.checks import check_install
from rbtools.utils.process import execute

class MercurialClient(SCMClient):
    """
    A wrapper around the hg Mercurial tool that fetches repository
    information and generates compatible diffs.
    """
    name = 'Mercurial'

    def __init__(self, **kwargs):
        super(MercurialClient, self).__init__(**kwargs)

        self.hgrc = {}
        self._type = 'hg'
        self._hg_root = ''
        self._remote_path = ()
        self._hg_env = {
            'HGRCPATH': os.devnull,
            'HGPLAIN': '1',
        }

        # `self._remote_path_candidates` is an ordered set of hgrc
        # paths that are checked if `parent_branch` option is not given
        # explicitly.  The first candidate found to exist will be used,
        # falling back to `default` (the last member.)
        self._remote_path_candidates = ['reviewboard', 'origin', 'parent',
                                        'default']

    def get_repository_info(self):
        if not check_install('hg --help'):
            return None

        self._load_hgrc()

        if not self.hg_root:
            # hg aborted => no mercurial repository here.
            return None

        svn_info = execute(["hg", "svn", "info"], ignore_errors=True)

        if (not svn_info.startswith('abort:') and
            not svn_info.startswith("hg: unknown command") and
            not svn_info.lower().startswith('not a child of')):
            return self._calculate_hgsubversion_repository_info(svn_info)

        self._type = 'hg'

        path = self.hg_root
        base_path = '/'

        if self.hgrc:
            self._calculate_remote_path()

            if self._remote_path:
                path = self._remote_path[1]
                base_path = ''

        return RepositoryInfo(path=path, base_path=base_path,
                              supports_parent_diffs=True)

    def _calculate_remote_path(self):
        for candidate in self._remote_path_candidates:

            rc_key = 'paths.%s' % candidate

            if (not self._remote_path and self.hgrc.get(rc_key)):
                self._remote_path = (candidate, self.hgrc.get(rc_key))
                logging.debug('Using candidate path %r: %r' %
                              self._remote_path)

                return

    def _calculate_hgsubversion_repository_info(self, svn_info):
        self._type = 'svn'
        def _info(r):
            m = re.search(r, svn_info, re.M)
            return urlsplit(m.group(1)) if m else None

        root = _info(r'^Repository Root: (.+)$')
        url = _info(r'^URL: (.+)$')

        if not (root and url): return None
        scheme, netloc, path, _, _ = root
        root = urlunparse([scheme, root.netloc.split("@")[-1], path,
                           "", "", ""])
        base_path = url.path[len(path):]

        return RepositoryInfo(path=root, base_path=base_path,
                              supports_parent_diffs=True)

    @property
    def hg_root(self):
        if not self._hg_root:
            root = execute(['hg', 'root'], env=self._hg_env,
                           ignore_errors=True)

            if not root.startswith('abort:'):
                self._hg_root = root.strip()
            else:
                return None

        return self._hg_root

    def _load_hgrc(self):
        for line in execute(['hg', 'showconfig'], split_lines=True):
            key, value = line.split('=', 1)
            self.hgrc[key] = value.strip()

    def extract_summary(self, revision):
        """
        Extracts the first line from the description of the given changeset.
        """
        return execute(['hg', 'log', '-r%s' % revision, '--template',
                        r'{desc|firstline}'], env=self._hg_env)

    def extract_description(self, rev1, rev2):
        """
        Extracts all descriptions in the given revision range and concatenates
        them, most recent ones going first.
        """
        numrevs = len(execute([
            'hg', 'log', '-r%s:%s' % (rev2, rev1),
            '--follow', '--template', r'{rev}\n'], env=self._hg_env
        ).strip().split('\n'))

        return execute(['hg', 'log', '-r%s:%s' % (rev2, rev1),
                        '--follow', '--template',
                        r'{desc}\n\n', '--limit',
                        str(numrevs - 1)], env=self._hg_env).strip()

    def diff(self, files):
        """
        Performs a diff across all modified files in a Mercurial repository.
        """
        files = files or []

        if self._type == 'svn':
            return self._get_hgsubversion_diff(files)
        else:
            return self._get_outgoing_diff(files)

    def _get_hgsubversion_diff(self, files):
        parent = execute(['hg', 'parent', '--svn', '--template',
                          '{node}\n']).strip()

        if self.options.parent_branch:
            parent = self.options.parent_branch

        if self.options.guess_summary and not self.options.summary:
            self.options.summary = self.extract_summary(".")

        if self.options.guess_description and not self.options.description:
            self.options.description = self.extract_description(parent, ".")

        rs = "-r{0}:{1}".format(parent, files[0] if len(files) == 1 else '.')

        return (execute(["hg", "diff", "--svn", rs]), None)

    def _get_outgoing_diff(self, files):
        """
        When working with a clone of a Mercurial remote, we need to find
        out what the outgoing revisions are for a given branch.  It would
        be nice if we could just do `hg outgoing --patch <remote>`, but
        there are a couple of problems with this.

        For one, the server-side diff parser isn't yet equipped to filter out
        diff headers such as "comparing with..." and "changeset: <rev>:<hash>".
        Another problem is that the output of `outgoing` potentially includes
        changesets across multiple branches.

        In order to provide the most accurate comparison between one's local
        clone and a given remote -- something akin to git's diff command syntax
        `git diff <treeish>..<treeish>` -- we have to do the following:

            - get the name of the current branch
            - get a list of outgoing changesets, specifying a custom format
            - filter outgoing changesets by the current branch name
            - get the "top" and "bottom" outgoing changesets
            - use these changesets as arguments to `hg diff -r <rev> -r <rev>`

        Future modifications may need to be made to account for odd cases like
        having multiple diverged branches which share partial history -- or we
        can just punish developers for doing such nonsense :)
        """
        files = files or []

        remote = self._remote_path[0]

        if not remote and self.options.parent_branch:
            remote = self.options.parent_branch

        current_branch = execute(['hg', 'branch'], env=self._hg_env).strip()

        outgoing_changesets = \
            self._get_outgoing_changesets(current_branch, remote)

        if outgoing_changesets:
            top_rev, bottom_rev = \
                self._get_top_and_bottom_outgoing_revs(outgoing_changesets)
        else:
            top_rev = None
            bottom_rev = None

        if self.options.guess_summary and not self.options.summary:
            self.options.summary = self.extract_summary(top_rev)

        if self.options.guess_description and not self.options.description:
            self.options.description = self.extract_description(bottom_rev,
                                                                 top_rev)

        if bottom_rev is not None and top_rev is not None:
            full_command = ['hg', 'diff', '-r', str(bottom_rev), '-r',
                            str(top_rev)] + files

            return (execute(full_command, env=self._hg_env), None)
        else:
            return ("", None)

    def _get_outgoing_changesets(self, current_branch, remote):
        """
        Given the current branch name and a remote path, return a list
        of outgoing changeset numbers.
        """

        # We must handle the special case where there are no outgoing commits
        # as mercurial has a non-zero return value in this case.
        outgoing_changesets = []
        raw_outgoing = execute(['hg', '-q', 'outgoing', '--template',
                                'b:{branches}\nr:{rev}\n\n', remote],
                               env=self._hg_env,
                               extra_ignore_errors=(1,))

        for pair in raw_outgoing.split('\n\n'):
            if not pair.strip():
                continue

            # Ignore warning messages that hg might put in, such as
            # "warning: certificate for foo can't be verified (Python too old)"
            branch, rev = [l for l in pair.strip().split('\n')
                           if not l.startswith('warning: ')]

            branch_name = branch[len('b:'):].strip()
            branch_name = branch_name or 'default'
            revno = rev[len('r:'):]

            if branch_name == current_branch and revno.isdigit():
                logging.debug('Found outgoing changeset %s for branch %r'
                              % (revno, branch_name))
                outgoing_changesets.append(int(revno))

        return outgoing_changesets

    def _get_top_and_bottom_outgoing_revs(self, outgoing_changesets):
        # This is a classmethod rather than a func mostly just to keep the
        # module namespace clean.  Pylint told me to do it.
        top_rev = max(outgoing_changesets)
        bottom_rev = min(outgoing_changesets)

        for rev in reversed(outgoing_changesets):
            parents = execute(["hg", "log", "-r", str(rev),
                               "--template", "{parents}"],
                               env=self._hg_env)
            parents = re.split(':[^\s]+\s*', parents)
            parents = [int(p) for p in parents if p != '']

            parents = [p for p in parents if p not in outgoing_changesets]

            if len(parents) > 0:
                bottom_rev = parents[0]
                break
            else:
                bottom_rev = rev - 1

        bottom_rev = max(0, bottom_rev)

        return top_rev, bottom_rev

    def diff_between_revisions(self, revision_range, args, repository_info):
        """
        Performs a diff between 2 revisions of a Mercurial repository.
        """
        if self._type != 'hg':
            raise NotImplementedError

        if ':' in revision_range:
            r1, r2 = revision_range.split(':')
        else:
            # If only 1 revision is given, we find the first parent and use
            # that as the second revision.
            #
            # We could also use "hg diff -c r1", but then we couldn't reuse the
            # code for extracting descriptions.
            r2 = revision_range
            r1 = execute(["hg", "parents", "-r", r2,
                          "--template", "{rev}\n"]).split()[0]

        if self.options.guess_summary and not self.options.summary:
            self.options.summary = self.extract_summary(r2)

        if self.options.guess_description and not self.options.description:
            self.options.description = self.extract_description(r1, r2)

        return (execute(["hg", "diff", "-r", r1, "-r", r2],
                        env=self._hg_env), None)

    def scan_for_server(self, repository_info):
        # Scan first for dot files, since it's faster and will cover the
        # user's $HOME/.reviewboardrc
        server_url = \
            super(MercurialClient, self).scan_for_server(repository_info)

        if not server_url and self.hgrc.get('reviewboard.url'):
            server_url = self.hgrc.get('reviewboard.url').strip()

        if not server_url and self._type == "svn":
            # Try using the reviewboard:url property on the SVN repo, if it
            # exists.
            prop = SVNClient().scan_for_server_property(repository_info)

            if prop:
                return prop

        return server_url


# uncompyle6 version 3.7.4
# Python bytecode 3.6 (3379)
# Decompiled from: Python 3.6.9 (default, Apr 18 2020, 01:56:04)
# [GCC 8.4.0]
# Embedded file name: /Users/amarin/dev/sphinx-mediatel/src/sphinx_paw/rewritable.py
# Compiled at: 2019-11-19 17:00:50
# Size of source mod 2**32: 1413 bytes
"""Allow default templates and configuration files redefinition locally"""
from sphinx.util import logging
from os import path
from sphinx.application import Sphinx
from sphinx.util import console
from sphinx_paw.constants import NOTSET
DEFAULT_PATH = path.join(path.dirname(__file__), 'defaults')
logger = logging.getLogger(__name__)

def rewritable_file_path(app, filename, local_path=NOTSET, default_path=NOTSET):
    """Get filepath in documentation src or default in sphinx_paw"""
    if not isinstance(app, Sphinx):
        raise AssertionError
    else:
        src_dir = app.srcdir
        if local_path:
            found_path = path.join(src_dir, local_path, filename)
        else:
            found_path = path.join(src_dir, filename)
    if path.exists(found_path):
        logger.info(f"Using local {console.bold(filename)}")
        return found_path
    else:
        if default_path is NOTSET:
            default_path = DEFAULT_PATH
        else:
            if default_path is None:
                raise FileNotFoundError(f"Local file {found_path} not found")
        logger.info(f"Using {console.bold('default')} {filename}")
        return path.join(default_path, filename)

def rewritable_file_content(app, filename):
    """Get rewritable file content"""
    assert isinstance(app, Sphinx)
    file_path = rewritable_file_path(app, filename, DEFAULT_PATH)
    with open(file_path, 'rb') as (content_fh):
        content = content_fh.read().decode()
        return content