import json
from dataclasses import dataclass, field
from typing import Union

import requests

@dataclass
class ManyChatAPI:
    api_base_url = 'https://api.manychat.com/fb/'
    api_key: str
    psid: str
    headers: dict = field(init=False)

    def __post_init__(self):
        self.headers = {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
            'Authorization': f'Bearer {self.api_key}',
        }

    def get_user_info(self) -> dict:
        params = {
            'subscriber_id': self.psid,
        }

        try:
            response = requests.get(
                url=f'{self.api_base_url}subscriber/getInfo',
                headers=self.headers,
                params=params,
                timeout=5,
            )
        except Exception as e:
            results = {
                'status': 'error',
                'message': e,
            }
        else:
            results = json.loads(response.text)

        return results

    def send_content(self, messages: list) -> dict:
        params = {
            'subscriber_id': self.psid,
            'data': {
                'version': 'v2',
                'content': {
                    'messages': [
                        {
                            'type': 'text',
                            'text': message,
                        } for message in messages
                    ]
                }
            },
        }

        try:
            response = requests.post(
                url=f'{self.api_base_url}sending/sendContent',
                headers=self.headers,
                data=json.dumps(params),
                timeout=5,
            )
        except Exception as e:
            results = {
                'status': 'error',
                'message': e,
            }
        else:
            results = json.loads(response.text)

        return results

    def send_flow(self, flow_ns: str) -> dict:
        params = {
            'subscriber_id': self.psid,
            'flow_ns': flow_ns,
        }

        try:
            response = requests.post(
                url=f'{self.api_base_url}sending/sendFlow',
                headers=self.headers,
                data=json.dumps(params),
                timeout=5,
            )
        except Exception as e:
            results = {
                'status': 'error',
                'message': e,
            }
        else:
            results = json.loads(response.text)

        return results

    def set_custom_field_by_name(self,
                                 field_name: str,
                                 field_value: Union[str, int, bool]) -> dict:
        params = {
            'subscriber_id': self.psid,
            'field_name': field_name,
            'field_value': field_value,
        }

        try:
            response = requests.post(
                url=f'{self.api_base_url}subscriber/setCustomFieldByName',
                headers=self.headers,
                data=json.dumps(params),
                timeout=5,
            )
        except Exception as e:
            results = {
                'status': 'error',
                'message': e,
            }
        else:
            results = json.loads(response.text)

        return results


# import statements

import nltk
import sys
import pandas as pd
import re
from nltk import pos_tag
from nltk.corpus import stopwords
from nltk.stem.porter import PorterStemmer
from nltk.stem.wordnet import WordNetLemmatizer
from nltk.tokenize import word_tokenize, sent_tokenize
from sqlalchemy import create_engine

# download necessary NLTK data
nltk.download(['punkt', 'wordnet'])
nltk.download('stopwords')

def load_data(messages_filepath, categories_filepath):
  """
  Load the data containing the messages and the
  categories, and merge on the common column 'id'
  Returns a single pandas Dataframe.

  Keyword arguments:
  messages_filepath -- filepath (including file name)
                       of the file containing the messages
  categories_filepath -- filepath (including file name)
                         of the file containing the message
                         categories
  """
  messages = pd.read_csv(messages_filepath, encoding='UTF-8')
  categories = pd.read_csv(categories_filepath, encoding='UTF-8')
  return messages.merge(categories, on=['id'])

def clean_data(df):
  """
  Parse the single 'categories' column into the 36 distinct
  message category columns, name the resulting columns, and
  clean the values, removing the category name from the cells
  and leaving only the numeric categorical value.

  Remove true duplicate rows.

  Returns a cleaned Dataframe.

  Keyword argument:
  df -- Dataframe requiring cleaning.
  """
  categories_new = df['categories'].str.split(pat=';', expand=True)
  row = categories_new.iloc[0,:]
  category_colnames = list(row.apply(lambda x: x[:-2]))
  categories_new.columns = category_colnames
  for column in categories_new:
    # set each value to be the last character of the string
    categories_new[column] = categories_new[column].str.slice(-1)

    # convert column from string to numeric
    categories_new[column] = categories_new[column].astype(int)

  df.drop(columns=['categories'], inplace=True)

  df = pd.concat([df, categories_new], axis=1)

  # drop duplicates
  df.drop_duplicates(inplace=True)
  return df

def save_data(df, database_filename):
  """
  Save cleaned Dataframe to a SQL Database table.

  Keyword arguments:
  df -- Cleaned Dataframe for export
  database_filename -- name of the database in which
                       table will be saved
  """
  engine = create_engine('sqlite:///' + database_filename)
  df.to_sql('messages_and_categories', engine, index=False)

def main():
  """
  Executes following functions:

  1) load_data(messages_filepath, categories_filepath)
  2) clean_data(df)
  3) save_data(df, database_filename)
  """
  if len(sys.argv) == 4:

      messages_filepath, categories_filepath, database_filepath = sys.argv[1:]

      print('Loading data...\n    MESSAGES: {}\n    CATEGORIES: {}'
            .format(messages_filepath, categories_filepath))
      df = load_data(messages_filepath, categories_filepath)

      print('Cleaning data...')
      df = clean_data(df)

      print('Saving data...\n    DATABASE: {}'.format(database_filepath))
      save_data(df, database_filepath)

      print('Cleaned data saved to database!')

  else:
      print('Please provide the filepaths of the messages and categories '\
            'datasets as the first and second argument respectively, as '\
            'well as the filepath of the database to save the cleaned data '\
            'to as the third argument. \n\nExample: python process_data.py '\
            'disaster_messages.csv disaster_categories.csv '\
            'DisasterResponse.db')

if __name__ == '__main__':
    main()


import torch
from torch import Tensor, nn
import torchvision
import os
import numpy as np

class Normalize:
    def __init__(self, n_channels, expected_values, variance):
        self.n_channels = n_channels
        self.expected_values = expected_values
        self.variance = variance
        assert self.n_channels == len(self.expected_values)

    def __call__(self, x):
        x_clone = x.clone()
        for channel in range(self.n_channels):
            x_clone[:, channel] = (x[:, channel] - self.expected_values[channel]) / self.variance[channel]
        return x_clone

class Denormalize:
    def __init__(self, n_channels, expected_values, variance):
        self.n_channels = n_channels
        self.expected_values = expected_values
        self.variance = variance
        assert self.n_channels == len(self.expected_values)

    def __call__(self, x):
        x_clone = x.clone()
        for channel in range(self.n_channels):
            x_clone[:, channel] = x[:, channel] * self.variance[channel] + self.expected_values[channel]
        return x_clone

class RegressionModel(nn.Module):
    def __init__(self, task, model, init_mask, init_pattern):
        self._EPSILON = 1e-7
        super(RegressionModel, self).__init__()
        self.mask_tanh = nn.Parameter(torch.tensor(init_mask))
        self.pattern_tanh = nn.Parameter(torch.tensor(init_pattern))

        self.classifier = self._get_classifier(model)
        self.normalizer = self._get_normalize(task)
        self.denormalizer = self._get_denormalize(task)

    def forward(self, x):
        mask = self.get_raw_mask()
        pattern = self.get_raw_pattern()
        if self.normalizer:
            pattern = self.normalizer(self.get_raw_pattern())
        x = (1 - mask) * x + mask * pattern
        return self.classifier(x)

    def get_raw_mask(self):
        mask = nn.Tanh()(self.mask_tanh)
        return mask / (2 + self._EPSILON) + 0.5

    def get_raw_pattern(self):
        pattern = nn.Tanh()(self.pattern_tanh)
        return pattern / (2 + self._EPSILON) + 0.5

    def _get_classifier(self, model):
        classifier = model
        for param in classifier.parameters():
            param.requires_grad = False
        classifier.eval()
        return classifier.to('cuda')

    def _get_denormalize(self, task):
        if task == 'cifar10':
            denormalizer = Denormalize(3, [0.4914, 0.4822, 0.4465], [0.247, 0.243, 0.261])
        elif task == 'mnist':
            denormalizer = Denormalize(1, [0.5], [0.5])
        elif task == 'imageNet':
            denormalizer = Denormalize(3,[0.485,0.456,0.406],[0.229,0.224,0.225])
        elif task == 'gtsrb':
            denormalizer = None
        else:
            raise Exception("Invalid dataset")
        return denormalizer

    def _get_normalize(self, task):
        if task == 'cifar10':
            normalizer = Normalize(3, [0.4914, 0.4822, 0.4465], [0.247, 0.243, 0.261])
        elif task == 'mnist':
            normalizer = Normalize(1, [0.5], [0.5])
        elif task == 'imageNet':
            normalizer = Denormalize(3,[0.485,0.456,0.406],[0.229,0.224,0.225])
        elif task == 'gtsrb':
            normalizer = None
        else:
            raise Exception("Invalid dataset")
        return normalizer

class Recorder:
    def __init__(self,target_label,task):
        super().__init__()

        # Best optimization results
        self.mask_best = None
        self.pattern_best = None
        self.reg_best = float('inf')
        self.target_label = target_label

        # Logs and counters for adjusting balance cost
        self.logs = []
        self.cost_set_counter = 0
        self.cost_up_counter = 0
        self.cost_down_counter = 0
        self.cost_up_flag = False
        self.cost_down_flag = False

        # Counter for early stop
        self.early_stop_counter = 0
        self.early_stop_reg_best = self.reg_best

        # Cost
        self.cost = 1e-3
        self.cost_multiplier_up = 2
        self.cost_multiplier_down = 2 ** 1.5

        self.task = task

    def reset_state(self):
        self.cost = 1e-3
        self.cost_up_counter = 0
        self.cost_down_counter = 0
        self.cost_up_flag = False
        self.cost_down_flag = False
        print("Initialize cost to {:f}".format(self.cost))

    def save_result_to_dir(self):
        result_dir = '%s/u_t_%s'%(self.task,self.task)
        if not os.path.exists(result_dir):
            os.makedirs(result_dir)
        result_dir = os.path.join(result_dir, str(self.target_label))
        if not os.path.exists(result_dir):
            os.makedirs(result_dir)

        pattern_best = self.pattern_best
        mask_best = self.mask_best
        trigger = pattern_best * mask_best

        path_mask = os.path.join(result_dir, 'mask.png')
        path_pattern = os.path.join(result_dir, 'pattern.png')
        path_trigger = os.path.join(result_dir, 'trigger.png')

        torchvision.utils.save_image(mask_best, path_mask, normalize=True)
        torchvision.utils.save_image(pattern_best, path_pattern, normalize=True)
        torchvision.utils.save_image(trigger, path_trigger, normalize=True)

class UniversalTrigger:
    def __init__(self):
        self.universal_trigger_dict = {}

def train(task, model, target_label, init_mask, init_pattern, test_loader):
    # Build regression model
    regression_model = RegressionModel(task, model, init_mask, init_pattern).to('cuda')

    # Set optimizer
    optimizerR = torch.optim.Adam(regression_model.parameters(), lr=1e-1, betas=(0.5, 0.9))

    # Set recorder (for recording best result)
    recorder = Recorder(target_label,task)

    for epoch in range(50):
        early_stop = train_step(regression_model, optimizerR, test_loader, recorder, epoch, target_label)
        if early_stop:
            break

    # Save result to dir
    recorder.save_result_to_dir()

    return recorder

def train_step(regression_model, optimizerR, dataloader, recorder, epoch, target_label,early_stop=True):
    print("Epoch {} - Label: {}".format(epoch, target_label))
    # Set losses
    cross_entropy = nn.CrossEntropyLoss()
    total_pred = 0
    true_pred = 0

    # Record loss for all mini-batches
    loss_ce_list = []
    loss_reg_list = []
    loss_list = []
    loss_acc_list = []

    # Set inner early stop flag
    inner_early_stop_flag = False
    for batch_idx, (inputs, labels) in enumerate(dataloader):
        # Forwarding and update model
        optimizerR.zero_grad()

        inputs = inputs.to('cuda')
        sample_num = inputs.shape[0]
        total_pred += sample_num
        target_labels = torch.ones((sample_num), dtype=torch.int64).to('cuda') * target_label
        predictions = regression_model(inputs)

        loss_ce = cross_entropy(predictions, target_labels)
        loss_reg = torch.norm(regression_model.get_raw_mask(), 2)
        total_loss = loss_ce + recorder.cost * loss_reg
        total_loss.backward()
        optimizerR.step()

        # Record minibatch information to list
        minibatch_accuracy = torch.sum(torch.argmax(predictions, dim=1) == target_labels).detach() * 100. / sample_num
        loss_ce_list.append(loss_ce.detach())
        loss_reg_list.append(loss_reg.detach())
        loss_list.append(total_loss.detach())
        loss_acc_list.append(minibatch_accuracy)

        true_pred += torch.sum(torch.argmax(predictions, dim=1) == target_labels).detach()

    loss_ce_list = torch.stack(loss_ce_list)
    loss_reg_list = torch.stack(loss_reg_list)
    loss_list = torch.stack(loss_list)
    loss_acc_list = torch.stack(loss_acc_list)

    avg_loss_ce = torch.mean(loss_ce_list)
    avg_loss_reg = torch.mean(loss_reg_list)
    avg_loss = torch.mean(loss_list)
    avg_loss_acc = torch.mean(loss_acc_list)

    # Check to save best mask or not
    if avg_loss_acc >= 99. and avg_loss_reg < recorder.reg_best:
        recorder.mask_best = regression_model.get_raw_mask().detach()
        recorder.pattern_best = regression_model.get_raw_pattern().detach()
        recorder.reg_best = avg_loss_reg
        recorder.save_result_to_dir()
        print(" Updated !!!")

    # Show information
    print('  Result: Accuracy: {:.3f} | Cross Entropy Loss: {:.6f} | Reg Loss: {:.6f} | Reg best: {:.6f}'.format(
        true_pred * 100. / total_pred,
        avg_loss_ce,
        avg_loss_reg,
        recorder.reg_best))

    # Check early stop
    if early_stop:
        if recorder.reg_best < float('inf'):
            if recorder.reg_best >= 99. * recorder.early_stop_reg_best:
                recorder.early_stop_counter += 1
            else:
                recorder.early_stop_counter = 0

        recorder.early_stop_reg_best = min(recorder.early_stop_reg_best, recorder.reg_best)

        if (
                recorder.cost_down_flag and recorder.cost_up_flag and recorder.early_stop_counter >= 25):
            print('Early_stop !!!')
            inner_early_stop_flag = True

    if not inner_early_stop_flag:
        # Check cost modification
        if recorder.cost == 0 and avg_loss_acc >= 99.:
            recorder.cost_set_counter += 1
            if recorder.cost_set_counter >= 5:
                recorder.reset_state()
        else:
            recorder.cost_set_counter = 0

        if avg_loss_acc >= 99.:
            recorder.cost_up_counter += 1
            recorder.cost_down_counter = 0
        else:
            recorder.cost_up_counter = 0
            recorder.cost_down_counter += 1

        if recorder.cost_up_counter >= 5:
            recorder.cost_up_counter = 0
            print("Up cost from {} to {}".format(recorder.cost, recorder.cost * recorder.cost_multiplier_up))
            recorder.cost *= recorder.cost_multiplier_up
            recorder.cost_up_flag = True

        elif recorder.cost_down_counter >= 5:
            recorder.cost_down_counter = 0
            print("Down cost from {} to {}".format(recorder.cost, recorder.cost / recorder.cost_multiplier_down))
            recorder.cost /= recorder.cost_multiplier_down
            recorder.cost_down_flag = True

        # Save the final version
        if recorder.mask_best is None:
            recorder.mask_best = regression_model.get_raw_mask().detach()
            recorder.pattern_best = regression_model.get_raw_pattern().detach()

    return inner_early_stop_flag


import pandas as pd
import redis
from redisgraph import Graph
from config import redisgraph_config
from pathlib import Path

def redisgraph_import_csv(output: Path) -> None:
    r = redis.Redis(host=redisgraph_config['host'], port=redisgraph_config['port'])
    graph_name = 'movie_graph'
    redis_graph = Graph(graph_name, r)

    import_csv = pd.read_csv(output / 'neo4j_export.csv')
    break_column_name = '_start'

    nodes = pd.DataFrame()
    relations = pd.DataFrame()

    active_df = nodes

    for idx, col in enumerate(import_csv.columns):
        if col == break_column_name:
            active_df = relations
        active_df[col] = import_csv[col]

    nodes.dropna(how='all', subset=None, inplace=True)
    relations.dropna(how='all', subset=None, inplace=True)

    # relations.to_csv('../out/Relations.csv')

    node_values = nodes['_labels'].unique()
    rows_to_drop = [node_value for node_value in node_values if 'UNIQUE IMPORT LABEL' in node_value]
    for row_to_drop in rows_to_drop:
        nodes = nodes[nodes["_labels"].str.contains(row_to_drop) == False]

    node_values = nodes['_labels'].unique()
    for node_type in node_values:
        node_data = nodes[nodes['_labels'] == node_type]
        filename = f'../out/{node_type.replace(":", "")}.csv'
        node_data.dropna(how='all', axis=1, inplace=True)
        # node_data.to_csv(filename)

        for node in node_data.iloc:
            params = ''
            for param in node_data.columns:
                if not param.startswith('_'):
                    val = node[param]
                    if not pd.isna(val):
                        try:
                            val = float(val)
                        except:
                            val = f'"{val}"'
                        params = params + f', {param}: {val}'

            query = f'MERGE ({node["_labels"]} {{id: {node["_id"]} {params} }})'
            redis_graph.query(query)

    for node in relations.iloc:
        query = f"""
        MATCH (a), (b) WHERE a.id = {node["_start"]} AND b.id = {node["_end"]} CREATE (a)-[:{node['_type']}]->(b)
        """
        redis_graph.query(query)


import os
import numpy as np
import scipy.io.wavfile as wavfile
from keras.models import Sequential
from keras.layers import Dense
from keras.utils import normalize
from utils import read_textgrid
from numpy_operation import get_martix
from python_speech_features import mfcc
from python_speech_features import delta
#from python_speech_features import fbank

def to_one_hot(labels, dimension=5):
    results = np.zeros((len(labels),dimension))
    for i, label in enumerate(labels):
        results[i, label] = 1.
    return results

def read_wav(filename):
    rate, data = wavfile.read(filename)
    #only use the 1st channel if stereo
    if len(data.shape) > 1:
        data =  data[:,0]
    data = data.astype(np.float32)
    data = data / 32768 #convert PCM int16 to float
    return data, rate

def feature_extract(filename, wavpath, tgpath):
    wav_filename = os.path.join(wavpath,filename+'.wav')
    print(wav_filename)
    tg_filename = os.path.join(tgpath,filename+'.textgrid')

    y,sr = read_wav(wav_filename)

    mfccs = mfcc(signal=y,samplerate=sr,winlen=0.02,winfunc=np.hamming)
    delta1 = delta(mfccs,1)
    delta2 = delta(mfccs,2)

    _mfccs = np.concatenate((mfccs,delta1,delta2),1)
    _mfccs = normalize(_mfccs)
    _mfccs = get_martix(_mfccs,30,10)

    _labels = None
    if(os.path.exists(tg_filename)):
        _labels = read_textgrid(tg_filename,len(_mfccs))
        _labels = to_one_hot(_labels)
    return _mfccs,_labels


from dotenv import load_dotenv
import discord
from discord.ext import commands
import os
import re

load_dotenv()
token = os.getenv('DISCORD_TOKEN')
commMark = os.getenv('COMMAND_MARKER')

description = 'Discord administration bot'

intents = discord.Intents.default()
intents.message_content = True
intents.members = True

bot = commands.Bot(command_prefix=commMark, description=description, intents=intents)

#posts log in message on log in
@bot.event
async def on_ready():
    print('Logged on as {bot.user} (ID {bot.user.id})')
    print('-----------')
#------------------------------------------------Functions---------------------------------------------------#

def get_rid(ctx, role_input):
    print("get_rid starting") #debugging - prints once function is called

    #cleans input and assigns to role_name
    role_name = role_input.strip()
    print(role_name)

    #first trying regext to get the id from the message itself
    role_id = re.search(r'\d{18}', role_name)
    roles_list = [] #initializing return list
    if role_id != None: #checking if re found something
        role_id = role.id.group(0) # getting readable id
        roles_list.append(int(role_id)) #getting and appending role-id to list
    else:
        #iterating through roles, searching for name match
        for g_role in ctx.guild.roles:
            if role_name in str(g_role.name):
                roles_list.append(int(g_role.id)) #appending to list

    print(roles_list) #debugging - prints roles_list
    roleLen = len(roles_list)
    print('length: ' + str(roleLen)) #debugging - prints length of roles_list
    print('get_rid finishing')
    return roles_list, len(roles_list)

#similar function to get_rid, but for retrieving user ID
def getuid(ctx, user_input):
    print("get_uid starting") #debugging - prints once function is called
    #cleans input and assigns to role_name
    users_list = []
    user_name = user_input.strip()
    print("uid start " + user_name)
    for g_user in ctx.guild.members:
        print( "uid for " + str(g_user))
        if user_name in str(g_user):
            users_list.append(int(g_user.id))
            print("username match")
            print("appended " + str(g_user.id)) #appending to list
            print("get_uid users list " + str(users_list))
        else:
            print("Not a match")
    print("get_uid list" + str(users_list)) #debugging - prints roles_list
    userLen = len(users_list)
    print(userLen)
    print('get_uid finishing')
    return users_list, len(users_list)

#----------------------------------------- Commands below, functions above-----------------------------------------------------------#

#------------------------------------------testing/troubleshooting commands----------------------------------------------------------#

#@bot.command()
#async def hello(ctx):
#    await ctx.send(f'Hello {ctx.author.display_name}.')

#test command, just echoes the argument
#@bot.command()
#async def test(ctx, content):
#    await ctx.send(content)

#-----------------------------------------------administrative commands---------------------------------------------------------------#
#command to get role ID
@bot.command()
async def roleid(ctx, role_name: str):
    try:
        role, le = get_rid(ctx, role_name)
        print(role)
        print(le)
        if le == 1:
            roleAdd = role[0]
            await ctx.send(roleAdd)
    except:
        emby = discord.Embed(title="", color=discord.Color.red())
        emby.add_field(name="Something went wrong", value="Please check your given argument")
        await ctx.send(embed=emby)

#command to add role to user
@bot.command()
async def addrole(ctx, role_name: str, user):
    try:
        role, le = get_rid(ctx, role_name)
        print(role)
        print(le)
        if le == 1:
            roleAdd = role[0]
            print(roleAdd)
            getuid(user)
            await ctx.send('Adding role %s to user %s' % (role_name, user))

    except:
        print("except")

#command to feth user id's
@bot.command()
async def userid(ctx, user):
    print('User ID command called by %s Requesting UserID for %s' % (ctx.author, user ))
    try:
        #calls function to get user ID by username, then prints variables for debugging/logging
        userN, leU = getuid(ctx, user)
        #outputs all user IDs to chat
        if leU == 0:
            await ctx.send("No user found with that name")
        else:
            for i in userN:
                await ctx.send(i)
    except:
        emby = discord.Embed(title="", color=discord.Color.red())
        emby.add_field(name="Something went wrong", value="Please check your given argument")
        await ctx.send(embed=emby)

#starts the bot
bot.run(token)


import sqlite3
import sys

from PyQt6.QtWidgets import QApplication, QLabel, QWidget, QGridLayout, \
    QLineEdit, QPushButton, QMainWindow, QTableWidget, QTableWidgetItem, QDialog, \
    QVBoxLayout, QComboBox, QToolBar, QStatusBar, QMessageBox

from PyQt6.QtGui import QAction, QIcon

from PyQt6.QtCore import Qt

# Database connection class
class DatabaseConnection:
    def __init__(self, database_file="database.db"):
        self.database_file = database_file

    def connect(self):
        # Establish connection to database and create cursor
        connection = sqlite3.connect(self.database_file)
        cursor = connection.cursor()

        # return connection and cursor, destructure variables in creation of instances
        return connection, cursor

    def close_connection(self, connection, cursor):

        # Commit changes to db and close connections, refresh app table
        return connection.commit(), cursor.close(), connection.close(), student_management_sys.load_data()

# App Main Window class
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Student Management System")
        self.setMinimumSize(600, 400)

        # Menu items
        file_menu_item = self.menuBar().addMenu("&File")
        utility_menu_item = self.menuBar().addMenu("&Utility")
        help_menu_item = self.menuBar().addMenu("&Help")

        # Add student menu item and action with toolbar icon binding to action
        add_student_action = QAction(QIcon("icons/add.png"), "Add Student", self)
        add_student_action.triggered.connect(self.insert)
        file_menu_item.addAction(add_student_action)

        # About menu item and action
        about_action = QAction("About", self)
        help_menu_item.addAction(about_action)
        about_action.triggered.connect(self.about)

        # SEARCH item and action with toolbar icon binding to action
        search_action = QAction(QIcon("icons/search.png"), "Search", self)
        search_action.triggered.connect(self.search)
        utility_menu_item.addAction(search_action)

        # Toolbar widget and elements, toolbar is also movable
        toolbar = QToolBar()
        toolbar.setMovable(True)
        self.addToolBar(toolbar)
        toolbar.addAction(add_student_action)
        toolbar.addAction(search_action)

        # Statusbar widget and elements
        self.statusbar = QStatusBar()
        self.setStatusBar(self.statusbar)

        # QTableWidget attributes
        self.table = QTableWidget()
        self.table.setColumnCount(4)
        self.table.setHorizontalHeaderLabels(("Id", "Name", "Course", "Mobile"))

        # To hide default vertical numbers not associated with SQL database
        self.table.verticalHeader().setVisible(False)

        # Detect if cell is clicked
        self.table.cellClicked.connect(self.cell_clicked)

        # Set a center layout widget to QTableWidget instance
        self.setCentralWidget(self.table)

    # Cell clicked method
    def cell_clicked(self):
        # Edit button
        edit_button = QPushButton("Edit Record")
        edit_button.clicked.connect(self.edit)

        # Delete button
        delete_button = QPushButton("Delete Record")
        delete_button.clicked.connect(self.delete)

        # Find children of statusbar widgets and remove appending children
        # Prevent duplications of widgets for every cell click
        children = self.findChildren(QPushButton)
        if children:
            for child in children:
                self.statusbar.removeWidget(child)

        # Add widgets after cell is clicked
        self.statusbar.addWidget(edit_button)
        self.statusbar.addWidget(delete_button)

    # Load SQL Database data in PyQt
    def load_data(self):
        # Connect SQL database
        connection, cursor = DatabaseConnection().connect()
        results = connection.execute("SELECT * FROM students")

        # Initialize table number to 0
        self.table.setRowCount(0)

        # Iterate through row numbers
        for row_number, row_data in enumerate(results):

            # Every index insert a row cell with a row number
            self.table.insertRow(row_number)

            # Iterate through column numbers
            for column_number, column_data in enumerate(row_data):

                # Every index of a row number and column number add column data
                self.table.setItem(row_number, column_number, QTableWidgetItem(str(column_data)))

        # Close the database connection
        connection.close()

    # Insert new data method call
    def insert(self):
        dialog = InsertDialog()
        dialog.exec()

    def search(self):
        search_dialog = SearchDialog()
        search_dialog.exec()

    def edit(self):
        edit_dialog = EditDialog()
        edit_dialog.exec()

    def delete(self):
        delete_dialog = DeleteDialog()
        delete_dialog.exec()

    def about(self):
        about_dialog = AboutDialog()
        about_dialog.exec()

# Dialog Attributes for Insert
class InsertDialog(QDialog):
    def __init__(self):
        super().__init__()

        # Set Window Attributes
        self.setWindowTitle("Insert Student Data")
        self.setFixedWidth(300)
        self.setFixedHeight(300)

        layout = QVBoxLayout()

        # Add Student Name widget
        self.student_name = QLineEdit()
        self.student_name.setPlaceholderText("Name")
        layout.addWidget(self.student_name)

        # Add Course ComboBox widget
        self.course_name = QComboBox()
        courses = ["Biology", "Math", "Astronomy", "Physics"]
        self.course_name.addItems(courses)
        layout.addWidget(self.course_name)

        # Add Mobile Number widget
        self.mobile_number = QLineEdit()
        self.mobile_number.setPlaceholderText("Mobile Number")
        layout.addWidget(self.mobile_number)

        # Submit button
        submit_btn = QPushButton("Register")
        submit_btn.clicked.connect(self.add_student)
        layout.addWidget(submit_btn)

        self.setLayout(layout)

    # Add Student method
    def add_student(self):
        # Reference to field values stored in variables
        name = self.student_name.text()
        course = self.course_name.itemText(self.course_name.currentIndex())
        mobile = self.mobile_number.text()

        # Connect to database and create cursor
        connection, cursor = DatabaseConnection().connect()

        # Use the cursor to destructure and INSERT reference variables into related db columns
        cursor.execute("INSERT INTO students (name, course, mobile) VALUES (?, ?, ?)",
                       (name, course, mobile))

        # Commit changes, Close connection to database and cursor
        DatabaseConnection().close_connection(connection, cursor)

        # Close window after entry
        self.close()

# Dialog Attributes for Search
class SearchDialog(QDialog):
    def __init__(self):
        super().__init__()

        # Set Window Attributes
        self.setWindowTitle("Search Student")
        self.setFixedWidth(300)
        self.setFixedHeight(300)

        search_layout = QVBoxLayout()

        # Search Student Name widget
        self.search_student_name = QLineEdit()
        self.search_student_name.setPlaceholderText("Name")
        search_layout.addWidget(self.search_student_name)

        # Search button
        search_btn = QPushButton("Search")
        search_btn.clicked.connect(self.search_student)
        search_layout.addWidget(search_btn)

        self.setLayout(search_layout)

    # Search Student method
    def search_student(self):
        # Reference to field values stored in variables
        name = self.search_student_name.text()

        # Connect to database and create cursor
        connection, cursor = DatabaseConnection().connect()

        # Select all fields that contained query of student name in database
        result = cursor.execute("SELECT * FROM students WHERE name = ?", (name, ))
        rows = list(result)
        print(rows)

        # Select all fields in Main window table and find match of student name
        items = student_management_sys.table.findItems(name, Qt.MatchFlag.MatchFixedString)

        # Highlight all names that match query and print item row to console
        for item in items:
            print(item)
            student_management_sys.table.item(item.row(), 1).setSelected(True)

        # Close cursor and connection to db
        cursor.close()
        connection.close()

        # Close dialog after search
        self.close()

# Dialog Attributes for Edit
class EditDialog(QDialog):
    def __init__(self):
        super().__init__()

        # Set Window Attributes
        self.setWindowTitle("Update Student Data")
        self.setFixedWidth(300)
        self.setFixedHeight(300)

        layout = QVBoxLayout()

        # Get table row and column of student to edit
        index = student_management_sys.table.currentRow()

        # Get ID from selected Row
        self.student_id = student_management_sys.table.item(index, 0).text()

        # Get student name
        student_name = student_management_sys.table.item(index, 1).text()

        # Get Course name
        course_name = student_management_sys.table.item(index, 2).text()

        # Get Mobile number
        mobile_number = student_management_sys.table.item(index, 3).text()

        # Add Student Name widget
        self.student_name = QLineEdit(student_name)
        self.student_name.setPlaceholderText("Name")
        layout.addWidget(self.student_name)

        # Add Course ComboBox widget
        self.course_name = QComboBox()
        courses = ["Biology", "Math", "Astronomy", "Physics"]
        self.course_name.addItems(courses)
        self.course_name.setCurrentText(course_name)
        layout.addWidget(self.course_name)

        # Add Mobile Number widget
        self.mobile_number = QLineEdit(mobile_number)
        self.mobile_number.setPlaceholderText("Mobile Number")
        layout.addWidget(self.mobile_number)

        # Submit button
        submit_btn = QPushButton("Update")
        submit_btn.clicked.connect(self.update_student)
        layout.addWidget(submit_btn)

        self.setLayout(layout)

    # Update method
    def update_student(self):
        connection, cursor = DatabaseConnection().connect()

        # Destructure table rows and UPDATE with new values from references in edit fields
        cursor.execute("UPDATE students SET name = ?, course = ?, mobile = ? WHERE id = ?",
                       (self.student_name.text(),
                        self.course_name.itemText(self.course_name.currentIndex()),
                        self.mobile_number.text(), self.student_id))

        # Commit changes, Close connection to database and cursor
        DatabaseConnection().close_connection(connection, cursor)

        # Close dialog after update
        self.close()

# Dialog Attributes for Delete
class DeleteDialog(QDialog):
    def __init__(self):
        super().__init__()

        # Set Window Attributes
        self.setWindowTitle("Delete Student Data")

        layout = QGridLayout()
        confirmation = QLabel("Are you sure you want to delete?")
        yes = QPushButton("Yes")
        no = QPushButton("No")

        layout.addWidget(confirmation, 0, 0, 1, 2)
        layout.addWidget(yes, 1, 0)
        layout.addWidget(no, 1, 1)
        self.setLayout(layout)

        yes.clicked.connect(self.delete_student)
        no.clicked.connect(self.close)

    # Delete Method
    def delete_student(self):
        # Connect to database
        connection, cursor = DatabaseConnection().connect()

        # Get table row and column of student to edit
        index = student_management_sys.table.currentRow()

        # Get ID from selected Row
        student_id = student_management_sys.table.item(index, 0).text()

        # Execute SQL DELETE query using student ID
        cursor.execute("DELETE FROM students WHERE id = ?", (student_id, ))

        # Commit changes, Close connection to database and cursor
        DatabaseConnection().close_connection(connection, cursor)

        # Create a message box to relay deletion was successful
        confirmation_widget = QMessageBox()
        confirmation_widget.setWindowTitle("Success")
        confirmation_widget.setText("The Record Deleted Successfully!")
        confirmation_widget.exec()

        # Close delete dialog window
        self.close()

# About Inheriting from 'QMessageBox' simple child version of a QDialog
class AboutDialog(QMessageBox):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("About")

        # Content for about section
        content = "I built this academic management app as I learned PyQt6 and it's component libraries. " \
                  "I used object oriented architecture to keep my code organized and scalable." \
                  " A SQL database was used store records and 'CRUD' methods were used to managed it's contents."

        # Use set text to content
        self.setText(content)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    student_management_sys = MainWindow()
    student_management_sys.show()
    student_management_sys.load_data()
    sys.exit(app.exec())


import sys
import os
from os.path import splitext
import glob
from common import TestCase

def get_tests():
    """Get all the tests to run.
    """
    files = glob.glob('test_*.py')
    return files

def run_all(tests):
    """Run the given tests.
    """
    args = ' '.join(sys.argv[1:])
    success = []
    fail = []
    for test in tests:
        cmd = 'python %s %s'%(test, args)
        print(cmd)
        status = os.system(cmd)
        if status == 0:
            print("OK")
            success.append(test)
        else:
            print("FAIL: %s"%test)
            fail.append(test)

    print('-'*70)
    print("%d successful tests, %d failures"%(len(success), len(fail)))
    for test in fail:
        print(test)
    print('-'*70)
    return len(fail) != 0

class RunAllTests(TestCase):
    """Runs all the tests in one go, instead of running each test
    separately.  This speeds up the testing.
    """
    def get_tests(self):
        tests = get_tests()
        tests = [splitext(t)[0] for t in tests]
        klasses = []
        for test in tests:
            # Find test.
            m = __import__(test)
            m.mayavi = self.script
            m.application = self.application
            for name in dir(m):
                klass = getattr(m, name)
                try:
                    if issubclass(klass, TestCase) and klass is not TestCase:
                        mod_name = '%s.%s'%(test, name)
                        klasses.append((mod_name, klass))
                        break
                except TypeError:
                    continue
        return klasses

    def do(self):
        klasses = self.get_tests()
        for name, klass in klasses:
            # Close existing scenes.
            e = self.script.engine
            for scene in e.scenes:
                e.close_scene(scene)
            print('*'*80)
            print(name)
            obj = klass()
            obj.trait_set(script=self.script)
            obj.test()

def main():
    argv = ' '.join(sys.argv)

    if '--one-shot' in argv:
        argv = argv.replace('--one-shot', '')
        sys.argv = argv.split()
        t = RunAllTests()
        t.main()
    else:
        tests = get_tests()
        status = run_all(tests)
        sys.exit(status)

if __name__ == "__main__":
    main()


"""
MongoDB Interaction - A simple example for future developments
Fabio Bove | fabio.bove.dr@gmail.com
"""

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

# Imports
from pymongo import MongoClient

class MongoUtils:
    def __init__(self, auth_param: str, collection_name: str, database_name: str, data: dict) -> None:
        self.mongo_client       = None
        self.last_op_status     = None
        self.database           = None
        self.collection         = None
        self.database_list      = None
        self.collections_list   = None
        self.auth_param         = auth_param
        self.collection_name    = collection_name
        self.database_name      = database_name
        self.data               = data

    def get_last_op_status(self) -> str:
        """
        get_last_op_status, this method returns a string containing the status of the last operation made by this class

        param: None
        return: last_op_status: A string containing the status of the last operation made by this class
        """
        return self.last_op_status

    def connect_to_cluster(self) -> None:
        """
            connect_to_cluster, this method allow to instantiate a new cluster Connection using the pymongo lib

            pram: None
            return: None
        """
        try:
            self.mongo_client = MongoClient(self.auth_param)
            self.last_op_status = "Successfully connected to Mongo Cluster"
        except Exception as e:
            self.last_op_status = f"Something went wrong during cluster connection: \n {e}"
            self.mongo_client = None

    def init_dabase(self, database_name:str) -> None:
        """
            init_dabase method, creates (if don't exists yet) a new database with name <database_name>

            param: database_name: A string with the name of the new database
            return: Nothing
        """
        try: # Get the list of databases for the current cluster
            self.database_list = self.mongo_client.list_database_names()
            self.last_op_status = f"Got the list of active databases: \n {self.database_list}"
        except Exception as e:
            self.last_op_status = f"Can't get the list of databases: \n {e}"
            self.database_list = None

        try:
            if self.database_list is not None and database_name in self.database_list:
                self.last_op_status = f"Database {database_name} already exists."
                self.database = self.mongo_client.get_database(database_name)
            else:
                self.database = self.mongo_client[database_name]
                self.last_op_status = f"Database <{database_name}> created successfully."
        except Exception as e:
            self.last_op_status = f"Something went wrong during database creation: \n {e}"
            self.database = None

    def init_collection(self, collection_name:str):
        """
        init_collection method, initialize a collection if doesn't exists already otherwhise returns the existing one

        param: collection_name: The name of the collection
        return: Nothing
        """
        try:
            self.collections_list = self.database.list_collection_names()
        except Exception as e:
            self.last_op_status = f"Can't get the list of collection: \n {e}"
            self.collection = None
            self.collections_list = None
        try:
            if self.collections_list is not None and collection_name in  self.collections_list:
                self.last_op_status = f"Collection already exists."
                self.collection = self.database.get_collection(collection_name)
            else:
                self.collection = self.database[collection_name]
                self.last_op_status = f"Collection <{collection_name}> created successfully."
        except Exception as e:
            self.last_op_status = f"Something went wrong during collection creation: \n {e}"
            self.collection = None

    def init_documents(self, data:dict) -> None:
        """
        init_documents method, inserts the documents into our collection taken from the given data

        param: data: a dict containing all the data to load in the collection
        return: Nothing
        """
        try:
            self.collection.insert_many(data) # [self.collection.insert_one(elem) for elem in data]
            self.last_op_status = f"Documents loaded successfully."
        except Exception as e:
           self.last_op_status = f"Something went wrong during document insertion: \n {e}"

    def clean_collection(self, collection_name: str) -> None:
        """
        clean_collection method, remove all the documents of a collection

        param: collection_name: A string containing the name of the collection.
        return: Nothing
        """
        if collection_name is not None: # Load the desired collection, if collection_name is empty use the last collection connected to the class
            self.init_collection(collection_name)
        if self.collection is not None:
            if self.collection.count_documents({}) > 0:  # Remove the old documents
                self.collection.delete_many({})
                self.last_op_status = f"Removed old files from the collection."

    def init_cluster(self):
        self.connect_to_cluster()
        self.init_dabase(self.database_name)
        self.init_collection(self.collection_name)
        self.init_documents(self.data)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
CS224N 2018-19: Homework 5
model_embeddings.py: Embeddings for the NMT model
Pencheng Yin <pcyin@cs.cmu.edu>
Sahil Chopra <schopra8@stanford.edu>
Anand Dhoot <anandd@stanford.edu>
Michael Hahn <mhahn2@stanford.edu>
"""

import torch.nn as nn

# Do not change these imports; your module names should be
#   `CNN` in the file `cnn.py`
#   `Highway` in the file `highway.py`
# Uncomment the following two imports once you're ready to run part 1(j)

from cnn import CNN
from highway import Highway

# End "do not change"

class ModelEmbeddings(nn.Module):
    """
    Class that converts input words to their CNN-based embeddings.
    """
    def __init__(self, embed_size, vocab):
        """
        Init the Embedding layer for one language
        @param embed_size (int): Embedding size (dimensionality) for the output
        @param vocab (VocabEntry): VocabEntry object. See vocab.py for documentation.
        """
        super(ModelEmbeddings, self).__init__()

        ## A4 code
        # pad_token_idx = vocab.src['<pad>']
        # self.embeddings = nn.Embedding(len(vocab.src), embed_size, padding_idx=pad_token_idx)
        ## End A4 code

        ### YOUR CODE HERE for part 1j

        self.e_char = 50
        self.w_word = 21  # same as max_word_length. same value (21) used in function pad_sents_char in utils.py
        self.embed_size = embed_size  # same as e_word

        self.char_embedding = nn.Embedding(len(vocab.char2id), self.e_char, vocab.char2id['<pad>'])
        self.cnn = CNN(self.e_char, self.embed_size, self.w_word)
        self.highway = Highway(self.embed_size)

        ### END YOUR CODE

    def forward(self, input):
        """
        Looks up character-based CNN embeddings for the words in a batch of sentences.
        @param input: Tensor of integers of shape (sentence_length, batch_size, max_word_length) where
            each integer is an index into the character vocabulary

        @param output: Tensor of shape (sentence_length, batch_size, embed_size), containing the
            CNN-based embeddings for each word of the sentences in the batch
        """
        ## A4 code
        # output = self.embeddings(input)
        # return output
        ## End A4 code

        ### YOUR CODE HERE for part 1j

        # x_padded has shape : (sentence_length, batch_size, max_word_length)
        x_padded = input

        # x_emb has shape : (sentence_length, batch_size, max_word_length, e_char)
        x_emb = self.char_embedding(x_padded)

        # x_reshape_4D has shape : (sentence_length, batch_size, e_char, max_word_length)
        x_reshape_4D = x_emb.permute(0, 1, 3, 2)

        sentence_length, batch_size, e_char, max_word_length = x_reshape_4D.shape

        # x_reshape has shape : (-1, e_char, max_word_length)
        x_reshape = x_reshape_4D.view(-1, e_char, max_word_length)

        # x_conv_out has shape : (-1, e_word)
        x_conv_out = self.cnn(x_reshape)

        # x_word_embed has shape : (-1, e_word)
        x_word_embed = self.highway(x_conv_out)

        output = x_word_embed.view(sentence_length, batch_size, self.embed_size)

        return output

        ### END YOUR CODE


import argparse
import os
import unittest

from bin.get_alleles_from_srst2_mlst import get_mismatch_and_depth, get_new_and_existing_alleles, write_alleles_file, get_arguments
class TestProcessResults(unittest.TestCase):
    TEST_OUTPUT_PREFIX = 'test'
    TEST_FILE = 'tests/test_data/input/test__mlst__Streptococcus_agalactiae_MLST_alleles__results.txt'
    TEST_OUT1 = 'tests/test_data/output/test_mlst_alleles.txt'
    TEST_OUT2 = 'tests/test_data/output/test_mlst_alleles2.txt'

    def test_get_mismatch_and_depth(self):
        actual = get_mismatch_and_depth(self.TEST_FILE)
        self.assertEqual(actual, ('adhP_1/1snp', 173.614142857, 'ST-1'))

    def test_get_new_and_existing_alleles(self):
        actual = get_new_and_existing_alleles(('adhP_1/1snp', 173.614142857, 'ST-1'), 30, self.TEST_OUTPUT_PREFIX)
        f = open(self.TEST_OUTPUT_PREFIX + '_new_mlst_alleles.txt', "r")
        actual = "".join(f.readlines())
        self.assertEqual(actual, """Alleles found\nadhP_1\n""")
        os.remove(self.TEST_OUTPUT_PREFIX + '_new_mlst_alleles.txt')

    def test_get_new_and_existing_alleles_low_depth(self):
        actual = get_new_and_existing_alleles(('adhP_1/1snp', 29.99, 'ST-1'), 30, self.TEST_OUTPUT_PREFIX)
        f = open(self.TEST_OUTPUT_PREFIX + '_new_mlst_alleles.txt', "r")
        actual = "".join(f.readlines())
        self.assertEqual(actual, """test: No new MLST alleles were found with sufficient read depth above 30.\n""")
        os.remove(self.TEST_OUTPUT_PREFIX + '_new_mlst_alleles.txt')

    def test_get_new_and_existing_alleles_multi_alleles(self):
        actual = get_new_and_existing_alleles(('adhP_1/1snp;pheS_1/1snp', 173.614142857, 'ST-1'), 30, self.TEST_OUTPUT_PREFIX)
        f = open(self.TEST_OUTPUT_PREFIX + '_new_mlst_alleles.txt', "r")
        actual = "".join(f.readlines())
        self.assertEqual(actual, """Alleles found\nadhP_1\npheS_1\n""")
        os.remove(self.TEST_OUTPUT_PREFIX + '_new_mlst_alleles.txt')

    def test_get_new_and_existing_alleles_no_mismatches(self):
        actual = get_new_and_existing_alleles(('0', 173.614142857, 'ST-1'), 30, self.TEST_OUTPUT_PREFIX)
        f = open(self.TEST_OUTPUT_PREFIX + '_existing_mlst_alleles.txt', "r")
        actual = "".join(f.readlines())
        self.assertEqual(actual, """ID\tST\ntest\tST-1\n""")
        os.remove(self.TEST_OUTPUT_PREFIX + '_existing_mlst_alleles.txt')

    def test_alleles_file(self):
        write_alleles_file(['Alleles found', 'adhP_1', 'pheS_1'], self.TEST_OUT1)
        f = open(self.TEST_OUT1, "r")
        actual = "".join(f.readlines())
        self.assertEqual(actual, """Alleles found\nadhP_1\npheS_1\n""")

    def test_alleles_file_without_alleles(self):
        write_alleles_file(['No new MLST alleles were found.'], self.TEST_OUT2)
        f = open(self.TEST_OUT2, "r")
        actual = "".join(f.readlines())
        self.assertEqual(actual, """No new MLST alleles were found.\n""")

    def test_arguments(self):
        actual = get_arguments().parse_args(
            ['--mlst_results_file', 'mlst_file', '--min_read_depth', '30',
            '--output_prefix', 'out'])
        self.assertEqual(actual,
                         argparse.Namespace(mlst='mlst_file', min_depth=30, output='out'))

    def test_arguments_short_options(self):
        actual = get_arguments().parse_args(
            ['-m', 'mlst_file', '-d', '30', '-o', 'out'])
        self.assertEqual(actual,
                         argparse.Namespace(mlst='mlst_file', min_depth=30, output='out'))


from __future__ import annotations

from dataclasses import dataclass
from typing import Iterable

from pants.backend.javascript import install_node_package
from pants.backend.javascript.install_node_package import (
    InstalledNodePackageRequest,
    InstalledNodePackageWithSource,
)
from pants.backend.javascript.nodejs_project_environment import NodeJsProjectEnvironmentProcess
from pants.backend.javascript.package_json import (
    NodeBuildScriptEntryPointField,
    NodeBuildScriptExtraEnvVarsField,
    NodePackageDependenciesField,
)
from pants.core.goals.run import RunFieldSet, RunInSandboxBehavior, RunRequest
from pants.core.util_rules.environments import EnvironmentField
from pants.engine.env_vars import EnvironmentVars, EnvironmentVarsRequest
from pants.engine.internals.selectors import Get
from pants.engine.process import Process
from pants.engine.rules import Rule, collect_rules, rule
from pants.engine.unions import UnionRule

@dataclass(frozen=True)
class RunNodeBuildScriptFieldSet(RunFieldSet):
    required_fields = (NodeBuildScriptEntryPointField, NodePackageDependenciesField)
    run_in_sandbox_behavior = RunInSandboxBehavior.RUN_REQUEST_HERMETIC

    entry_point: NodeBuildScriptEntryPointField
    extra_env_vars: NodeBuildScriptExtraEnvVarsField
    environment: EnvironmentField

@rule
async def run_node_build_script(
    field_set: RunNodeBuildScriptFieldSet,
) -> RunRequest:
    installation = await Get(
        InstalledNodePackageWithSource, InstalledNodePackageRequest(field_set.address)
    )
    target_env_vars = await Get(
        EnvironmentVars, EnvironmentVarsRequest(field_set.extra_env_vars.value or ())
    )
    process = await Get(
        Process,
        NodeJsProjectEnvironmentProcess(
            installation.project_env,
            args=("--prefix", "{chroot}", "run", str(field_set.entry_point.value)),
            description=f"Running {str(field_set.entry_point.value)}.",
            input_digest=installation.digest,
            extra_env=target_env_vars,
        ),
    )

    return RunRequest(
        digest=process.input_digest,
        args=process.argv,
        extra_env=process.env,
        immutable_input_digests=process.immutable_input_digests,
    )

def rules() -> Iterable[Rule | UnionRule]:
    return [*collect_rules(), *install_node_package.rules(), *RunNodeBuildScriptFieldSet.rules()]


import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from math import sqrt
from scipy import stats

import warnings
warnings.filterwarnings("ignore")

from statsmodels.formula.api import ols
from sklearn.metrics import mean_squared_error, r2_score, explained_variance_score, mean_absolute_error
from sklearn.feature_selection import f_regression, SelectKBest, RFE
from sklearn.linear_model import LinearRegression, LassoLars, TweedieRegressor
from sklearn.preprocessing import PolynomialFeatures

from numpy import mean
from numpy import std, absolute
from sklearn.datasets import make_blobs
from sklearn.model_selection import LeaveOneOut
from sklearn.model_selection import cross_val_score
from sklearn.svm import SVR
from sklearn.ensemble import RandomForestRegressor

def feature_ranking(X_train_scaled, y_train):
    lm = LinearRegression()
    rfe = RFE(lm, 1)
    rfe.fit(X_train_scaled, y_train)
    ranks = rfe.ranking_
    names = X_train_scaled.columns.tolist()
    rankdf = pd.DataFrame({'features': names, 'rank': ranks}).set_index('rank').sort_values('rank')
    return rankdf

def cvLinearReg(X_train, y_train):
    # create loocv procedure
    cvLR = LeaveOneOut()
    # create model
    modelLR = LinearRegression()
    # evaluate model
    scoresLR = cross_val_score(modelLR, X_train, y_train, scoring='neg_mean_absolute_error', cv=cvLR, n_jobs=-1)
    # force positive
    scoresLR = absolute(scoresLR)
    # report performance
    print('MAE: %.3f (%.3f)' % (mean(scoresLR), std(scoresLR)))
    meanMAE = mean(scoresLR)
    stddevMAE = std(scoresLR)
    return meanMAE

def cvLassoLars(X_train, y_train, x):
    # LassoLars
    # create loocv procedure
    cvLL = LeaveOneOut()
    # create model
    modelLL = LassoLars(alpha=x)
    # evaluate model
    scoresLL = cross_val_score(modelLL, X_train, y_train, scoring='neg_mean_absolute_error', cv=cvLL, n_jobs=-1)
    # force positive
    scoresLL = absolute(scoresLL)
    # report performance
    print('MAE: %.3f (%.3f)' % (mean(scoresLL), std(scoresLL)))
    meanMAE = mean(scoresLL)
    stddevMAE = std(scoresLL)
    return meanMAE

def cvTweedie(X_train, y_train, pwr, alf):
    # Tweedie Regressor
    # create loocv procedure
    cvTW = LeaveOneOut()
    # create model
    modelTW = TweedieRegressor(power=pwr, alpha=alf) # 0 = normal distribution
    # evaluate model
    scoresTW = cross_val_score(modelTW, X_train, y_train, scoring='neg_mean_absolute_error', cv=cvTW, n_jobs=-1)
    # force positive
    scoresTW = absolute(scoresTW)
    # report performance
    print('MAE: %.3f (%.3f)' % (mean(scoresTW), std(scoresTW)))
    meanMAE = mean(scoresTW)
    stddevMAE = std(scoresTW)
    return meanMAE

def cvRandomForest(X_train, y_train, x):
    # Random Forest Regressor
    # create loocv procedure
    cvRF = LeaveOneOut()
    # create model
    modelRF = RandomForestRegressor(n_estimators=x, random_state = 123)
    # evaluate model
    scoresRF = cross_val_score(modelRF, X_train, y_train, scoring='neg_mean_absolute_error', cv=cvRF, n_jobs=-1)
    # force positive
    scoresRF = absolute(scoresRF)
    # report performance
    print('MAE: %.3f (%.3f)' % (mean(scoresRF), std(scoresRF)))
    meanMAE = mean(scoresRF)
    stddevMAE = std(scoresRF)
    return meanMAE

def cvSVR(X_train, y_train, x):
    # Support Vector Regressor
    # create loocv procedure
    cvSVR = LeaveOneOut()
    # create model
    modelSVR = SVR(kernel = x)
    # evaluate model
    scoresSVR = cross_val_score(modelSVR, X_train, y_train, scoring='neg_mean_absolute_error', cv=cvSVR, n_jobs=-1)
    # force positive
    scoresSVR = absolute(scoresSVR)
    # report performance
    print('MAE: %.3f (%.3f)' % (mean(scoresSVR), std(scoresSVR)))
    meanMAE = mean(scoresSVR)
    stddevMAE = std(scoresSVR)
    return meanMAE

def get_baseline_mean(y_train):
    '''
    Using mean gets baseline for y dataframe
    '''
    # determine Baseline to beat
    rows_needed = y_train.shape[0]
    # create array of predictions of same size as y_train.logerror based on the mean
    y_hat = np.full(rows_needed, np.mean(y_train))
    # calculate the MSE for these predictions, this is our baseline to beat
    baseline = mean_absolute_error(y_train, y_hat)
    print("Baseline MAE:", baseline)
    return baseline, y_hat

def get_baseline_median(y_train):
    '''
    Using median gets baseline for y dataframe
    '''
    # determine Baseline to beat
    rows_needed = y_train.shape[0]
    # create array of predictions of same size as y_train.logerror based on the median
    y_hat = np.full(rows_needed, np.median(y_train))
    # calculate the MSE for these predictions, this is our baseline to beat
    baseline = mean_absolute_error(y_train, y_hat)
    print("Baseline MAE:", baseline)
    return baseline, y_hat

def linear_reg_train(x_scaleddf, target):
    '''
    runs linear regression algorithm
    '''
    lm = LinearRegression()
    lm.fit(x_scaleddf, target)
    y_hat = lm.predict(x_scaleddf)

    LM_MAE = mean_absolute_error(target, y_hat)
    return LM_MAE

def lasso_lars(x_scaleddf, target):
    '''
    runs Lasso Lars algorithm
    '''
    # Make a model
    lars = LassoLars(alpha=1)
    # Fit a model
    lars.fit(x_scaleddf, target)
    # Make Predictions
    lars_pred = lars.predict(x_scaleddf)
    # Computer root mean squared error
    lars_MAE = mean_absolute_error(target, lars_pred)
    return lars_MAE

def polynomial2(X_trainsdf, target):
    '''
    runs polynomial algorithm
    '''
    # Make a model
    pf = PolynomialFeatures(degree=2)
    # Fit and Transform model to get a new set of features...which are the original features squared
    X_train_squared = pf.fit_transform(X_trainsdf)

    # Feed new features in to linear model.
    lm_squared = LinearRegression(normalize=True)
    lm_squared.fit(X_train_squared, target)
    # Make predictions
    lm_squared_pred = lm_squared.predict(X_train_squared)
    # Compute root mean squared error
    pf2_MAE = mean_absolute_error(target, lm_squared_pred)
    return pf2_MAE

def tweedie05(X_train_scaled, y_train):
    '''
    runs tweedie algorithm
    '''
    # Make Model
    tw = TweedieRegressor(power=0, alpha=.5) # 0 = normal distribution
    # Fit Model
    tw.fit(X_train_scaled, y_train)
    # Make Predictions
    tw_pred = tw.predict(X_train_scaled)
    # Compute root mean squared error
    tw_MAE = mean_absolute_error(y_train, tw_pred)
    return tw_MAE

def randomforest_test(x_scaleddf, target, X_test, y_test, est):
    '''
    runs random forest regressor
    '''
    # make model
    regressor = RandomForestRegressor(n_estimators = est, random_state = 123)
    # fit the model
    regressor.fit(x_scaleddf, target)
    # make predictions
    y_pred = regressor.predict(X_test)
    # calculate MAE
    randMAE = mean_absolute_error(y_test, y_pred)
    return randMAE, regressor

def lasso_lars_test(x_scaleddf, target, X_test, y_test):
    '''
    runs Lasso Lars algorithm
    '''
    # Make a model
    lars = LassoLars(alpha=1)
    # Fit a model
    lars.fit(x_scaleddf, target)
    # Make Predictions
    lars_pred = lars.predict(X_test)
    # calculate MAE
    lars_MAE = mean_absolute_error(y_test, lars_pred)
    return lars_MAE, lars, lars_pred

def linear_test(x_scaleddf, target, X_test, y_test):
    '''
    runs Lasso Lars algorithm
    '''
    # Make a model
    lm = LinearRegression()
    # Fit model on train dataset
    lm.fit(x_scaleddf, target)
    # Make Predictions on test dataset
    y_hat = lm.predict(X_test)
    # calculate MAE
    LM_MAE = mean_absolute_error(y_test, y_hat)
    return LM_MAE, lm, y_hat

def SVR_test(x_scaleddf, target, X_test, y_test, kern):
    '''
    runs Support Vector Regressor algorithm
    '''
    # Make a model
    regressor = SVR(kernel = kern)
    # Fit model on train dataset
    regressor.fit(x_scaleddf, target)
    # Make Predictions on test dataset
    y_hat = sc_y.inverse_transform(regressor.predict(sc_X.transform(X_test)))
    # calculate MAE
    svr_MAE = mean_absolute_error(y_test, y_hat)
    return svr_MAE, regressor

def tweedie_test(X_train, y_train, X_test, y_test, pwr, alf):
    '''
    runs tweedie algorithm
    '''
    # Make Model
    tw = TweedieRegressor(power=pwr, alpha=alf) # 0 = normal distribution
    # Fit Model
    tw.fit(X_train, y_train)
    # Make Predictions
    tw_pred = tw.predict(X_test)
    # Compute root mean squared error
    tw_MAE = mean_absolute_error(y_test, tw_pred)
    return tw_MAE, tw, tw_pred

def create_visualdf(y_test, y_train, y_test_predLL, y_test_predLR, y_test_predTW, y_test_predrTW):
    '''
    creates dataframe for making visualizations
    '''
    visualdf = pd.DataFrame()
    visualdf['actual'] = y_test.tract_cases_per_100k
    visualdf['baseline'] = y_train.tract_cases_per_100k.mean()
    visualdf['TWpred'] = y_test_predTW
    visualdf['LRpred'] = y_test_predLR
    visualdf['LLpred'] = y_test_predLL
    visualdf['SVI_only'] = y_test_predrTW
    return visualdf

def plot_actual_vs_predicted(visualdf):
    '''
    Produces subplots of actual VS predicted for the top models
    '''
    plt.figure(figsize=(16,8))
    #plt.suptitle('Plotting Actual Cases per 100K vs Predicted Cases per 100K')
    plt.plot(visualdf.actual, visualdf.baseline, alpha=.5, color="gray", label='_nolegend_')
    #plt.annotate("Baseline: Predict Using Mean", (15, 8))
    plt.plot(visualdf.actual, visualdf.actual, alpha=.5, color="blue", label='_nolegend_')
    #plt.annotate("The Ideal Line: Predicted = Actual", (.5, 1), rotation=15.5)
    #plt.subplot(1,3,1,)
    plt.scatter(visualdf.actual, visualdf.SVI_only,
               alpha=.5, color="blue", s=50, label="Model: TW SVI only")
    #plt.subplot(1,3,2)
    plt.scatter(visualdf.actual, visualdf.TWpred,
                alpha=.5, color="green", s=100, label="Model: TW Top 4 Features")
    #plt.subplot(1,3,3)
    # plt.scatter(visualdf.actual, visualdf.LLpred,
    #           alpha=.5, color="orange", s=75, label="Model: LassoLars")
    plt.legend()
    plt.xlabel("Actual Cases per 100K")
    plt.ylabel("Predicted Cases per 100K")

    # plt.annotate("The polynomial model appears to overreact to noise", (2.0, -10))
    # plt.annotate("The OLS model (LinearRegression)\n appears to be most consistent", (15.5, 3))
    plt.show()

def plotting_errors(visualdf):
    '''
    Plots the errors of the top models with zero error line
    '''
    # plotting Errors in Predictions
    plt.figure(figsize=(16,8))
    plt.axhline(label="No Error")
    plt.scatter(visualdf.actual, visualdf.SVI_only-visualdf.actual,
                alpha=.5, color="blue", s=50, label="Model: TW SVI only")
    plt.scatter(visualdf.actual, visualdf.TWpred-visualdf.actual,
                alpha=.5, color="green", s=100, label="Model: TW Top 4 Features")
    # plt.scatter(visualdf.actual, visualdf.LLpred-visualdf.actual,
    #             alpha=.5, color="orange", s=75, label="Model: LassoLars")
    plt.legend()
    plt.xlabel("Actual Cases per 100K")
    plt.ylabel("Residual/Error: Predicted Cases per 100K - Actual Cases per 100K")
    plt.title("Do the size of errors change as the actual value changes?")
    # plt.annotate("The polynomial model appears to overreact to noise", (2.0, -10))
    # plt.annotate("The OLS model (LinearRegression)\n appears to be most consistent", (15.5, 3))
    plt.show()

def plotting_histograms(visualdf):
    '''
    Plots Histograms of top models, currently only shows actual vs best performing
    '''
    plt.figure(figsize=(16,8))
    plt.hist(visualdf.actual, color='blue', alpha=.5, label="Actual Cases per 100K", histtype=u'step', linewidth=5)
    plt.hist(visualdf.LRpred, color='orange', alpha=.5, label="Model: TW SVI only")
    plt.hist(visualdf.TWpred, color='green', alpha=.5, label="Model: TW Top 4 Features")
    #plt.hist(visualdf.LLpred, color='red', alpha=.5, label="Model: LassoLars")
    plt.xlabel("Actual Cases per 100K")
    plt.ylabel("predictions")
    plt.title("SVI alone is not enough")
    plt.legend()
    plt.show()


from django.conf.urls import url    # include is adding then
from django.contrib import admin
from .views import(
    post_home,
    post_delete,
    post_update,
    post_edit,
    post_create,
    post_save,
    )

urlpatterns = [

    url(r'^$',post_home),
    url(r'^delete/$',post_delete),
    url(r'^update/$',post_update),
    url(r'^edit/$',post_edit),
    url(r'^create/$',post_create),
    url(r'^save/$',post_save),

]


from sklearn.ensemble import AdaBoostRegressor
from sklearn.ensemble import RandomForestRegressor, ExtraTreesRegressor, GradientBoostingRegressor

def run(x_train, y_train, x_test, y_test,
        base_estimator, estimator_params, n_estimators, learning_rate, loss, random_state):
    base_estimator = getEstimator(base_estimator, estimator_params)
    reg = AdaBoostRegressor(base_estimator=base_estimator,
                            n_estimators=n_estimators,
                            learning_rate=learning_rate,
                            loss=loss,
                            random_state=random_state).fit(x_train, y_train)

    return {'train_predict': reg.predict(x_train).tolist(),
            'test_predict': reg.predict(x_test).tolist(),
            'train_score': reg.score(x_train, y_train),
            'test_score': reg.score(x_test, y_test),
            'estimator_weights_': reg.estimator_weights_.tolist(),
            'estimator_errors_': reg.estimator_errors_.tolist(),
            'feature_importances_': reg.feature_importances_.tolist()
            }

def getEstimator(base_estimator, estimator_params):
    if base_estimator is None:
        return base_estimator
    base_estimator.replace("(", "").replace(")", "")
    if estimator_params is None:
        estimator_params = {}
    return {
        'GradientBoostingRegressor': GradientBoostingRegressor(*estimator_params),
        'ExtraTreesRegressor': ExtraTreesRegressor(*estimator_params),
        'RandomForestRegressor': RandomForestRegressor(*estimator_params)
    }.get(base_estimator, RandomForestRegressor(max_depth=3))


import struct
import typing

from .base_bean import BaseBean
from .config import Config
from .ctrl_enum import EnumDevice, EnumCmdType, EnumFanDirection, EnumOutDoorRunCond, EnumFanVolume, EnumControl, \
    EnumSensor, FreshAirHumidification, ThreeDFresh
from .dao import Room, AirCon, Geothermic, Ventilation, HD, Device, AirConStatus, get_device_by_aircon, Sensor, \
    UNINITIALIZED_VALUE
from .param import GetRoomInfoParam, AirConRecommendedIndoorTempParam, AirConCapabilityQueryParam, \
    AirConQueryStatusParam, Sensor2InfoParam

def decoder(b):
    if b[0] != 2:
        return None, None

    length = struct.unpack('<H', b[1:3])[0]
    if length == 0 or len(b) - 4 < length or struct.unpack('<B', b[length + 3:length + 4])[0] != 3:
        if length == 0:
            return HeartbeatResult(), None
        else:
            return None, None

    return result_factory(struct.unpack('<BHBBBBIBIBH' + str(length - 16) + 'sB', b[:length + 4])), b[length + 4:]

def result_factory(data):
    r1, length, r2, r3, subbody_ver, r4, cnt, dev_type, dev_id, need_ack, cmd_type, subbody, r5 = data
    if dev_id == EnumDevice.SYSTEM.value[1]:
        if cmd_type == EnumCmdType.SYS_ACK.value:
            result = AckResult(cnt, EnumDevice.SYSTEM)
        elif cmd_type == EnumCmdType.SYS_CMD_RSP.value:
            result = CmdRspResult(cnt, EnumDevice.SYSTEM)
        elif cmd_type == EnumCmdType.SYS_TIME_SYNC.value:
            result = TimeSyncResult(cnt, EnumDevice.SYSTEM)
        elif cmd_type == EnumCmdType.SYS_ERR_CODE.value:
            result = ErrCodeResult(cnt, EnumDevice.SYSTEM)
        elif cmd_type == EnumCmdType.SYS_GET_WEATHER.value:
            result = GetWeatherResult(cnt, EnumDevice.SYSTEM)
        elif cmd_type == EnumCmdType.SYS_LOGIN.value:
            result = LoginResult(cnt, EnumDevice.SYSTEM)
        elif cmd_type == EnumCmdType.SYS_CHANGE_PW.value:
            result = ChangePWResult(cnt, EnumDevice.SYSTEM)
        elif cmd_type == EnumCmdType.SYS_GET_ROOM_INFO.value:
            result = GetRoomInfoResult(cnt, EnumDevice.SYSTEM)
        elif cmd_type == EnumCmdType.SYS_QUERY_SCHEDULE_SETTING.value:
            result = QueryScheduleSettingResult(cnt, EnumDevice.SYSTEM)
        elif cmd_type == EnumCmdType.SYS_QUERY_SCHEDULE_ID.value:
            result = QueryScheduleIDResult(cnt, EnumDevice.SYSTEM)
        elif cmd_type == EnumCmdType.SYS_HAND_SHAKE.value:
            result = HandShakeResult(cnt, EnumDevice.SYSTEM)
        elif cmd_type == EnumCmdType.SYS_CMD_TRANSFER.value:
            result = CmdTransferResult(cnt, EnumDevice.SYSTEM)
        elif cmd_type == EnumCmdType.SYS_QUERY_SCHEDULE_FINISH.value:
            result = QueryScheduleFinish(cnt, EnumDevice.SYSTEM)
        elif cmd_type == EnumCmdType.SYS_SCHEDULE_QUERY_VERSION_V3:
            result = ScheduleQueryVersionV3Result(cnt, EnumDevice.SYSTEM)
        elif cmd_type == EnumCmdType.SENSOR2_INFO:
            result = Sensor2InfoResult(cnt, EnumDevice.SYSTEM)
        else:
            result = UnknownResult(cnt, EnumDevice.SYSTEM, cmd_type)
    elif dev_id == EnumDevice.NEWAIRCON.value[1] or dev_id == EnumDevice.AIRCON.value[1] \
            or dev_id == EnumDevice.BATHROOM.value[1] or dev_id == EnumDevice.SENSOR.value[1]:
        device = EnumDevice((8, dev_id))
        if cmd_type == EnumCmdType.STATUS_CHANGED.value:
            result = AirConStatusChangedResult(cnt, device)
        elif cmd_type == EnumCmdType.QUERY_STATUS.value:
            result = AirConQueryStatusResult(cnt, device)
        elif cmd_type == EnumCmdType.AIR_RECOMMENDED_INDOOR_TEMP.value:
            result = AirConRecommendedIndoorTempResult(cnt, device)
        elif cmd_type == EnumCmdType.AIR_CAPABILITY_QUERY.value:
            result = AirConCapabilityQueryResult(cnt, device)
        elif cmd_type == EnumCmdType.QUERY_SCENARIO_SETTING.value:
            result = AirConQueryScenarioSettingResult(cnt, device)
        elif cmd_type == EnumCmdType.SENSOR2_INFO.value:
            result = Sensor2InfoResult(cnt, device)
        else:
            result = UnknownResult(cnt, device, cmd_type)
    else:
        """ignore other device"""
        result = UnknownResult(cnt, EnumDevice.SYSTEM, cmd_type)

    result.subbody_ver = subbody_ver
    result.load_bytes(subbody)

    return result

class Decode:
    def __init__(self, b):
        self._b = b
        self._pos = 0

    def read1(self):
        pos = self._pos
        s = struct.unpack('<B', self._b[pos:pos + 1])[0]
        pos += 1
        self._pos = pos
        return s

    def read2(self):
        pos = self._pos
        s = struct.unpack('<H', self._b[pos:pos + 2])[0]
        pos += 2
        self._pos = pos
        return s

    def read4(self):
        pos = self._pos
        s = struct.unpack('<I', self._b[pos:pos + 4])[0]
        pos += 4
        self._pos = pos
        return s

    def read(self, l):
        pos = self._pos
        s = self._b[pos:pos + l]
        pos += l
        self._pos = pos
        return s

    def read_utf(self, l):
        pos = self._pos
        try:
            s = self._b[pos:pos + l].decode('utf-8')
        except UnicodeDecodeError:
            s = None
        pos += l
        self._pos = pos
        return s

class BaseResult(BaseBean):
    def __init__(self, cmd_id: int, targe: EnumDevice, cmd_type: EnumCmdType):
        BaseBean.__init__(self, cmd_id, targe, cmd_type)

    def load_bytes(self, b):
        """do nothing"""

    def do(self):
        """do nothing"""

class HeartbeatResult(BaseResult):
    def __init__(self):
        BaseResult.__init__(self, 0, EnumDevice.SYSTEM, EnumCmdType.SYS_ACK)

class AckResult(BaseResult):
    def __init__(self, cmd_id: int, target: EnumDevice):
        BaseResult.__init__(self, cmd_id, target, EnumCmdType.SYS_ACK)

    def load_bytes(self, b):
        Config.is_new_version = struct.unpack('<B', b)[0] == 2

class ScheduleQueryVersionV3Result(BaseResult):
    def __init__(self, cmd_id: int, target: EnumDevice):
        BaseResult.__init__(self, cmd_id, target, EnumCmdType.SYS_ACK)

class Sensor2InfoResult(BaseResult):
    def __init__(self, cmd_id: int, target: EnumDevice):
        BaseResult.__init__(self, cmd_id, target, EnumCmdType.SENSOR2_INFO)
        self._count = 0
        self._mode = 0
        self._room_id = 0
        self._sensor_type = 0
        self._sensors: typing.List[Sensor] = []

    def load_bytes(self, b):
        data = Decode(b)
        self._mode = data.read1()
        count = data.read1()
        self._count = count
        while count > 0:
            self._room_id = data.read1()
            d = Decode(data.read(data.read1()))
            self._sensor_type = d.read1()
            unit_id = d.read1()
            sensor = Sensor()
            sensor.mac = d.read(6).hex()
            sensor.room_id = self._room_id
            sensor.unit_id = unit_id
            length = d.read1()
            sensor.alias = d.read_utf(length)
            sensor.name = sensor.alias
            sensor.type1 = d.read1()
            sensor.type2 = d.read1()
            humidity = UNINITIALIZED_VALUE
            hcho = UNINITIALIZED_VALUE
            temp = UNINITIALIZED_VALUE
            if (sensor.type1 & 1) == 1:
                temp = d.read2()
            if ((sensor.type1 >> 1) & 1) == 1:
                humidity = d.read2()
            pm25 = UNINITIALIZED_VALUE
            if (sensor.type1 >> 2) & 1 == 1:
                pm25 = d.read2()
            co2 = UNINITIALIZED_VALUE
            if (sensor.type1 >> 3) & 1 == 1:
                co2 = d.read2()
            voc = EnumSensor.Voc.STEP_UNUSE
            if (sensor.type1 >> 4) & 1 == 1:
                f = d.read1()
                voc = EnumSensor.Voc(f)
            tvoc = UNINITIALIZED_VALUE
            if (sensor.type1 >> 5) & 1 == 1:
                tvoc = d.read2()
            if (sensor.type1 >> 6) & 1 == 1:
                hcho = d.read2()
            switch_on_off = d.read1() == 1
            temp_upper = d.read2()
            temp_lower = d.read2()
            humidity_upper = d.read2()
            humidity_lower = d.read2()
            pm25_upper = d.read2()
            pm25_lower = d.read2()
            co2_upper = d.read2()
            co2_lower = d.read2()
            voc_lower = d.read1()
            tvoc_upper = d.read2()
            hcho_upper = d.read2()
            connected = d.read1() == 1
            sleep_mode_count = d.read1()
            sleep_mode_enable = False
            if sleep_mode_count > 0:
                sleep_mode_enable = d.read1() == 1
            sensor.sensor_type = self._sensor_type
            sensor.temp = temp
            sensor.humidity = humidity
            sensor.pm25 = pm25
            sensor.co2 = co2
            sensor.voc = voc
            if self._sensor_type == 3:
                sensor.tvoc = tvoc
                sensor.hcho = hcho
                sensor.tvoc_upper = tvoc_upper
                sensor.hcho_upper = hcho_upper
            sensor.switch_on_off = switch_on_off
            sensor.temp_upper = temp_upper
            sensor.temp_lower = temp_lower
            sensor.humidity_upper = humidity_upper
            sensor.humidity_lower = humidity_lower
            sensor.pm25_upper = pm25_upper
            sensor.pm25_lower = pm25_lower
            sensor.co2_upper = co2_upper
            sensor.co2_lower = co2_lower
            sensor.voc_lower = voc_lower
            sensor.connected = connected
            sensor.sleep_mode_count = sleep_mode_count
            self._sensors.append(sensor)
            count = count - 1

    def do(self):
        from .service import Service
        Service.set_sensors_status(self._sensors)

    @property
    def count(self):
        return self._count

    @property
    def mode(self):
        return self._mode

    @property
    def room_id(self):
        return self._room_id

    @property
    def sensor_type(self):
        return self._sensor_type

    @property
    def sensors(self):
        return self._sensors

class CmdRspResult(BaseResult):
    def __init__(self, cmd_id: int, target: EnumDevice):
        BaseResult.__init__(self, cmd_id, target, EnumCmdType.SYS_CMD_RSP)
        self._cmdId = None
        self._code = None

    def load_bytes(self, b):
        self._cmdId, self._code = struct.unpack('<IB', b)

    @property
    def cmd_id(self):
        return self._cmdId

    @property
    def code(self):
        return self._code

class TimeSyncResult(BaseResult):
    def __init__(self, cmd_id: int, target: EnumDevice):
        BaseResult.__init__(self, cmd_id, target, EnumCmdType.SYS_TIME_SYNC)
        self._time = None

    def load_bytes(self, b):
        self._time = struct.unpack('<I', b)[0]

    @property
    def time(self):
        return self._time

class ErrCodeResult(BaseResult):
    def __init__(self, cmd_id: int, target: EnumDevice):
        BaseResult.__init__(self, cmd_id, target, EnumCmdType.SYS_ERR_CODE)
        self._code = None
        self._device = None
        self._room = None
        self._unit = None

    def load_bytes(self, b):
        dev_id, room, unit = struct.unpack('<iBB', b[:6])
        self._device = EnumDevice((8, dev_id))
        self._room = room
        self._unit = unit
        self._code = b[6:].decode('ASCII')

    @property
    def code(self):
        return self._code

    @property
    def device(self):
        return self._device

    @property
    def room(self):
        return self._room

    @property
    def unit(self):
        return self._unit

class GetWeatherResult(BaseResult):
    def __init__(self, cmd_id: int, target: EnumDevice):
        BaseResult.__init__(self, cmd_id, target, EnumCmdType.SYS_GET_WEATHER)
        self._condition = None
        self._humidity = None
        self._temp = None
        self._wind_dire = None
        self._wind_speed = None

    def load_bytes(self, b):
        self._condition, self._humidity, self._temp, self._wind_dire, self._wind_speed \
            = struct.unpack('<BBHBB', b)

    @property
    def condition(self):
        return self._condition

    @property
    def humidity(self):
        return self._humidity

    @property
    def temp(self):
        return self._temp

    @property
    def wind_dire(self):
        return self._wind_dire

    @property
    def wind_speed(self):
        return self._wind_speed

class LoginResult(BaseResult):
    def __init__(self, cmd_id: int, target: EnumDevice):
        BaseResult.__init__(self, cmd_id, target, EnumCmdType.SYS_LOGIN)
        self._status = None

    def load_bytes(self, b):
        self._status = struct.unpack('<BB', b)[1]

    @property
    def status(self):
        return self._status

class ChangePWResult(BaseResult):
    def __init__(self, cmd_id: int, target: EnumDevice):
        BaseResult.__init__(self, cmd_id, target, EnumCmdType.SYS_CHANGE_PW)
        self._status = None

    def load_bytes(self, b):
        self._status = struct.unpack('<B', b)[0]

    @property
    def status(self):
        return self._status

class GetRoomInfoResult(BaseResult):
    def __init__(self, cmd_id: int, target: EnumDevice):
        BaseResult.__init__(self, cmd_id, target, EnumCmdType.SYS_GET_ROOM_INFO)
        self._count: int = 0
        self._hds: typing.List[HD] = []
        self._sensors: typing.List[Sensor] = []
        self._rooms: typing.List[Room] = []

    def load_bytes(self, b):
        ver_flag = 1
        d = Decode(b)
        self._count = d.read2()
        room_count = d.read1()
        for i in range(room_count):
            room = Room()
            room.id = d.read2()
            if self.subbody_ver == 1:
                ver_flag = d.read1()
            if ver_flag != 2:
                length = d.read1()
                room.name = d.read_utf(length)
                length = d.read1()
                room.alias = d.read_utf(length)
                length = d.read1()
                room.icon = d.read_utf(length)
            unit_count = d.read2()
            for j in range(unit_count):
                device = EnumDevice((8, d.read4()))
                device_count = d.read2()
                for unit_id in range(device_count):
                    if EnumDevice.AIRCON == device or EnumDevice.NEWAIRCON == device or EnumDevice.BATHROOM == device:
                        dev = AirCon()
                        room.air_con = dev
                        dev.new_air_con = EnumDevice.NEWAIRCON == device
                        dev.bath_room = EnumDevice.BATHROOM == device
                    elif EnumDevice.GEOTHERMIC == device:
                        dev = Geothermic()
                        room.geothermic = dev
                    elif EnumDevice.HD == device:
                        dev = HD()
                        self.hds.append(dev)
                        room.hd_room = True
                        room.hd = dev
                    elif EnumDevice.SENSOR == device:
                        dev = Sensor()
                        self.sensors.append(dev)
                        room.sensor_room = True
                    elif EnumDevice.VENTILATION == device or EnumDevice.SMALL_VAM == device:
                        dev = Ventilation()
                        room.ventilation = dev
                        dev.is_small_vam = EnumDevice.SMALL_VAM == device
                    else:
                        dev = Device()
                    dev.room_id = room.id
                    dev.unit_id = unit_id
                    if ver_flag > 2:
                        length = d.read1()
                        dev.name = d.read_utf(length)
                        length = d.read1()
                        dev.alias = d.read_utf(length)
                        if dev.alias is None:
                            dev.alias = room.alias
            self.rooms.append(room)

    def do(self):
        from .service import Service
        Service.set_rooms(self.rooms)
        Service.send_msg(AirConRecommendedIndoorTempParam())
        Service.set_sensors(self.sensors)

        aircons = []
        new_aircons = []
        bathrooms = []
        for room in Service.get_rooms():
            if room.air_con is not None:
                room.air_con.alias = room.alias
                if room.air_con.new_air_con:
                    new_aircons.append(room.air_con)
                elif room.air_con.bath_room:
                    bathrooms.append(room.air_con)
                else:
                    aircons.append(room.air_con)

        p = AirConCapabilityQueryParam()
        p.aircons = aircons
        p.target = EnumDevice.AIRCON
        Service.send_msg(p)
        p = AirConCapabilityQueryParam()
        p.aircons = new_aircons
        p.target = EnumDevice.NEWAIRCON
        Service.send_msg(p)
        p = AirConCapabilityQueryParam()
        p.aircons = bathrooms
        p.target = EnumDevice.BATHROOM
        Service.send_msg(p)

    @property
    def count(self):
        return self._count

    @property
    def hds(self):
        return self._hds

    @property
    def rooms(self):
        return self._rooms

    @property
    def sensors(self):
        return self._sensors

class QueryScheduleSettingResult(BaseResult):
    def __init__(self, cmd_id: int, target: EnumDevice):
        BaseResult.__init__(self, cmd_id, target, EnumCmdType.SYS_QUERY_SCHEDULE_SETTING)

    def load_bytes(self, b):
        """todo"""

class QueryScheduleIDResult(BaseResult):
    def __init__(self, cmd_id: int, target: EnumDevice):
        BaseResult.__init__(self, cmd_id, target, EnumCmdType.SYS_QUERY_SCHEDULE_ID)

    def load_bytes(self, b):
        """todo"""

class HandShakeResult(BaseResult):
    def __init__(self, cmd_id: int, target: EnumDevice):
        BaseResult.__init__(self, cmd_id, target, EnumCmdType.SYS_HAND_SHAKE)
        self._time: str = ''

    def load_bytes(self, b):
        d = Decode(b)
        self._time = d.read_utf(14)

    def do(self):
        p = GetRoomInfoParam()
        p.room_ids.append(0xffff)
        from .service import Service
        Service.send_msg(p)
        Service.send_msg(Sensor2InfoParam())

class GetGWInfoResult(BaseResult):
    def __init__(self, cmd_id: int, target: EnumDevice):
        BaseResult.__init__(self, cmd_id, target, EnumCmdType.SYS_HAND_SHAKE)
        self._time: str = ''

    def load_bytes(self, b):
        """todo"""

    def do(self):
        """todo"""

class CmdTransferResult(BaseResult):
    def __init__(self, cmd_id: int, target: EnumDevice):
        BaseResult.__init__(self, cmd_id, target, EnumCmdType.SYS_CMD_TRANSFER)

    def load_bytes(self, b):
        """todo"""

class QueryScheduleFinish(BaseResult):
    def __init__(self, cmd_id: int, target: EnumDevice):
        BaseResult.__init__(self, cmd_id, target, EnumCmdType.SYS_QUERY_SCHEDULE_FINISH)

    def load_bytes(self, b):
        """todo"""

class AirConStatusChangedResult(BaseResult):
    def __init__(self, cmd_id: int, target: EnumDevice):
        BaseResult.__init__(self, cmd_id, target, EnumCmdType.STATUS_CHANGED)
        self._room = 0  # type: int
        self._unit = 0  # type: int
        self._status = AirConStatus()  # type: AirConStatus

    def load_bytes(self, b):
        d = Decode(b)
        self._room = d.read1()
        self._unit = d.read1()
        status = self._status
        flag = d.read1()
        if flag & EnumControl.Type.SWITCH:
            status.switch = EnumControl.Switch(d.read1())
        if flag & EnumControl.Type.MODE:
            status.mode = EnumControl.Mode(d.read1())
        if flag & EnumControl.Type.AIR_FLOW:
            status.air_flow = EnumControl.AirFlow(d.read1())
        if flag & EnumControl.Type.CURRENT_TEMP:
            status.current_temp = d.read2()
        if flag & EnumControl.Type.SETTED_TEMP:
            status.setted_temp = d.read2()
        if Config.is_new_version:
            if flag & EnumControl.Type.FAN_DIRECTION:
                direction = d.read1()
                status.fan_direction1 = EnumControl.FanDirection(direction & 0xF)
                status.fan_direction2 = EnumControl.FanDirection((direction >> 4) & 0xF)

    def do(self):
        from .service import Service
        Service.update_aircon(self.target, self._room, self._unit, status=self._status)

class AirConQueryStatusResult(BaseResult):
    def __init__(self, cmd_id: int, target: EnumDevice):
        BaseResult.__init__(self, cmd_id, target, EnumCmdType.QUERY_STATUS)
        self.unit = 0
        self.room = 0
        self.current_temp = 0
        self.setted_temp = 0
        self.switch = EnumControl.Switch.OFF
        self.air_flow = EnumControl.AirFlow.AUTO
        self.breathe = EnumControl.Breathe.CLOSE
        self.fan_direction1 = EnumControl.FanDirection.INVALID
        self.fan_direction2 = EnumControl.FanDirection.INVALID
        self.humidity = EnumControl.Humidity.CLOSE
        self.mode = EnumControl.Mode.AUTO
        self.hum_allow = False
        self.fresh_air_allow = False
        self.fresh_air_humidification = FreshAirHumidification.OFF
        self.three_d_fresh = ThreeDFresh.CLOSE

    def load_bytes(self, b):
        d = Decode(b)
        self.room = d.read1()
        self.unit = d.read1()
        flag = d.read1()
        if flag & 1:
            self.switch = EnumControl.Switch(d.read1())
        if flag >> 1 & 1:
            self.mode = EnumControl.Mode(d.read1())
        if flag >> 2 & 1:
            self.air_flow = EnumControl.AirFlow(d.read1())
        if Config.is_c611:
            if flag >> 3 & 1:
                bt = d.read1()
                self.hum_allow = bt & 8 == 8
                self.fresh_air_allow = bt & 4 == 4
                self.fresh_air_humidification = FreshAirHumidification(bt & 3)

            if flag >> 4 & 1:
                self.setted_temp = d.read2()
            if Config.is_new_version:
                if flag >> 5 & 1:
                    b = d.read1()
                    self.fan_direction1 = EnumControl.FanDirection(b & 0xf)
                    self.fan_direction2 = EnumControl.FanDirection(b >> 4 & 0xf)
                if flag >> 6 & 1:
                    self.humidity = EnumControl.Humidity(d.read1())
                if self.target == EnumDevice.BATHROOM:
                    if flag >> 7 & 1:
                        self.breathe = EnumControl.Breathe(d.read1())
                elif self.target == EnumDevice.AIRCON:
                    if flag >> 7 & 1 == 1:
                        self.three_d_fresh = ThreeDFresh(d.read1())
        else:
            if flag >> 3 & 1:
                self.current_temp = d.read2()
            if flag >> 4 & 1:
                self.setted_temp = d.read2()
            if Config.is_new_version:
                if flag >> 5 & 1:
                    b = d.read1()
                    self.fan_direction1 = EnumControl.FanDirection(b & 0xf)
                    self.fan_direction2 = EnumControl.FanDirection(b >> 4 & 0xf)
                if self.target == EnumDevice.NEWAIRCON:
                    if flag >> 6 & 1:
                        self.humidity = EnumControl.Humidity(d.read1())
                else:
                    if flag >> 7 & 1:
                        self.breathe = EnumControl.Breathe(d.read1())

    def do(self):
        from .service import Service
        status = AirConStatus(self.current_temp, self.setted_temp, self.switch, self.air_flow, self.breathe,
                              self.fan_direction1, self.fan_direction2, self.humidity, self.mode)
        Service.set_aircon_status(self.target, self.room, self.unit, status)

class AirConRecommendedIndoorTempResult(BaseResult):
    def __init__(self, cmd_id: int, target: EnumDevice):
        BaseResult.__init__(self, cmd_id, target, EnumCmdType.AIR_RECOMMENDED_INDOOR_TEMP)
        self._temp: int = 0
        self._outdoor_temp: int = 0

    def load_bytes(self, b):
        d = Decode(b)
        self._temp = d.read2()
        self._outdoor_temp = d.read2()

    @property
    def temp(self):
        return self._temp

    @property
    def outdoor_temp(self):
        return self._outdoor_temp

class AirConCapabilityQueryResult(BaseResult):
    def __init__(self, cmd_id: int, target: EnumDevice):
        BaseResult.__init__(self, cmd_id, target, EnumCmdType.AIR_CAPABILITY_QUERY)
        self._air_cons: typing.List[AirCon] = []

    def load_bytes(self, b):
        d = Decode(b)
        room_size = d.read1()
        for i in range(room_size):
            room_id = d.read1()
            unit_size = d.read1()
            for j in range(unit_size):
                aircon = AirCon()
                aircon.unit_id = d.read1()
                aircon.room_id = room_id
                aircon.new_air_con = self.target == EnumDevice.NEWAIRCON
                aircon.bath_room = self.target == EnumDevice.BATHROOM
                flag = d.read1()
                aircon.fan_volume = EnumFanVolume(flag >> 5 & 0x7)
                aircon.dry_mode = flag >> 4 & 1
                aircon.auto_mode = flag >> 3 & 1
                aircon.heat_mode = flag >> 2 & 1
                aircon.cool_mode = flag >> 1 & 1
                aircon.ventilation_mode = flag & 1
                if Config.is_new_version:
                    flag = d.read1()
                    if flag & 1:
                        aircon.fan_direction1 = EnumFanDirection.STEP_5
                    else:
                        aircon.fan_direction1 = EnumFanDirection.FIX

                    if flag >> 1 & 1:
                        aircon.fan_direction2 = EnumFanDirection.STEP_5
                    else:
                        aircon.fan_direction2 = EnumFanDirection.FIX

                    aircon.fan_dire_auto = flag >> 2 & 1
                    aircon.fan_volume_auto = flag >> 3 & 1
                    aircon.temp_set = flag >> 4 & 1
                    aircon.hum_fresh_air_allow = (flag >> 5 & 1) & (flag >> 6 & 1)
                    aircon.three_d_fresh_allow = flag >> 7 & 1

                    flag = d.read1()
                    aircon.out_door_run_cond = EnumOutDoorRunCond(flag >> 6 & 3)
                    aircon.more_dry_mode = flag >> 4 & 1
                    aircon.pre_heat_mode = flag >> 3 & 1
                    aircon.auto_dry_mode = flag >> 2 & 1
                    aircon.relax_mode = flag >> 1 & 1
                    aircon.sleep_mode = flag & 1
                else:
                    d.read1()
                self._air_cons.append(aircon)

    def do(self):
        from .service import Service
        if Service.is_ready():
            if len(self._air_cons):
                for i in self._air_cons:
                    Service.update_aircon(get_device_by_aircon(i), i.room_id, i.unit_id, aircon=i)
        else:
            for i in self._air_cons:
                p = AirConQueryStatusParam()
                p.target = self.target
                p.device = i
                from .service import Service
                Service.send_msg(p)
            Service.set_device(self.target, self._air_cons)

    @property
    def aircons(self):
        return self._air_cons

class AirConQueryScenarioSettingResult(BaseResult):
    def __init__(self, cmd_id: int, target: EnumDevice):
        BaseResult.__init__(self, cmd_id, target, EnumCmdType.QUERY_SCENARIO_SETTING)

    def load_bytes(self, b):
        """todo"""

class UnknownResult(BaseResult):
    def __init__(self, cmd_id: int, target: EnumDevice, cmd_type: EnumCmdType):
        BaseResult.__init__(self, cmd_id, target, cmd_type)
        self._subbody = ''

    def load_bytes(self, b):
        self._subbody = struct.pack('<' + str(len(b)) + 's', b).hex()

    @property
    def subbody(self):
        return self._subbody