#!/usr/bin/env python
# -*- coding:utf-8 -*-
import os
import gensim
import pickle
import pandas as pd
from conf.paths import MODEL_HOME, RESOURCE_HOME
from conf.paths import corpus_path, dictionary_path, df_tokens_path
from conf.config import all_models
from libs.segment import tokenizer
from model.tfidf import TF_IDF
from model.lsi import LSI
from model.word2vec import Word2Vector
from model.doc2vec import Doc2Vector
from libs.wrapper import costime
from libs.logger import get_logger

logger = get_logger(_file_=__file__)
original_csv = os.path.join(RESOURCE_HOME, "accountant_qa_dataset.csv")    #

class IQAMode(object):
    def __init__(self, mode, tokenize=None):
        self.mode = mode
        logger.debug("running mode is: %s" % self.mode)
        self.tokenize = lambda x: tokenizer.cut(x, pregex=True) if tokenize is None else tokenize
        self.models = dict()

    def train(self):
        if not os.path.exists(MODEL_HOME):
            os.makedirs(MODEL_HOME)
        # load original data
        if os.path.exists(original_csv):
            df = pd.read_csv(original_csv, header=None, names=["id", "question", "answer"])
            logger.debug("load dataframe: '%s', size: %d" % (original_csv, df.shape[0]))
            df = df[["id", "question"]].drop_duplicates().reset_index(drop=True)
            logger.debug("after drop duplicates, size: %d" % df.shape[0])
            df["tokens"] = df["question"].map(lambda x: tokenizer.cut(x, pregex=True))
        else:
            logger.debug("load dataframe: '%s'" % df_tokens_path)
            df = pd.read_csv(df_tokens_path, index_col=0)
            df["tokens"] = df["tokens"].map(lambda x: str(x).split())
        # build dictionary/corpus
        dictionary = gensim.corpora.Dictionary(df["tokens"])
        corpus = [dictionary.doc2bow(tokens) for tokens in df["tokens"]]
        logger.debug("build dictionary and corpus. dictionary size: %d" % (len(dictionary.token2id)))

        # build models
        self.models = build_models(df, dictionary, corpus, model="all")
        if self.mode == "train":
            self.check_model(*all_models)
        # dump df/dictionary/corpus/models
        dump(dictionary=dictionary, corpus=corpus, dataframe=df, models=self.models)
        #
        return df, dictionary, corpus

    @costime("test mode", msg="running total")
    def test(self):
        if not os.path.exists(MODEL_HOME) or len(os.listdir(MODEL_HOME)) <= 0:
            df, dictionary, corpus = self.train()
        else:
            df, dictionary, corpus = load_corpus()
            # build model if it not existed
        if len(self.models) == 0:
            self.models = build_models(df, dictionary, corpus, model="all", load=True)
        self.check_model(*all_models)

    def check_model(self, *args):
        question = "KTV开发票明细能不能开服务费？"
        que_tokens = tokenizer.cut(question)
        logger.debug(question)
        logger.debug(" ".join(que_tokens))
        for name in args:
            model = self.models.get(name)
            logger.debug("%s %s %s" % ("="*20, name.upper(), "="*20))
            logger.debug(model.nearest(que_tokens) if model is not None else "None")

def _check_model_name(mod_names):
    _model = set()
    mod_names = [mod_names, ] if isinstance(mod_names, str) else list(mod_names)
    for name in mod_names:
        if name == "all":
            return all_models
        if name not in all_models:
            logger.info("'%s' model not existed" % name)
        else:
            _model.add(name)
    return list(_model)

def load_corpus():
    # load dataframe from csv
    logger.debug("load dataframe: '%s'" % df_tokens_path)
    df = pd.read_csv(df_tokens_path, index_col=0)
    df["tokens"] = df["tokens"].map(lambda x: str(x).split())
    # load dictionary/corpus
    logger.debug("load dictionary: '%s'" % dictionary_path)
    with open(dictionary_path, "rb") as fopen:
        dictionary = pickle.load(fopen)
    logger.debug("load corpus: '%s'" % corpus_path)
    corpus = gensim.corpora.MmCorpus(corpus_path)
    return df, dictionary, corpus

def build_models(dataframe, dictionary, corpus, model="all", load=False):
    models = dict()
    model_names = _check_model_name(model)
    for name in model_names:
        if name == "tfidf":
            models[name] = TF_IDF(dictionary, corpus, dataframe=dataframe, load=load)
        elif name == "lsi":
            models[name] = LSI(dictionary, corpus, dataframe=dataframe, load=load)
        elif name == "word2vec":
            models[name] = Word2Vector(dataframe=dataframe, load=load)
        elif name == "doc2vec":
            models[name] = Doc2Vector(dataframe=dataframe, load=load)
    return models

def dump(dictionary=None, corpus=None, dataframe=None, models=None):
    if dictionary is not None:
        logger.debug("dump dictionary to '%s'" % dictionary_path)
        with open(dictionary_path, "wb") as fopen:
            pickle.dump(dictionary, fopen)
    if corpus is not None:
        logger.debug("dump corpus to '%s'" % corpus_path)
        gensim.corpora.MmCorpus.serialize(corpus_path, corpus)
    if dataframe is not None:
        logger.debug("write dataframe to '%s'" % df_tokens_path)
        dataframe["tokens"] = dataframe["tokens"].map(lambda x: " ".join(x))
        dataframe.to_csv(df_tokens_path)
    if models is not None:
        for name in models:
            if models.get(name) is not None:
                models[name].dump()


def get_fake_env(name=None, status=None, release_id=None,
                 fuel_version=None, pending_release=None, env_id=None):
    """Create a random fake environment

    Returns the serialized and parametrized representation of a dumped Fuel
    environment. Represents the average amount of data.

    """
    return {'status': status or 'new',
            'is_customized': False,
            'release_id': release_id or 2,
            'name': name or 'fake_env',
            'fuel_version': fuel_version or '9.0',
            'pending_release_id': pending_release,
            'id': env_id or 1,
            'changes': []}


# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    curSum = 0
    def traverse(self, root):
        if not root: return 0

        self.traverse(root.right)

        self.curSum += root.val
        root.val = self.curSum

        self.traverse(root.left)

    def bstToGst(self, root: TreeNode) -> TreeNode:
        self.traverse(root)
        return root


# W - weight, P - price, B - max weight
# constant version
# greedy

def knapsack(W: list, P: list, B: int) -> int:
    total = 0

    H = []
    for w, p in zip(W, P):
        H.append((p / w, w))
    H.sort(key=lambda x: x[0], reverse=True)

    print(H)
    i = 0
    while B > 0 and i < len(H):
        p, w = H[i]
        total += p * min(B, w)
        B -= min(B,w)
        i += 1

    return total

W = [3, 4, 6, 5]
P = [2, 3, 1, 4]
B = 8

print(knapsack(W, P, B))


"""
strings aka char arrays

Strings are recursive data structures
"""

def immutable():
    # strings are immutable in python
    s = "abcdef"
    s[0] = 'g' # raises error 'str' object does not support item assignment

    # to change it just make it into list then convert back to str
    l = list(s)
    l[0] = 'g'
    s = "".join(l)
    s # 'gbcdef'


import traceback

import numpy as np
import pandas as pd
import pyfirmata2 as fmt
import serial
import usb.core
import usb.util

from miniPoly.compiler.prototypes import AbstractCompiler, StreamingCompiler

class PololuServoInterface(StreamingCompiler):
    MOUSE_SERVO_DISTANCE = 150 # distance between the mouse and the servo in mm
    ARM0_LENGTH = 40 # length of the first arm in mm
    ARM1_LENGTH = 90 # length of the second arm in mm
    EXTENDED_LENGTH = 100

    @staticmethod
    def servo_angle_solver(target_azi, target_r):
        # the inputs and outputs are both in degrees
        target_azi *= np.pi / 180
        servo_azi = np.pi/2 - np.arctan(np.cos(target_azi) / (PololuServoInterface.MOUSE_SERVO_DISTANCE / target_r + np.sin(target_azi)))
        total_length = (PololuServoInterface.MOUSE_SERVO_DISTANCE + target_r * np.sin(target_azi)) / np.sin(servo_azi) - PololuServoInterface.EXTENDED_LENGTH
        servo_r = np.arccos((PololuServoInterface.ARM0_LENGTH ** 2 + total_length ** 2 - PololuServoInterface.ARM1_LENGTH ** 2) / (2 * PololuServoInterface.ARM0_LENGTH * total_length)) - np.pi/2
        return servo_azi, servo_r

    def __init__(self, *args, port_name='COM6', servo_dict={}, **kwargs):
        super(PololuServoInterface, self).__init__(*args, **kwargs)
        self._port = None
        self._port_name = port_name
        self.servo_dict = servo_dict
        self.servo_param = {}

        self.streaming = False
        self._AUX_FileHandle = None
        self._AUX_writer = None
        self._stream_init_time = None

        self.target_azi = None
        self.target_r = None

        self._azi = 0.5
        self._r = 0.5

        self.init_pololu()
        # for i in range(24):
        #     self.setRange(i, 2500, 10000)
        self._watching_state = {}
        for n, v in self.servo_dict.items():
            try:
                self.create_streaming_state(n, -1, shared=True)
                self.servo_param[n] = [v[1], v[2]]
                self.servo_dict[n] = v[0]
            except:
                print(traceback.format_exc())
        # self.create_state('StreamToDisk', False)
        # self.create_state('SaveDir', False)
        # self.create_state('SaveName', False)
        # self.create_state('InitTime', False)

    def on_time(self, t):
        # yaw = self.getPosition(self.servo_dict['yaw'])
        # radius = self.getPosition(self.servo_dict['radius'])
        # print(f"Yaw: {yaw}, Radius: {radius}")
        should_update = False
        for n, v in self.servo_dict.items():
            state = self.get_state(n)
            if self.watch_state(n, state) and state is not None:
                if n == 'yaw':
                    self.target_azi = state
                    if self.target_r is not None:
                        should_update = True
                elif n == 'radius':
                    self.target_r = state
                    if self.target_azi is not None:
                        should_update = True
                else:
                    iter_min, iter_max = self.servo_param[n][0], self.servo_param[n][1]
                    new_pos = int(state*(iter_max-iter_min) + iter_min)
                    self.setTarget(v, new_pos)

        if should_update:
            azi, radius = self.servo_angle_solver(self.target_azi, self.target_r)
            azi = azi/np.pi
            radius = .5+radius/np.pi
            print(f'Azimuth: {azi}, radius: {radius}')
            # azi, radius = self.target_azi, self.target_r
            yaw_min, yaw_max = self.servo_param['yaw'][0], self.servo_param['yaw'][1]
            radius_min, radius_max = self.servo_param['radius'][0], self.servo_param['radius'][1]
            self._azi = int(yaw_min + azi*(yaw_max-yaw_min))
            self._r = int(radius_min + radius*(radius_max-radius_min))
        self.setTarget(self.servo_dict['yaw'], self._azi)
        self.setTarget(self.servo_dict['radius'], self._r)

        super().on_time(t)

    def on_close(self):
        self._port.close()
        self.set_state('status', -1)

    ###### The following are copied from https://github.com/FRC4564/Maestro/blob/master/maestro.py with MIT license
    def init_pololu(self):
        self._port = serial.Serial(self._port_name)
        # Command lead-in and device number are sent for each Pololu serial command.
        self.PololuCmd = chr(0xaa) + chr(0x0c)
        # Track target position for each servo. The function isMoving() will
        # use the Target vs Current servo position to determine if movement is
        # occuring.  Upto 24 servos on a Maestro, (0-23). Targets start at 0.
        self.Targets = [0] * 24
        # Servo minimum and maximum targets can be restricted to protect components.
        self.Mins = [0] * 24
        self.Maxs = [0] * 24

        # Cleanup by closing USB serial port

    def sendCmd(self, cmd):
        cmdStr = self.PololuCmd + cmd
        self._port.write(bytes(cmdStr, 'latin-1'))

        # Set channels min and max value range.  Use this as a safety to protect
        # from accidentally moving outside known safe parameters. A setting of 0
        # allows unrestricted movement.
        #
        # ***Note that the Maestro itself is configured to limit the range of servo travel
        # which has precedence over these values.  Use the Maestro Control Center to configure
        # ranges that are saved to the controller.  Use setRange for software controllable ranges.

    def setRange(self, chan, min, max):
        self.Mins[chan] = min
        self.Maxs[chan] = max

        # Return Minimum channel range value

    def getMin(self, chan):
        return self.Mins[chan]

        # Return Maximum channel range value

    def getMax(self, chan):
        return self.Maxs[chan]

        # Set channel to a specified target value.  Servo will begin moving based
        # on Speed and Acceleration parameters previously set.
        # Target values will be constrained within Min and Max range, if set.
        # For servos, target represents the pulse width in of quarter-microseconds
        # Servo center is at 1500 microseconds, or 6000 quarter-microseconds
        # Typcially valid servo range is 3000 to 9000 quarter-microseconds
        # If channel is configured for digital output, values < 6000 = Low ouput

    def setTarget(self, chan, target):
        # if Min is defined and Target is below, force to Min
        if self.Mins[chan] > 0 and target < self.Mins[chan]:
            target = self.Mins[chan]
        # if Max is defined and Target is above, force to Max
        if self.Maxs[chan] > 0 and target > self.Maxs[chan]:
            target = self.Maxs[chan]
        #
        lsb = target & 0x7f  # 7 bits for least significant byte
        msb = (target >> 7) & 0x7f  # shift 7 and take next 7 bits for msb
        cmd = chr(0x04) + chr(chan) + chr(lsb) + chr(msb)
        self.sendCmd(cmd)
        # Record Target value
        self.Targets[chan] = target

        # Set speed of channel
        # Speed is measured as 0.25microseconds/10milliseconds
        # For the standard 1ms pulse width change to move a servo between extremes, a speed
        # of 1 will take 1 minute, and a speed of 60 would take 1 second.
        # Speed of 0 is unrestricted.

    def setSpeed(self, chan, speed):
        lsb = speed & 0x7f  # 7 bits for least significant byte
        msb = (speed >> 7) & 0x7f  # shift 7 and take next 7 bits for msb
        cmd = chr(0x07) + chr(chan) + chr(lsb) + chr(msb)
        self.sendCmd(cmd)

        # Set acceleration of channel
        # This provides soft starts and finishes when servo moves to target position.
        # Valid values are from 0 to 255. 0=unrestricted, 1 is slowest start.
        # A value of 1 will take the servo about 3s to move between 1ms to 2ms range.

    def setAccel(self, chan, accel):
        lsb = accel & 0x7f  # 7 bits for least significant byte
        msb = (accel >> 7) & 0x7f  # shift 7 and take next 7 bits for msb
        cmd = chr(0x09) + chr(chan) + chr(lsb) + chr(msb)
        self.sendCmd(cmd)

        # Get the current position of the device on the specified channel
        # The result is returned in a measure of quarter-microseconds, which mirrors
        # the Target parameter of setTarget.
        # This is not reading the true servo position, but the last target position sent
        # to the servo. If the Speed is set to below the top speed of the servo, then
        # the position result will align well with the acutal servo position, assuming
        # it is not stalled or slowed.

    def getPosition(self, chan):
        cmd = chr(0x10) + chr(chan)
        self.sendCmd(cmd)
        lsb = ord(self._port.read())
        msb = ord(self._port.read())
        return (msb << 8) + lsb

        # Test to see if a servo has reached the set target position.  This only provides
        # useful results if the Speed parameter is set slower than the maximum speed of
        # the servo.  Servo range must be defined first using setRange. See setRange comment.
        #
        # ***Note if target position goes outside of Maestro's allowable range for the
        # channel, then the target can never be reached, so it will appear to always be
        # moving to the target.

    def isMoving(self, chan):
        if self.Targets[chan] > 0:
            if self.getPosition(chan) != self.Targets[chan]:
                return True
        return False

        # Have all servo outputs reached their targets? This is useful only if Speed and/or
        # Acceleration have been set on one or more of the channels. Returns True or False.
        # Not available with Micro Maestro.

    def getMovingState(self):
        cmd = chr(0x13)
        self.sendCmd(cmd)
        if self._port.read() == chr(0):
            return False
        else:
            return True

        # Run a Maestro Script subroutine in the currently active script. Scripts can
        # have multiple subroutines, which get numbered sequentially from 0 on up. Code your
        # Maestro subroutine to either infinitely loop, or just end (return is not valid).

    def runScriptSub(self, subNumber):
        cmd = chr(0x27) + chr(subNumber)
        # can pass a param with command 0x28
        # cmd = chr(0x28) + chr(subNumber) + chr(lsb) + chr(msb)
        self.sendCmd(cmd)

        # Stop the current Maestro Script

    def stopScript(self):
        cmd = chr(0x24)
        self.sendCmd(cmd)

    #############################################################################################

class SerialCommandCompiler(StreamingCompiler):

    def __init__(self, *args, port_name='COM7', baud=9600, timeout=0.001, **kwargs):
        super(SerialCommandCompiler, self).__init__(*args, **kwargs)
        self._port_name = port_name
        self._baud = baud
        self._timeout = timeout
        self._port = None

        self._port = serial.Serial(self._port_name, self._baud, timeout=self._timeout)

    def on_time(self, t):
        super().on_time(t)

class MotorShieldCompiler(SerialCommandCompiler):
    RADIUS_SERVO_MIN = 15
    MASK_OFF_ANGLE = [0, 180]
    MASK_ON_ANGLE = [170, 15]

    def __init__(self, processHandler, motor_dict={}, **kwargs):
        super(MotorShieldCompiler, self).__init__(processHandler, **kwargs)
        self._motor_dict = motor_dict
        for k in self._motor_dict.keys():
            self.create_streaming_state(k, 0, shared=False,use_buffer=False)

        self._mask_status = np.array([False, False])

        self.watch_state('runSignal', False)
        self._running_protocol = False

        self.create_streaming_state('protocolFn', '', shared=False, use_buffer=False)
        self.watch_state('protocolFn', '')

        # The following shared state are for debugging
        self.create_state('serial_cmd', '')
        self.watch_state('serial_cmd', '')

        self.watch_state('cmd_idx',-1)
        self.create_streaming_state('cmd_idx', -1, shared=True, use_buffer=True)
        self._protocolFn = ''
        self._protocol = None
        self._protocol_start_time = None
        self._time_index_col = None
        self._cmd_idx_lookup_table = None
        self._running_time = 0

        self._stepper_counter = 0

    def on_time(self,t):
        self.get_protocol_fn()
        running = self.get_run_signal()
        if running:
            self._run_protocol()
        else:
            if self._protocol_start_time is not None:
                self._end_protocol()
            else:
                serial_cmd = self.get_state('serial_cmd')
                if self.watch_state('serial_cmd', serial_cmd):
                    self._port.write(serial_cmd.encode())
                    self.info(f"Execute serial cmd: {self.get_state('serial_cmd')}")

        super().on_time(t)

    def reset_servo_status(self):
        pass

    def get_protocol_fn(self):
        if self._protocol_start_time is None:  # Only execute if protocol is not running
            protocolFn = self.get_state_from(self._trigger_minion,'protocolFn')
            if self.watch_state('protocolFn', protocolFn) and protocolFn not in ['', None]:
                self.info(f"Loading protocol from {protocolFn}")
                self._protocol = pd.read_excel(protocolFn)
                self._protocolFn = protocolFn
                self._time_index_col = self._protocol['time'].to_numpy()
                self._cmd_idx_lookup_table = {k: [self._motor_dict[k],i] for i, k in enumerate(self._protocol.columns) if k in self._motor_dict.keys()}

    def get_run_signal(self):
        if self._protocolFn is not None:  # Only execute if protocol is loaded
            runSignal = self.get_state_from(self._trigger_minion,'runSignal')
            if self.watch_state('runSignal', runSignal):
                self._running_protocol = runSignal
                if self._running_protocol:
                    self._start_protocol()
                    return True
                else:  # if self._running_protocol has been switched off, return False to stop protocal running and reset related params
                    self._end_protocol()
                    return False
            else:
                return self._running_protocol
        else:
            return False

    def _start_protocol(self):
        self.info('Starting protocol')
        self.set_streaming_state('protocolFn', self._protocolFn)
        self._protocol_start_time = self.get_timestamp()
        self.set_streaming_state('cmd_idx', 0)
        self.reset_servo_status()

    def _run_protocol(self):
        self._running_time = self.get_timestamp() - self._protocol_start_time
        cmd_idx = sum(self._running_time >= self._time_index_col) - 1
        if self.watch_state('cmd_idx', cmd_idx):
            for k, v in self._cmd_idx_lookup_table.items():
                if 'servo' in k:
                    # write serial command to set servo position
                    target_pos = int(self._protocol.iloc[cmd_idx, v[1]])
                    self.set_servo_motor_pos(k, v, target_pos)
                elif 'stepper' in k:
                    target_pos = self._protocol.iloc[cmd_idx, v[1]]
                    self.set_stepper_motor_pos(k, v, target_pos)
                elif 'pin' in k:
                    pin_num = v[0]
                    pin_val = self._protocol.iloc[cmd_idx, v[1]]
                    if pin_num < 10:
                        self._port.write(f'pin0{pin_num}{pin_val}\n'.encode())
                    else:
                        self._port.write(f'pin{pin_num}{pin_val}\n'.encode())
                    self.set_streaming_state(k, pin_val)

            self.set_streaming_state('cmd_idx', cmd_idx)
            if cmd_idx >= len(self._time_index_col) - 1:
                self._end_protocol()

    def _end_protocol(self):
        if self._cmd_idx_lookup_table is not None:
            pin_param = []
            flag_param = []
            servo_param = []
            stepper_param = []
            mask_param = []
            for k, v in self._cmd_idx_lookup_table.items():
                if 'servo' in k:
                    # write serial command to set servo position
                    if 'flag' in k:
                        flag_param = [k,v,180]
                    else:
                        servo_param.append([k,v,self.RADIUS_SERVO_MIN])
                elif 'stepper' in k:
                    stepper_param.append([k,v,0])
                elif 'pin' in k:
                    pin_num = v[0]
                    if pin_num < 10:
                        pin_param.append([k,f'pin0{pin_num}0\n'.encode()])
                    else:
                        pin_param.append([k,f'pin{pin_num}0\n'.encode()])
                elif 'mask' in k:
                    mask_param.append([k, f'm1{self.MASK_OFF_ANGLE[0]}\n'.encode()])
                    mask_param.append([k, f'm2{self.MASK_OFF_ANGLE[1]}\n'.encode()])

            if pin_param != []:
                for i in pin_param:
                    self._port.write(i[1])
                    self.set_streaming_state(i[0], 0)
            if flag_param != []:
                self.set_servo_motor_pos(*flag_param)
            if servo_param != []:
                for i in servo_param:
                    self.set_servo_motor_pos(*i)
            if stepper_param != []:
                for i in stepper_param:
                    self.set_stepper_motor_pos(*i)
            if mask_param != []:
                for i in mask_param:
                    self._port.write(i[1])
                    self.set_streaming_state(i[0], 0)
                self._mask_status = np.array([False, False])

        self._protocol_start_time = None
        self.set_streaming_state('cmd_idx', -1)
        self.set_state_to(self._trigger_minion, 'runSignal', False)
        self._running_time = 0
        self.info('Protocol ended')

    def set_servo_motor_pos(self, servo_name, servo_vals, target_pos):
        self._set_servo_motor_pos(servo_vals[0], target_pos)
        self.set_streaming_state(servo_name, target_pos)

    def _set_servo_motor_pos(self, servo_idx, target_pos):
        if servo_idx == self._motor_dict['radius_servo']:
            if target_pos < self.RADIUS_SERVO_MIN:
                self.warning(f"Radius servo position is smaller than the lower limit ({target_pos}<{self.RADIUS_SERVO_MIN})")
                target_pos = self.RADIUS_SERVO_MIN
        self._port.write(f's{servo_idx}{target_pos}\n'.encode())

    def set_stepper_motor_pos(self, stepper_name, stepper_vals, target_pos):
        has_set = self._set_stepper_motor_pos(stepper_vals[0], target_pos)
        if has_set:
            self.set_streaming_state(stepper_name, target_pos)

    def _set_stepper_motor_pos(self, stepper_idx, target_pos):
       if target_pos > 180 or target_pos < 0:
           self.error('Stepper position must be between 0 and 180 degrees')
           return False
       else:
           target_step = int(target_pos / 180 * self.STEPPER_180)
           delta_steps = target_step - self._stepper_counter
           if delta_steps > 0:
               self._port.write(f'f{stepper_idx}{delta_steps}\n'.encode())
           elif delta_steps < 0:
               self._port.write(f'b{stepper_idx}{-delta_steps}\n'.encode())
           self._stepper_counter = target_step
           return True

    def toggle_mask_servo(self, mask_num):
        self._toggle_mask_servo(mask_num)

    def _toggle_mask_servo(self, mask_num):
        # mask num is 0(left) or 1(right)
        if mask_num in [0,1]:
            if self._mask_status[mask_num]:
                self._mask_status[mask_num] = False
                self._port.write(f'm{mask_num+1}{self.MASK_OFF_ANGLE[mask_num]}\n'.encode())
            else:
                self._mask_status[mask_num] = True
                if self._mask_status[1 -mask_num]:
                    self._port.write(f'm{2-mask_num}{self.MASK_OFF_ANGLE[1-mask_num]}\n'.encode())
                    self._mask_status[1-mask_num] = False
                self._port.write(f'm{mask_num+1}{self.MASK_ON_ANGLE[mask_num]}\n'.encode())

    def reset_mask_servo(self):
        # mask num is 0(left) or 1(right)
        for i in range(2):
            self._mask_status[i] = False
            self._port.write(f'm{i+1}{self.MASK_OFF_ANGLE[i]}\n'.encode())

class ArduinoCompiler(AbstractCompiler):

    def __init__(self, *args, port_name='COM7', pin_address={}, **kwargs):
        super(ArduinoCompiler, self).__init__(*args, **kwargs)
        self._port_name = port_name
        self.pin_address = pin_address
        self._port = None
        self.input_pin_dict = {}
        self.output_pin_dict = {}

        try:
            self._port = fmt.Arduino(self._port_name)
            self._watching_state = {}
            for n, v in self.pin_address.items():
                if v.split(":")[-1] == 'i':
                    try:
                        self.input_pin_dict[n] = self._port.get_pin(v)
                        self.create_state(n, self.input_pin_dict[n].read())
                    except:
                        print(traceback.format_exc())
                elif v.split(":")[-1] == 'o':
                    try:
                        self.output_pin_dict[n] = self._port.get_pin(v)
                        self.create_state(n, 0)
                    except:
                        print(traceback.format_exc())
        except:
            print(traceback.format_exc())

    def on_time(self, t):
        # while self._port.bytes_available():
        #     self._port.iterate()
        for n, v in self.input_pin_dict.items():
            state = v.read()
            if self.watch_state(n, state) and state is not None:
                self.set_state(n,state)

        for n, v in self.output_pin_dict.items():
            state = self.get_state(n)
            if self.watch_state(n, state) and state is not None:
                v.write(state)

    def on_close(self):
        self.set_state('status', -1)
        self._port.exit()

class OMSInterface(StreamingCompiler):

    def __init__(self, *args, VID=None, PID=None, timeout=1, mw_size=1, **kwargs):
        super(OMSInterface, self).__init__(*args, **kwargs)
        if VID is None or PID is None:
            raise ValueError('VID and PID must be set')
        else:
            self._VID = VID
            self._PID = PID

        self.device = usb.core.find(idVendor=self._VID, idProduct=self._PID)
        if self.device is not None:
            self.device.set_configuration()
            self._endpoint = self.device[0][(0,0)][0]
        else:
            raise ValueError(f'Device not found. VID: {self._VID}, PID: {self._PID}')

        self._timeout = timeout
        self._mw_size = mw_size
        self._pos_buffer = np.zeros((self._mw_size, 2))

        self.create_streaming_state('xPos',0, shared=True, use_buffer=False)
        self.create_streaming_state('yPos',0, shared=True, use_buffer=False)
        # self.create_state('xPos', 0)
        # self.create_state('yPos', 0)

    def on_time(self, t):
        try:
            x, y = self._read_device()
            if x is not None and y is not None:
                self._pos_buffer = np.roll(self._pos_buffer, -1, axis=0)
                self._pos_buffer[-1, 0] = x
                self._pos_buffer[-1, 1] = y
                xPos,yPos = np.nanmean(self._pos_buffer, axis=0)

                self.set_streaming_state('xPos', xPos)
                self.set_streaming_state('yPos', yPos)
        except:
            print(traceback.format_exc())

        super().on_time(t)

    def _read_device(self):
        try:
            data = self.device.read(self._endpoint.bEndpointAddress, self._endpoint.wMaxPacketSize, self._timeout)
            if data is not None:
                x = data[2]
                y = data[4]
                if x > 127:
                    x = (x - 256)/128
                else:
                    x = (x+1)/128
                if y > 127:
                    y = (y - 256)/128
                else:
                    y = (y+1)/128
                return x, y
        except:
            self.debug('OMS device timeout')
            return None, None

    def on_close(self):
        self.set_state('status', -1)


#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Resource information of command
"""

def get_name(friendly=False):
    """Get name of this resource

    :return: name of this resource
    :rtype: str
    """
    if friendly:  # pragma: no cover
        return "Alignak command"
    return 'command'

def get_doc():  # pragma: no cover
    """Get documentation of this resource

    :return: rst string
    :rtype: str
    """
    return """
    The ``command`` model is used to represent a command in the monitored system.

    A command is used:

    - for the hosts and services active checks. The command is a check plugin
    used to determine the host or service state.

    - for the event handlers launched when an host / service state changes.

     - for the notifications sent to inform the users of the detected problems
    """

def get_schema():
    """Schema structure of this resource

    :return: schema dictionary
    :rtype: dict
    """
    return {
        'mongo_indexes': {
            'index_updated': [('_updated', 1)],
            'index_name': [('name', 1)],
        },
        'schema': {
            'schema_version': {
                'type': 'integer',
                'default': 1,
            },
            # Importation source
            'imported_from': {
                'schema_version': 1,
                'title': 'Imported from',
                'comment': 'Item importation source (alignak-backend-import, ...)',
                'type': 'string',
                'default': 'unknown'
            },
            'definition_order': {
                'schema_version': 1,
                'title': 'Definition order',
                'comment': 'Priority level if several elements have the same name',
                'type': 'integer',
                'default': 100
            },

            # Identity
            'name': {
                'schema_version': 1,
                'title': 'Command name',
                'comment': 'Unique command name',
                'type': 'string',
                'required': True,
                'empty': False,
                'unique': True,
            },
            'alias': {
                'schema_version': 1,
                'title': 'Alias',
                'comment': 'Element friendly name used by the Web User Interface.',
                'type': 'string',
                'default': ''
            },
            'notes': {
                'schema_version': 1,
                'title': 'Notes',
                'comment': 'Element notes. Free text to store element information.',
                'type': 'string',
                'default': ''
            },

            # Command specific
            'command_line': {
                'schema_version': 1,
                'title': 'Command line',
                'comment': 'System command executed to run the command.',
                'type': 'string',
            },
            'module_type': {
                'schema_version': 1,
                'title': 'Module type',
                'comment': 'A specific module type may be defined to associate commands '
                           'to a dedicated worker. To be completed...',
                'type': 'string',
                'default': 'fork'
            },
            'timeout': {
                'schema_version': 1,
                'title': 'Timeout',
                'comment': 'Maximum command execution time before ALignak force the command stop.',
                'type': 'integer',
                'default': -1
            },
            'enable_environment_macros': {
                'schema_version': 1,
                'title': 'Environment macros',
                'comment': 'Set Alignak environment macros before running this command.',
                'type': 'boolean',
                'default': False
            },

            # Alignak daemons
            'poller_tag': {
                'schema_version': 1,
                'title': 'Poller tag',
                'comment': 'Set a value for this element checks to be managed by a '
                           'dedicated poller.',
                'type': 'string',
                'default': ''
            },
            'reactionner_tag': {
                'schema_version': 1,
                'title': 'Reactionner tag',
                'comment': 'Set a value for this element notifications to be managed by a '
                           'dedicated reactionner.',
                'type': 'string',
                'default': ''
            },

            # Realm
            '_realm': {
                'schema_version': 1,
                'title': 'Realm',
                'comment': 'Realm this element belongs to.',
                'type': 'objectid',
                'data_relation': {
                    'resource': 'realm',
                    'embeddable': True
                },
                'required': True,
            },
            '_sub_realm': {
                'schema_version': 1,
                'title': 'Sub-realms',
                'comment': 'Is this element visible in the sub-realms of its realm?',
                'type': 'boolean',
                'default': True
            },

            # Users CRUD permissions
            '_users_read': {
                'schema_version': 1,
                'type': 'list',
                'schema': {
                    'type': 'objectid',
                    'data_relation': {
                        'resource': 'user',
                        'embeddable': True,
                    }
                },
            },
            '_users_update': {
                'schema_version': 1,
                'type': 'list',
                'schema': {
                    'type': 'objectid',
                    'data_relation': {
                        'resource': 'user',
                        'embeddable': True,
                    }
                },
            },
            '_users_delete': {
                'schema_version': 1,
                'type': 'list',
                'schema': {
                    'type': 'objectid',
                    'data_relation': {
                        'resource': 'user',
                        'embeddable': True,
                    }
                },
            },
        },
        'schema_deleted': {}
    }


from __future__ import print_function, absolute_import, division
from future.builtins import *
from future import standard_library
standard_library.install_aliases()

# Copyright 2017 Autodesk Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import json

import moldesign as mdt
from .. import units as u

PACKAGEPATH = os.path.abspath(os.path.dirname(mdt.__file__))

class CyclicList(list):
    def __getitem__(self, item):
        return super().__getitem__(item % len(self))

COLOR_LIST = ['lightgreen', 'lightblue', 'lightgrey',
              'yellow', 'orange', 'purple', 'IndianRed',
              'PaleTurquoise', 'OldLace', 'Thistle', 'pink']

DEFAULT_FORCE_TOLERANCE = (0.0001 * u.hartree / u.bohr).defunits()  # taken from GAMESS OPTTOL keyword

# Precompute odd factorial values (N!!)
ODD_FACTORIAL = {0: 1}  # by convention
_ofact = 1
for _i in range(1, 20, 2):
    _ofact *= _i
    ODD_FACTORIAL[_i] = float(_ofact)

def print_environment():
    """For reporting bugs - spits out the user's environment"""
    import sys
    version = {}
    for pkg in 'moldesign IPython ipywidgets jupyter matplotlib numpy docker pyccc distutils' \
               'nbmolviz jupyter_client jupyter_core pint Bio openbabel simtk pyscf pip setuptools'\
            .split():
        try:
            module = __import__(pkg)
        except ImportError as e:
            version[pkg] = str(e)
        else:
            try:
                version[pkg] = module.__version__
            except AttributeError as e:
                version[pkg] = str(e)
    env = {'platform': sys.platform,
           'version': sys.version,
           'prefix': sys.prefix}

    try:
        import platform
        env['machine'] = platform.machine()
        env['linux'] = platform.linux_distribution()
        env['mac'] = platform.mac_ver()
        env['windows'] = platform.win32_ver()
        env['impl'] = platform.python_implementation()
        env['arch'] = platform.architecture()
        env['system'] = platform.system()
        env['python_build'] = platform.python_build()
        env['platform_version'] = platform.version()

    except Exception as e:
        env['platform_exception'] = str(e)

    print(json.dumps({'env': env,
                      'versions': version}))


# coding=UTF-8
import logging
from body.model import create_good_from_list, show_the_entire_list, max_min_goods_on_the_list
from body.model import delete_goods_from_list, db_in_json, clean_db
import body.view_file as view

logger = logging.getLogger(f'main.{__name__}')

class Controllers:
    """Single controller class."""

    @staticmethod
    def primary_data():
        """Entering initial data into the database."""
        for row in view.ViewForGood().data_from_file():
            create_good_from_list(row)

        logger.info('The data has been entered into the database.')

    @staticmethod
    def show_main_window():
        """The function of obtaining the initial data file for the database and launching the main user window."""
        logger.debug('Funktion show_main_window is worked')
        view.ViewForGood().data_from_list()
        view.ViewForGood().start_main_window()

    @staticmethod
    def create_user_good(data):
        """A function that creates products from a list."""
        logger.debug('Function create_user_good is worked')
        return create_good_from_list(data)

    @staticmethod
    def result_list():
        """The function of passing the database content sheet to the output in Tkinter"""
        return show_the_entire_list()

    @staticmethod
    def del_data(data):
        """Function to delete data by name."""
        deld = delete_goods_from_list(data)
        if deld:
            logger.debug(f'del_data is worked. Product "{data}" removed from the list')
            return deld

    @staticmethod
    def max_min_func():
        """Function of initial processing of max and min values."""
        data = max_min_goods_on_the_list()
        if data:
            return data
        return False

    @staticmethod
    def clear_db_func():
        """Function of completely deleting data from the database."""
        if show_the_entire_list():
            clean_db()
            logger.info('DB is cleaned')
            return True
        else:
            return False

    @staticmethod
    def json_output():
        """Function of outputting data from the database to a file in JSON format"""
        data = db_in_json()
        if data:
            logger.info(f'The database is written in JSON format to the file "{data}"')
            return data
        else:
            logger.info('DB is empty, unsuccessful attempt to create JSON file')
            return False


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time    : 2018/11/7 17:32
# @Author  : Jerry
# @Site    :
# @File    : class.py
# @Software: PyCharm

# 继承
class Person(object):
    def __init__(self, name, sex):
        self.name = name
        self.sex = sex

class Child(Person):
    def __init__(self, name, sex, mother, father):
       Person.__init__(self, name, sex)
       self.mother = mother
       self.father = father

May = Child("May", "female", "April", "June")
print(May.mother, May.father)

# 多态
class Screen(object):
    @property
    def width(self):
        return self.width

    @width.setter
    def width(self, valuer):
        if not isinstance(valuer, int):
            raise ValueError()
        if valuer < 0:
            raise ValueError()
        self.width = valuer

    @property
    def height(self):
        return self.height

    @width.setter
    def height(self, valuer):
        if not isinstance(valuer, int):
            raise ValueError()
        if valuer < 0:
            raise ValueError()
        self.height = valuer

s = Screen
s.width = 3
s.height = 400
print(s.width,s.height)


from flask import request
from flask_restx import Resource, Api, Namespace
import random

# Define a Flask-RestX Namespace for the VAD Analyzer API
Danger = Namespace(
    name='Danger',
    description='Danger Analysis API'
)

@Danger.route('')
class DangerAnalyzer(Resource):
    def get(self):
        response_data = {
            "response": "Hello"
        }
        return response_data


BLOCKCHAIN_OPTIONS = (
    ('bitcoin', 'BTC'),
    ('bitcoin-cash', 'BCH'),
    ('litecoin', 'LTC'),
    ('dogecoin', 'DOGE'),
    ('dash', 'DASH'),
    ('ethereum', 'ETH'),
    ('ethereum-classic', 'ETC'),
    ('xrp', 'XRP'),
    ('zcash', 'Zcash'),
    ('binance-smart-chain', 'BSC'),
    ('tron', 'TRON')
)

NETWORK_OPTIONS = (
    ('mainnet', 'Mainnet'),
    ('testnet', 'Testnet'),
    ('mordor', 'Mordor'),
    ('nile', 'Nile'),
    ('goerli', 'Goerli'),
)

LOGO_SETTINGS = {
    'bitcoin'               : '/media/icons/btc.png',
    'bitcoin-cash'          : '/media/icons/bitcoin-cash.png',
    'litecoin'              : '/media/icons/litecoin.png',
    'dogecoin'              : '/media/icons/dogecoin.png',
    'dash'                  : '/media/icons/dash.png',
    'ethereum'              : '/media/icons/ethereum.png',
    'ethereum-classic'      : '/media/icons/etherum-classic.png',
    'xrp'                   : '/media/icons/xrp.png',
    'zcash'                 : '/media/icons/zcash.png',
    'binance-smart-chain'   : '/media/icons/binance-smart-chain.png',
    'tron'                  : '/media/icons/tron.png'
}

BLOCKCHAIN_CODE = {
    'bitcoin'               : 'BTC',
    'bitcoin-cash'          : 'BCH',
    'litecoin'              : 'LTC',
    'dogecoin'              : 'DOGE',
    'dash'                  : 'DASH',
    'ethereum'              : 'ETH',
    'ethereum-classic'      : 'ETC',
    'xrp'                   : 'XRP',
    'zcash'                 : 'ZEC',
    'binance-smart-chain'   : 'BNB',
    'tron'                  : 'TRX'
}

NETWORK_CODE = {
    'testnet'   : 'TNT',
    'mainnet'   : 'MNT',
    'mordor'    : 'MRD',
    'nile'      : 'NLE',
    'goerli'    : 'GOE'
}


import GPy
import numpy as np
import os
import sys
import typing
import h5py

class GPRSM:
    def __init__(self, train_x:np.array, train_y:np.array, kernel_name:str="Matern52", is_ard:bool=True, normalizer="standardization") -> None:
        """initialize GPR surrogate model

        Args:
            train_x (numpy.ndarray): training data x (number of samples x number of features)
            train_y (numpy.ndarray): training data x (number of samples x 1)
            kernel_name (str): kernel name (Matern52, Matern32, RBF, etc.)
            is_ard (bool): whether ARD is used or not
            normalizer (str): normalizer (standardization, minmax, none)
        """
        if train_x.shape[0] != train_y.shape[0]:
            print("Error: train_x and train_y have different number of samples", file=sys.stderr)
            return
        self.train_x = train_x.copy()
        self.train_y = train_y.copy()
        if normalizer is not None:
            inp_x, inp_y = self.normalize(normalizer)
        else:
            inp_x, inp_y = train_x, train_y
        self.is_ard = is_ard
        self.kernel_name = kernel_name
        num_dim = train_x.shape[1]
        kernel_func = self.select_kernel_func(kernel_name)
        self.kernel = kernel_func(input_dim=num_dim, ARD=is_ard)
        self.model = GPy.models.GPRegression(X=inp_x, Y=inp_y, kernel=self.kernel, normalizer=False)
        self.is_transfer = False
        self.is_optimized = False

    def normalize(self, normalizer):
        """normalize training data

        Args:
            normalizer (str): normalizer (standardization, minmax, none)

        Returns:
            np.array: normalized training data x and y
        """
        if normalizer=="standardization":
            self.mean_x = np.mean(self.train_x, axis=0)
            self.std_x = np.std(self.train_x, axis=0)
            self.mean_y = np.mean(self.train_y, axis=0)
            self.std_y = np.std(self.train_y, axis=0)
            train_x = (self.train_x - self.mean_x) / self.std_x
            train_y = (self.train_y - self.mean_y) / self.std_y
        elif normalizer=="minmax":
            self.min_x = np.min(self.train_x, axis=0)
            self.max_x = np.max(self.train_x, axis=0)
            self.min_y = np.min(self.train_y, axis=0)
            self.max_y = np.max(self.train_y, axis=0)
            train_x = (train_x - self.min_x) / (self.max_x - self.min_x)
            train_y = (train_y - self.min_y) / (self.max_y - self.min_y)
        else:
            print("Error: normalizer is not defined", file=sys.stderr)
            return
        self.normalizer = normalizer
        return train_x, train_y

    def normalize_x(self, inp_x):
        """normalize input data x

        Args:
            inp_x (np.array): input data x (number of samples x number of features)

        Returns:
            np.array: normalized input data x
        """
        if self.normalizer=="standardization":
            inp_x = (inp_x - self.mean_x) / self.std_x
        elif self.normalizer=="minmax":
            inp_x = (inp_x - self.min_x) / (self.max_x - self.min_x)
        else:
            print("Error: normalizer is not defined", file=sys.stderr)
            return
        return inp_x

    def inverse_normalize(self, pred_y):
        """inverse normalize predicted data y

        Args:
            pred_y (np.array): normalized predicted data y (number of samples x 1)

        Returns:
            np.array: inverse normalized predicted data y
        """
        if self.normalizer=="standardization":
            pred_y = pred_y * self.std_y + self.mean_y
        elif self.normalizer=="minmax":
            pred_y = pred_y * (self.max_y - self.min_y) + self.min_y
        else:
            print("Error: normalizer is not defined", file=sys.stderr)
            return
        return pred_y

    def select_kernel_func(self, kernel_name):
        """select kernel function

        Args:
            kernel_name (str): kernel name (Matern52, Matern32, RBF, etc.)

        Returns:
            GPy.kern: kernel function
        """
        if kernel_name=="Matern52":
            return GPy.kern.Matern52
        elif kernel_name=="Matern32":
            return GPy.kern.Matern32
        elif kernel_name=="RBF":
            return GPy.kern.RBF
        elif kernel_name=="Exp" or kernel_name=="Exponential":
            return GPy.kern.Exponential
        elif kernel_name=="RQ" or kernel_name=="RatQuad":
            return GPy.kern.RatQuad
        else:
            print("Error: kernel name is not defined", file=sys.stderr)
            return None

    def set_transfer_learning(self, source_x, source_y):
        """set transfer learning

        Args:
            source_x (numpy.ndarray): source data x of transfer learning (number of samples x number of features)
            source_y (numpy.ndarray): source data y of transfer learning (number of samples x 1)
        """
        if self.is_transfer:
            print("Reset transfer learning")
        self.source_x = source_x.copy()
        self.source_y = source_y.copy()
        min_dim = min(self.train_x.shape[1], self.source_x.shape[1])
        num_dim = self.train_x.shape[1] + self.source_x.shape[1] + min_dim
        self.kernel = GPy.kern.Matern52(input_dim=num_dim, ARD=self.kernel.ARD)
        if self.train_x.shape[1] <= self.source_x.shape[1]:
            train_x1 = np.hstack((self.source_x[:,:self.train_x.shape[1]], self.source_x, np.zeros(shape=(self.source_x.shape[0], self.train_x.shape[1]))))
            train_x2 = np.hstack((self.train_x, np.zeros(shape=(self.train_x.shape[0], self.source_x.shape[1])), self.train_x))
        else:
            train_x1 = np.hstack((self.source_x, self.source_x, np.zeros(shape=(self.source_x.shape[0], self.train_x.shape[1]))))
            train_x2 = np.hstack((self.train_x[:,:self.source_x.shape[1]], np.zeros(shape=(self.train_x.shape[0], self.source_x.shape[1])), self.train_x))
        self.target_x = self.train_x.copy()
        self.target_y = self.train_y.copy()
        self.train_x = np.vstack((train_x1, train_x2))
        self.train_y = np.vstack((self.source_y, self.train_y))
        if self.normalizer is not None:
            inp_x, inp_y = self.normalize(self.normalizer)
        else:
            inp_x, inp_y = self.train_x, self.train_y
        self.model = GPy.models.GPRegression(X=inp_x, Y=inp_y, kernel=self.kernel, normalizer=False)
        self.common_part_dim = min_dim
        self.target_part_dim = self.target_x.shape[1]
        self.source_part_dim = self.source_x.shape[1]
        self.is_transfer = True

    def optimize(self, max_iter:int, messages:bool=False, num_restarts:int=10, parallel:bool=True) -> None:
        """optimize GPR surrogate model

        Args:
            max_iter (int): max iteration number
            messages (bool, optional): print messages. Defaults to False.
            num_restarts (int, optional): number of restarts. Defaults to 10.
            parallel (bool, optional): is parallel. Defaults to True.
        """
        self.model.optimize(max_iters=max_iter, messages=messages)
        if num_restarts > 0:
            num_cpu = os.cpu_count()
            self.model.optimize_restarts(num_restarts=num_restarts, parallel=parallel, num_processes=num_cpu, messages=messages)
        self.is_optimized = True

    def predict(self, test_x:np.array) -> typing.Tuple[np.array, np.array]:
        """predict by GPR surrogate model

        Args:
            test_x (np.array): test data x (number of samples x number of features)

        Returns:
            typing.Tuple[np.array, np.array]: predicted mean and variance
        """
        if self.is_transfer:
            if self.target_x.shape[1] != test_x.shape[1]:
                print("Error: dimension of test data is different from dimension of training data", file=sys.stderr)
                return None, None
        else:
            if self.train_x.shape[1] != test_x.shape[1]:
                print("Error: dimension of test data is different from dimension of training data", file=sys.stderr)
                return None, None

        if not self.is_optimized:
            print("Warning: GPR surrogate model is not optimized", file=sys.stderr)
            return None, None
        self.test_x = test_x.copy()
        if self.is_transfer:
            if self.target_part_dim <= self.source_part_dim:
                self.test_x = np.hstack((test_x, np.zeros(shape=(self.test_x.shape[0], self.source_part_dim)), test_x))
            else:
                self.test_x = np.hstack((test_x[:, self.source_part_dim], np.zeros(shape=(self.test_x.shape[0], self.source_part_dim)), test_x))
        if self.normalizer is not None:
            inp_x = self.normalize_x(self.test_x)
        else:
            inp_x = self.test_x
        pred_mean, pred_var = self.model.predict(inp_x)
        if self.normalizer is not None:
            _tmp = self.inverse_normalize(pred_mean+pred_var)
            pred_mean = self.inverse_normalize(pred_mean)
            pred_var = _tmp - pred_mean
        return pred_mean, pred_var

    def get_ard_contribution(self, normalized=True) -> np.array:
        """get ARD contribution

        Args:
            normalized (bool, optional): whether normalized or not. Defaults to True.

        Returns:
            np.array: ARD contributions
        """
        if not self.is_optimized:
            print("Error: model is not optimized", file=sys.stderr)
            return None
        if not self.is_ard:
            print("Error: kernel is not ARD", file=sys.stderr)
            return None
        length_scales = self.model.kern.lengthscale
        contribution = [1.0/l for l in length_scales]
        if normalized:
            contribution = [100.0*c/sum(contribution) for c in contribution]
        return np.array(contribution)

    def get_transfer_learning_effect(self) -> float:
        """get transfer learning effect

        Returns:
            float: effect of transfer learning (%)
        """
        if not self.is_optimized:
            print("Error: model is not optimized", file=sys.stderr)
            return None
        if not self.is_ard:
            print("Error: kernel is not ARD", file=sys.stderr)
            return None
        if not self.is_transfer:
            print("Error: model is not transfer lerning", file=sys.stderr)
            return None
        contribution = self.get_ard_contribution(normalized=True)
        contribution_common = np.sum(contribution[:self.common_part_dim])
        contribution_target = np.sum(contribution[self.common_part_dim+self.source_part_dim:])
        effect = contribution_common / contribution_target
        return effect

    def get_part_contribution(self) -> typing.Tuple[float, float, float]:
        """get contribution of each part

        Returns:
            typing.Tuple[float, float, float]: contribution of common part, source part, target part (%)
        """
        if not self.is_optimized:
            print("Error: model is not optimized", file=sys.stderr)
            return None
        if not self.is_ard:
            print("Error: kernel is not ARD", file=sys.stderr)
            return None
        if not self.is_transfer:
            print("Error: model is not transfer lerning", file=sys.stderr)
            return None
        contribution = self.get_ard_contribution(normalized=True)
        contribution_common = np.sum(contribution[:self.common_part_dim])
        contribution_source = np.sum(contribution[self.common_part_dim:self.common_part_dim+self.source_part_dim])
        contribution_target = np.sum(contribution[self.common_part_dim+self.source_part_dim:])
        return contribution_common, contribution_source, contribution_target

    def save_model(self, path:str) -> None:
        """save model

        Args:
            path (str): path to save model
        """
        if not self.is_optimized:
            print("Error: model is not optimized", file=sys.stderr)
            return None
        if not ".h5" in path:
            print("Error: path must be .h5 file", file=sys.stderr)
            return None
        with h5py.File(path, "w") as h5:
            h5.create_dataset("param_array", data=self.model.param_array)
            h5.create_dataset("is_ard", data=np.array([self.is_ard]), dtype=np.bool)
            h5.create_dataset("is_transfer", data=np.array([self.is_transfer]), dtype=np.bool)
            h5.create_dataset("is_optimized", data=np.array([self.is_optimized]), dtype=np.bool)
            kernel_name = h5.create_dataset("kernel_name", shape=(1,), dtype=h5py.special_dtype(vlen=str))
            kernel_name[0] = self.kernel_name
            h5.create_dataset("train_x", data=self.train_x)
            h5.create_dataset("train_y", data=self.train_y)
            if self.is_transfer:
                h5.create_dataset("common_part_dim", data=np.array([self.common_part_dim]), dtype=np.int32)
                h5.create_dataset("source_part_dim", data=np.array([self.source_part_dim]), dtype=np.int32)
                h5.create_dataset("target_part_dim", data=np.array([self.target_part_dim]), dtype=np.int32)
                h5.create_dataset("target_x", data=self.target_x)
                h5.create_dataset("target_y", data=self.target_y)
                h5.create_dataset("source_x", data=self.source_x)
                h5.create_dataset("source_y", data=self.source_y)

    @staticmethod
    def load_model(path:str):
        """load model

        Args:
            path (str): path to load model
        Returns:
            GPRSM: GPRSM model
        """
        if not ".h5" in path:
            print("Error: path must be .h5 file", file=sys.stderr)
            return None
        with h5py.File(path, "r") as h5:
            param_array = h5["param_array"][:]
            train_x = h5["train_x"][:]
            train_y = h5["train_y"][:]
            kernel_name = h5["kernel_name"][0].decode()
            is_ard = h5["is_ard"][0]
        gprsm = GPRSM(train_x, train_y, kernel_name=kernel_name, is_ard=is_ard)
        with h5py.File(path, "r") as h5:
            gprsm.is_transfer = h5["is_transfer"][0]
            gprsm.is_optimized = h5["is_optimized"][0]
            if gprsm.is_transfer:
                gprsm.common_part_dim = h5["common_part_dim"][0]
                gprsm.source_part_dim = h5["source_part_dim"][0]
                gprsm.target_part_dim = h5["target_part_dim"][0]
                gprsm.target_x = h5["target_x"][:]
                gprsm.target_y = h5["target_y"][:]
                gprsm.source_x = h5["source_x"][:]
                gprsm.source_y = h5["source_y"][:]
        gprsm.model = GPy.models.GPRegression(gprsm.train_x, gprsm.train_y, gprsm.kernel, initialize=False)
        gprsm.model.update_model(False)
        gprsm.model.initialize_parameter()
        gprsm.model[:] = param_array
        gprsm.model.update_model(True)
        return gprsm


#!/usr/bin/python3

import smtplib
from email.mime.text import MIMEText

def send_email(subject, message, from_addr, *to_addrs, host="localhost", port=1025, **headers):
  email = MIMEText(message)
  email['Subject'] = subject
  email['From'] = from_addr
  for header, value in headers.items():
    email[header] = value

  sender = smtplib.SMTP(host, port)
  for addr in to_addrs:
    del email['To']
    email['To'] = addr
    sender.sendmail(from_addr, addr, email.as_string())
  sender.quit()

if __name__ == "__main__":
  # headers = {}
  send_email("A model subject", "The message contents", "from@example.com", "to1@example.com", "to2@example.com", "Reply-To", "me2@example.com")


class TicTacToe:

    def __init__(self, end=False, board=list(), iswinner=str, players=list(), crntPlayer=str(), move=None):
        self.board = board
        self.players = players
        self.end = end
        self.iswinner = iswinner
        self.crntPlayer = crntPlayer
        self.move = move

    def reset(self):
        self.board = [1, 2, 3, 4, 5, 6, 7, 8, 9]
        self.defPlayer()

    def defPlayer(self):
        self.players = ['X', 'O']
        self.crntPlayer = input('X or O? ').upper()
        if self.crntPlayer not in self.players:
            print('Please enter X or O')
            self.defPlayer()

    def doMoves(self):
        try:
            self.printBoard()
            self.move = input(self.crntPlayer + ', Where do you want to go? (1-9): ')
            if isinstance(int(self.move), int) == False: print ('[ERROR] Please select a number!')
            else:
                if int(self.move) > 0 and int(self.move) <= 9:
                    if isinstance(self.board[int(self.move) - 1], int):
                        self.board[int(self.move) - 1] = self.crntPlayer
                        self.checkWin()
                        if self.crntPlayer == self.players[0]: self.crntPlayer = self.players[1]
                        else: self.crntPlayer = self.players[0]
                    else:
                        print('Tile has been taken, try another!')
                else:
                    print('Please select a number on the board!')
        except:
            print('[ERROR] Incorrect input, please try again!')

    def checkRow(self, move1, move2, move3):
        moves = [self.board[int(move1) - 1], self.board[int(move2) - 1], self.board[int(move3) - 1]]
        if len(set(moves)) == 1:
            self.iswinner = self.crntPlayer
            return True

    def winner(self):
        if isinstance(self.iswinner, str):
            self.printBoard()
            print('Player ' + self.iswinner + ' wins!')
            result = input('Play again? (yes or no): ').lower()
            if result in ['y', 'yes']:
                self.reset()
            else:
                self.end = True
                print('Thanks for playing!')

    def checkWin(self):
        win_rows = ['1,2,3', '4,5,6', '7,8,9', '1,4,7', '1,5,9', '2,5,8', '3,6,9', '3,5,6', '7,5,3']
        for i in win_rows:
            x = i.split(',')
            if self.checkRow(int(x[0]), int(x[1]), int(x[2])): self.winner()

    def printBoard(self):
        print('''
                Tic Tac Toe
               -------------
               | %s | %s | %s |
               -------------
               | %s | %s | %s |
               -------------
               | %s | %s | %s |
               -------------

            ''' % (self.board[0], self.board[1], self.board[2], self.board[3], self.board[4], self.board[5], self.board[6], self.board[7], self.board[8]))

game = TicTacToe()
game.reset()
while True:
    if game.end == True:
        break
    game.doMoves()


#################################################################################
# Set only in this values optionss
# please make this file accessible only for root!

app_name = "secureros"  # keyword, don't change if not sure
app_tmp_dir = "/tmp/" + app_name     #script must have write permissions to this folder
app_log_dir = "/var/log/" + app_name #script must have write permissions to this folder

#################################################################################
# Options which can be modified via commandline
#debug = False
debug = True #unsafe!


import sys
import json
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as md
import datetime

# ==========================
# *** Reading JSON files ***

stchoo = int(sys.argv[1])

#monthUb = ['aug', 'sep', 'oct', 'nov']
monthUub = ['aug', 'sep', 'oct', 'nov', 'dec', 'jan', 'feb', 'mar', 'abr']

basenameUub = "../../readMonit/hv"+str(stchoo)
outnameUub = "../../plots/uubHVSt"+str(stchoo)+".png"

# ===============================
# *** For Peak HBase Plotting ***

hvdataUub = [[], [], [], []]# time, pmt1, pmt2, pmt3
for mth in monthUub:
  tmpdata = np.loadtxt( basenameUub+str(mth)+".dat" )
  for info in tmpdata:
    hvdataUub[0].append( datetime.datetime.fromtimestamp( info[0] ) )
    hvdataUub[1].append( info[1] )
    hvdataUub[2].append( info[2] )
    hvdataUub[3].append( info[3] )

fig = plt.figure(figsize=(16,9))

markers = ['o', 's', '^']
ax=plt.gca()
xfmt = md.DateFormatter('%m/%d')
ax.xaxis.set_major_formatter(xfmt)
mkrSize = 6

ymin = 9e2
ymax = 2.75e3

plt.plot(hvdataUub[0], hvdataUub[1], markers[0], markersize=mkrSize, label="UUB HV PMT1") #, color='tab:blue'
plt.plot(hvdataUub[0], hvdataUub[2], markers[1], markersize=mkrSize, label="UUB HV PMT2") #, color='tab:blue'
plt.plot(hvdataUub[0], hvdataUub[3], markers[2], markersize=mkrSize, label="UUB HV PMT3") #, color='tab:blue'

plt.legend(fontsize=22)
#plt.ylim(ymin, ymax)
plt.ylabel("Station "+str(stchoo)+" HV [V]", fontsize=22)
plt.xlabel("Time since August 1st, 2020 [month/day]", fontsize=22)
plt.xticks(fontsize=22)
plt.yticks(fontsize=22)

plt.tight_layout()
#plt.show()
plt.savefig(outnameUub, dpi=100)
print("Done for HV over time, ST. "+str(stchoo))


from socketserver import UnixStreamServer, StreamRequestHandler, ThreadingMixIn
import subprocess
import os
import time
import json
import signal
import base64
import re

import tucal
import tucal.db

CHILDREN = {}
CLEANUP_STARTED = False

def cleanup_jobs():
    cur = tucal.db.cursor()
    cur.execute("UPDATE tucal.job SET status = 'aborted', pid = NULL WHERE status = ANY('{waiting, running}')")
    cur.close()
    tucal.db.commit()

def cleanup():
    global CLEANUP_STARTED
    if CLEANUP_STARTED:
        return
    CLEANUP_STARTED = True

    print('cleaning up child processes', flush=True)
    for pid, data in CHILDREN.items():
        proc = data['proc']
        print(f'killing {proc.pid}...', flush=True)
        proc.terminate()

    time.sleep(1)

    print('cleaning up jobs', flush=True)
    cleanup_jobs()

    print('cleanup complete', flush=True)
    exit(0)

def signal_exit(signal_num: int, frame):
    cleanup()

class Handler(StreamRequestHandler):
    def handle(self):
        job = self.rfile.readline()
        if not job:
            self.wfile.write(b'error: no input\n')
            return
        job = re.sub(r'\s+', ' ', job.decode('utf8').strip()).split(' ')
        delay, job_name, job = int(job[0]), job[1], job[2:]
        cur = tucal.db.cursor()

        cmd = ['python3', '-m']
        stdin = ''
        mnr = None
        if job_name == 'sync-user':
            # sync-user [store] [keep] [reset] <mnr> [<pwd-b64> [<2fa-token> | <2fa-generator-b64>]]
            cmd += ['tucal.jobs.sync_user']
            if len(job) > 0 and job[0] == 'store':
                job.pop(0)
                cmd += ['-s']
            if len(job) > 0 and job[0] == 'keep':
                job.pop(0)
                cmd += ['-k']
            if len(job) > 0 and job[0] == 'reset':
                job.pop(0)
                cmd += ['-r']
            if len(job) == 0:
                self.wfile.write(b'error: job sync-user requires at least one argument <mnr>\n')
                return
            mnr = int(job[0])
            cmd += ['-m', str(mnr)]
            if len(job) > 1:
                stdin += base64.b64decode(job[1]).decode('utf8') + '\n'
            else:
                cmd += ['-d']
            if len(job) > 2:
                stdin += job[2] + '\n'
        elif job_name == 'sync-cal':
            # sync-cal [<mnr>]
            cmd += ['tucal.jobs.sync_cal']
            if len(job) > 0:
                cmd += ['-m', job[0]]
        elif job_name == 'sync-users':
            # sync-users
            cmd += ['tucal.jobs.sync_users']
            if len(job) > 0:
                self.wfile.write(b'error: job sync-users has no additional arguments\n')
                return
        elif job_name == 'sync-plugins':
            # sync-plugins
            cmd += ['tucal.jobs.sync_plugins']
            if len(job) > 0:
                self.wfile.write(b'error:job sync-plugins has no additional arguments\n ')
                return
        else:
            self.wfile.write(b'error: unknown job type\n')
            return

        data = {
            'name': job_name.replace('-', ' '),
            'pid': None,
            'mnr': mnr,
            'status': 'waiting',
            'data': '{}',
        }
        cur.execute("""
            INSERT INTO tucal.job (name, pid, mnr, status)
            VALUES (%(name)s, %(pid)s, %(mnr)s, %(status)s)
            RETURNING job_nr, job_id""", data)
        tucal.db.commit()
        job_nr, job_id = cur.fetch_all()[0]
        data['nr'] = job_nr
        data['id'] = job_id

        self.wfile.write(f'{job_nr} {job_id}\n'.encode('utf8'))

        if delay > 0:
            print(f'[{job_nr:8}] {job_name} - delay {delay} seconds', flush=True)
            time.sleep(delay)

        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
        pid = proc.pid
        CHILDREN[pid] = {'proc': proc}
        proc.stdin.write(stdin.encode('utf8'))
        proc.stdin.close()
        CHILDREN[pid]['job_nr'] = job_nr

        data['status'] = 'running'
        data['pid'] = pid
        cur.execute("""
            UPDATE tucal.job
            SET status = %(status)s, pid = %(pid)s
            WHERE job_nr = %(nr)s""", data)
        tucal.db.commit()

        print(f'[{job_nr:8}] {job_name} - PID {pid} - {" ".join(cmd)}', flush=True)
        try:
            self.wfile.write(f'{pid}\n'.encode('utf8'))
        except BrokenPipeError:
            pass

        reader = tucal.JobStatus()
        data['time'] = reader.time
        data['start'] = reader.start.isoformat() if reader.start else None
        data['data'] = reader.json(),
        data['err'] = None

        cur.execute("""
            UPDATE tucal.job
            SET data = %(data)s,
                time = %(time)s,
                name = %(name)s
            WHERE job_nr = %(nr)s""", data)
        tucal.db.commit()

        code: int
        while True:
            code = proc.returncode
            if code is not None:
                break

            line = proc.stdout.readline().decode('utf8')
            if len(line) > 0:
                try:
                    self.wfile.write(b'stdout:' + line.encode('utf8'))
                except BrokenPipeError:
                    pass
            if not reader.line(line):
                proc.poll()
                time.sleep(0.125)
                continue

            data['time'] = reader.time
            data['start'] = reader.start.isoformat() if reader.start else None
            data['name'] = reader.steps[0]['name'] if len(reader.steps) > 0 else None
            data['data'] = reader.json()
            cur.execute("""
                UPDATE tucal.job
                SET data = %(data)s,
                    status = %(status)s,
                    start_ts = %(start)s,
                    time = %(time)s,
                    name = %(name)s
                WHERE job_nr = %(nr)s""", data)
            tucal.db.commit()

        proc.stdout.read()
        err = proc.stderr.read().decode('utf8')
        if len(err) > 0:
            print('\n'.join([f'[{job_nr:8}] {line}' for line in err.rstrip().splitlines()]), flush=True)
            try:
                self.wfile.write(b'\n'.join(
                    [b'stderr:' + line.encode('utf8') for line in err.rstrip().splitlines()]
                ) + b'\n')
            except BrokenPipeError:
                pass

        data['data'] = reader.json()

        if len(err) > 0:
            d = json.loads(data['data'])
            d['error'] = err
            data['data'] = json.dumps(d)

        if code == 0:
            data['status'] = 'success'
        elif code > 0:
            data['status'] = 'error'
        else:
            data['status'] = 'aborted'

        try:
            self.wfile.write(f'status:{code}\n'.encode('utf8'))
        except BrokenPipeError:
            pass

        cur.execute("""
            UPDATE tucal.job
            SET data = %(data)s, status = %(status)s, pid = NULL
            WHERE job_nr = %(nr)s""", data)
        tucal.db.commit()

        proc.stdout.close()
        proc.stderr.close()
        proc.terminate()

        print(f'[{job_nr:8}] terminated ({code})', flush=True)
        del CHILDREN[pid]
        self.wfile.close()
        self.rfile.close()

class ThreadedUnixStreamServer(ThreadingMixIn, UnixStreamServer):
    pass

if __name__ == '__main__':
    signal.signal(signal.SIGINT, signal_exit)
    signal.signal(signal.SIGHUP, signal_exit)
    signal.signal(signal.SIGABRT, signal_exit)
    signal.signal(signal.SIGTERM, signal_exit)

    cleanup_jobs()

    try:
        os.unlink('/var/tucal/scheduler.sock')
    except FileNotFoundError:
        pass
    with ThreadedUnixStreamServer('/var/tucal/scheduler.sock', Handler) as server:
        server.serve_forever()


# 카카오 다트게임
import re

# YouTube 해설보고 이해
def solution(dartResult):
    #각 option에 맞는 값은 dictionary에 저장
    options = {'S' : '**1', 'D' : '**2', 'T' : '**3', '#': '*-1'}

    # 정규표현식을 사용하여 문자열 분할
    # S,D,T 가 있는지 그다음에 #, * 이 있는지, ?로 #, * 은 있을수도 있고 없을수도 있다고 저장
    # 그다음 split으로 분할
    lst = re.sub('([SDT][#*]?)', '\g<1> ', dartResult).split(' ')[:-1]

    result = []
    for i in lst:
        for j in i:
            i = i.replace(j, options.get(j, j))
        if i[-1] == '*':
            i += '2'
            # 앞에 값이 있다면 그값도 두배 곱해줘야함.
            if result:
                result[-1] += '*2'
        result.append(i)

    # 문자열을 바로 계산 할 수 있도록 해주는 함수 eval
    return sum([eval(i) for i in result])

print(solution('1S2D*3T'))


class Algorithm:

    # Flag for negative weight cycle detection
    HAS_CYCLE = False

    def calculate_shortest_paths(self, vertex_list, edge_list, start_vertex):

        start_vertex.min_distance = 0

        # -1 because bf algorithm dictates max iterations = |V|-1
        for i in range(0, len(vertex_list)-1):

            for edge in edge_list:

                u = edge.start_vertex
                v = edge.target_vertex
                new_distance = u.min_distance + edge.weight

                # relaxation process
                if new_distance < v.min_distance:
                    v.min_distance = new_distance
                    # must set for backtracking
                    v.predecessor = u

        # after |V|-1 iterations, final iteration to
        # check for negative weight cycles
        for edge in edge_list:
            if self.has_cycle(edge):
                print("Negative cycle detected")
                self.HAS_CYCLE = True
                return

    @staticmethod
    def has_cycle(edge):
        # if we run calculate_shortest_paths for one final iteration and a min_distance value decreases,
        # it means there is a negative cycle
        if edge.start_vertex.min_distance + edge.weight < edge.target_vertex.min_distance:
            return True
        else:
            return False

    def get_shortest_path_to(self, target_vertex):

        if not self.HAS_CYCLE:
            print("Shortest path to target vertex: ", target_vertex.min_distance)
            node = target_vertex
            # while loop breaks when it reaches start node (has no predecessor)
            while node is not None:
                print("$s -> ", node.name)
                node = node.predecessor


# -*- coding: utf-8 -*-
"""
Created on Sat Jan  7 21:21:55 2023

@author: mrpot
"""

fname = input("Enter file name: ")
fh = open(fname)
lst = list()
final_lst = list()
for line in fh:
    x = line.rstrip()
    lst.append(x)

print(lst)

# concate list
for line in lst:
    #line.split
    stuff = line.split
    final_lst += stuff()

# removes duplicate character & sort order
final_lst = list(dict.fromkeys(final_lst))
final_lst.sort()
print(final_lst)


# Imports
import os
import numpy as np
import pandas as pd

import pickle, json
import tweepy

from datetime import datetime,timezone
import re
import time

from utils import get_logger
from auth import api
from dotenv import load_dotenv
import dicttoobject

if not load_dotenv():
    print('cant load .env file. Exiting!')
    exit()

users_folder = os.getenv('USERS_CACHE_FOLDER')

logger = get_logger('logs', 'flask.log')

#twitter_keys = {
#    'consumer_key': os.environ.get('consumer_key', None),
#    'consumer_secret': os.environ.get('consumer_secret', None),
#    'access_token_key': os.environ.get('access_token_key', None),
#    'access_token_secret': os.environ.get('access_token_secret', None)
#}

# Get fully-trained XGBoostClassifier model
with open('model_37k.pickle', 'rb') as read_file:
    xgb_model = pickle.load(read_file)

# Set up connection to Twitter API
#auth = tweepy.OAuthHandler(
#    twitter_keys['consumer_key'], twitter_keys['consumer_secret'])
#auth.set_access_token(
#    twitter_keys['access_token_key'], twitter_keys['access_token_secret'])

#api = tweepy.API(auth)

def is_cached(screen_name):
    filepath = os.path.join(users_folder, f'{screen_name}.json')
    if os.path.isfile(filepath):
        logger.info(('reading cached data', filepath))
        data = json.loads(open(filepath, 'r').read())
        data['created_at'] = datetime.strptime(data['created_at'], '%a %b %d %H:%M:%S %z %Y')
        return dicttoobject.dict_to_readonly_object(data)

def save_user(screen_name, data):
    file_path = os.path.join(users_folder, f'{screen_name}.json')
    os.makedirs(users_folder, exist_ok=True)
    if os.path.isfile(file_path):
        logger.info(('Duplicate file found - skipping', file_path))
        return None
    with open(file_path,'w') as f:
        json.dump(data,f,indent=4) # write to file
    logger.info(('File saved', file_path))
    return file_path

def get_user_features(screen_name):
    '''
    Input: a Twitter handle (screen_name)
    Returns: a list of account-level information used to make a prediction
            whether the user is a bot or not
    '''

    try:

        user = is_cached(screen_name)
        if not user:
            # Get user information from screen name
            user = api.get_user(screen_name=screen_name)
            save_user(screen_name, user._json)

        # account features to return for predicton
        account_age_days = (datetime.now(timezone.utc) - user.created_at).days
        verified = user.verified
        geo_enabled = user.geo_enabled
        default_profile = user.default_profile
        default_profile_image = user.default_profile_image
        favourites_count = user.favourites_count
        followers_count = user.followers_count
        friends_count = user.friends_count
        statuses_count = user.statuses_count
        average_tweets_per_day = np.round(statuses_count / account_age_days, 3)

        # manufactured features
        hour_created = int(user.created_at.strftime('%H'))
        network = np.round(np.log(1 + friends_count)
                           * np.log(1 + followers_count), 3)
        tweet_to_followers = np.round(
            np.log(1 + statuses_count) * np.log(1 + followers_count), 3)
        follower_acq_rate = np.round(
            np.log(1 + (followers_count / account_age_days)), 3)
        friends_acq_rate = np.round(
            np.log(1 + (friends_count / account_age_days)), 3)

        # organizing list to be returned
        account_features = [verified, hour_created, geo_enabled, default_profile, default_profile_image, favourites_count, followers_count, friends_count, statuses_count, average_tweets_per_day, network, tweet_to_followers, follower_acq_rate,friends_acq_rate]
        logger.info((f'features for {screen_name} verified:{verified}, hour_created:{hour_created}, geo_enabled:{geo_enabled}, default_profile:{default_profile}, default_profile_image:{default_profile_image}, favourites_count:{favourites_count}, followers_count:{followers_count}, friends_count:{friends_count}, statuses_count:{statuses_count}, average_tweets_per_day:{average_tweets_per_day}, network:{network}, tweet_to_followers:{tweet_to_followers}, follower_acq_rate:{follower_acq_rate}, friends_acq_rate:{friends_acq_rate}'))

    except Exception as e:
        logger.exception(e)
        return 'User not found'

    return account_features if len(account_features) == 14 else f'User not found'

def bot_or_not(twitter_handle):
    '''
    Takes in a twitter handle and predicts whether or not the user is a bot
    Required: trained classification model (XGBoost) and user account-level info as features
    '''

    user_features = get_user_features(twitter_handle)

    if user_features == 'User not found':
        return 'User not found'

    else:
        # features for model
        features = ['verified', 'hour_created', 'geo_enabled', 'default_profile', 'default_profile_image',
                    'favourites_count', 'followers_count', 'friends_count', 'statuses_count', 'average_tweets_per_day',
                    'network', 'tweet_to_followers', 'follower_acq_rate', 'friends_acq_rate']

        # creates df for model.predict() format
        user_df = pd.DataFrame(np.matrix(user_features), columns=features)

        prediction = xgb_model.predict(user_df)[0]

        return "Bot" if prediction == 1 else "Not a bot"

def bot_proba(twitter_handle):
    '''
    Takes in a twitter handle and provides probabily of whether or not the user is a bot
    Required: trained classification model (XGBoost) and user account-level info from get_user_features
    '''
    user_features = get_user_features(twitter_handle)

    if user_features == 'User not found':
        return 'User not found'
    else:
        user = np.matrix(user_features)
        proba = np.round(xgb_model.predict_proba(user)[:, 1][0]*100, 2)
        return proba

if __name__=="__main__":
    username = input('Enter a username:')
    u = get_user_features(username)
    print(u)


import re
import csv
import glob
import json
import argparse
import pandas as pd

from parse_gpx import GPXObj as gpxobj

# 1. Paths to:
#   a. gpx file                 -- duration,lat,lon
#   b. allData_clusters.csv     -- cluster, xy_umap, filepath
#   c. phases_dates.csv         -- day/moth/date/phase

# 2. Loop through allData_clusters.csv file

# X. activedays.json needs to be updated after geojson is generated

parser = argparse.ArgumentParser()
parser.add_argument('--gpx_folder_path')
parser.add_argument('--data_clusters_csv_path')
parser.add_argument('--phases_dates_csv_path')
parser.add_argument('--phase_files_path')

args = parser.parse_args()

# {
#    'type': 'Feature',
#    'properties': {
#        # from gpx file
#        'duration': '3',
#        'phase': '2.1', # generate from matching gpx filename to phases_dates.csv
#        'chunks': [
#            # from --> allData_clusters.csv
#            {
#                'chunkFilepath': '/Users/elinaoik/Documents/MIT/THESIS-MIT/python/CLEAN/CHUNKS3/200731_001_Stereo/ChannelsTest/200731_001_Stereo_681_mono.wav',
#                'cluster': '0',
#                'xy_umap' : [1,2]
#            },
#            {
#                'chunkFilepath': '/Users/elinaoik/Documents/MIT/THESIS-MIT/python/CLEAN/CHUNKS3/200731_001_Stereo/ChannelsTest/200731_001_Stereo_681_mono.wav',
#                'cluster': '0',
#                'xy_umap' : [1,2]
#            },
#            {
#                'chunkFilepath': '/Users/elinaoik/Documents/MIT/THESIS-MIT/python/CLEAN/CHUNKS3/200731_001_Stereo/ChannelsTest/200731_001_Stereo_681_mono.wav',
#                'cluster': '0',
#                'xy_umap' : [1,2]
#            }
#        ],
#    },
#    'geometry': {
#        'type': 'LineString',
#        'coordinates': [
#            # from gpx file
#            [-122.483696, 37.833818],
#            [-122.483482, 37.833174],
#        ]
#    }
# }

def all_files_in_folder(gpx_folder_path: str, file_suffix: str) -> list:
    """ list of gpx filepaths """
    return glob.glob(f"{gpx_folder_path}/*.{file_suffix}")

def phase_url_from_phase_nr(datestr: str, phase_nr: str) -> str:
    """ 200606_PM & 3.1 --> PM_3_1 """
    am_pm = datestr.split('_')[-1]
    phase, subphase = str(phase_nr).split('.')
    return f"{am_pm}_{phase}_{subphase}"

def add_zero_to_date(date):
    """ 6 --> 06 """
    if len(str(date)) == 1:
        return f"0{date}"
    else:
        return date

if __name__ == '__main__':

    # all of the data clusters for all the days
    data_clusters = pd.read_csv(args.data_clusters_csv_path)
    # phases dates file
    phases_dates = pd.read_csv(args.phases_dates_csv_path)
    # list of files in the phase path
    phase_file_list = all_files_in_folder(args.phase_files_path, 'csv')
    # gpx fiile list
    gpx_paths = all_files_in_folder(args.gpx_folder_path, 'gpx')

    # updated filenames to match with gpx files
    # audio names set
    audio_names_updated = set()
    # get YYMMDD_AM unique filenames for matching with GPX FILES
    for idx, cluster_row in data_clusters.iterrows():
        audio_name = (cluster_row['AudioNames'])
        updated_name = '_'.join(audio_name.split('/')[-1].split('_')[:2])
        audio_names_updated.add(updated_name)

    # match phases with dates
    dates_phases = {}

    # match the audio files from the csv file
    for dates in list(audio_names_updated):
        # whith the file from the phases
        for idx, phases_dt in phases_dates.iterrows():
            date = add_zero_to_date(phases_dt['Date'])
            month = add_zero_to_date(phases_dt['Month'])
            datestr = f"20{month}{date}_{phases_dt['Part_of_the_Day']}"

            # get the right phase for the the right date
            if dates == datestr:
                phase_file = f"{phase_url_from_phase_nr(datestr, phases_dt['Phase'])}.csv"
                for phase_url in phase_file_list:
                    phase_url_short = phase_url.split('/')[-1]
                    if phase_url_short == phase_file:
                        dates_phases[dates] = {
                            'phase': phases_dt['Phase'], 'url': f"{phase_url.split('.')[0]}.json"}

    # create Objects containing all of the GPX data
    gpx_objects = []
    # create gpx file for each
    for gpx_file_name in gpx_paths:
        gpx_date = gpx_file_name.split('/')[-1].split('.')[0]
        try:
            curr_phase_f = dates_phases[gpx_date]['url']
        except KeyError as ke:
            continue
        with open(curr_phase_f) as f:
            phase_File = json.load(f)
        gpx_f = open(gpx_file_name, mode='r', encoding='utf-8-sig')
        curr_gpx_o = gpxobj(gpx_date, gpx_f, phase_File)
        curr_gpx_o.phase = curr_phase_f
        gpx_objects.append(curr_gpx_o)

    # match gpx files to wav dates
    for gpx_obj in gpx_objects:
        for idx, cluster_row in data_clusters.iterrows():
            match = re.search(r"[0-9]+_(?:AM|PM)", cluster_row['AudioNames'])
            if match:
                if match.group() == gpx_obj.gpx_date:
                    gpx_obj.add_chunk_path(cluster_row)

    for gpx_obj in gpx_objects:
        # sorting
        gpx_obj.chunk_paths = sorted(gpx_obj.chunk_paths, key=lambda x: int(
            x['AudioNames'].split('/')[-1].split('_')[-2]))
        # duration to millisec
        gpx_obj.duration_multi = [i*1000 for i in gpx_obj.duration]
        chunks_select = []

        # duration needs more than 100 points
        if len(gpx_obj.duration_multi) > 100:
            durations = iter(gpx_obj.duration_multi)
            curr_dur = next(durations)
            for i, chunk in enumerate(gpx_obj.chunk_paths):
                audio_chunk = int(chunk['AudioNames'].split(
                    '/')[-1].split('_')[-2]) * 960
                if audio_chunk + 960 <= curr_dur:
                    chunks_select.append(chunk)
                if audio_chunk > curr_dur:
                    gpx_obj.chunks_by_gps.append(chunks_select)
                    chunks_select = []
                    chunks_select.append(chunk)
                    try:
                        curr_dur = next(durations) + curr_dur
                    except StopIteration:
                        break

    for gpx_obj in gpx_objects:
        res = gpx_obj.to_geojson()

        with open(f"{gpx_obj.gpx_date}.json", "w") as outfile:
            json.dump(res, outfile)


import nextcord
from nextcord.ext import commands, tasks
import aiohttp
from urllib import parse

class googleit(commands.Cog, name="Google it"):
    def __init__(self,client):
        self.client = client

    @commands.command(
        name='googleit',
        aliases=['lmgt', 'letme'],
    )
    async def googleit(self, ctx, string: str):
        """Return a url link that animate a google research."""
        stringed_array = " ".join(word[:50] for word in string.split(' ')[:32])  # Maximum of 32 words, and a word has 50 chars max.
        query = parse.quote_plus(stringed_array)

        await ctx.send("The google tool is very powerful, see how it works!")
        await ctx.send(f"<https://letmegooglethat.com/?q={query}>")

def setup(client):
    client.add_cog(googleit(client))


import threading
import random
import time

class Philosopher(threading.Thread):
    running = True

    def __init__(self, _name, fork_on_left, fork_on_right):
        super(Philosopher, self).__init__()
        self.name = _name
        self.fork_on_left = fork_on_left
        self.fork_on_right = fork_on_right

    def run(self):
        while (self.running):
            time.sleep(random.uniform(3, 13))
            print('%s is hungry.' % self.name)
            self.dine()

    def dine(self):
        fork1, fork2 = self.fork_on_left, self.fork_on_right

        while self.running:
            fork1.acquire(True)
            locked = fork2.acquire(False)

            if locked:
                break

            fork1.release()
            print('%s swaps forks' % self.name)
            fork1, fork2 = fork2, fork1
        else:
            return

        self.dining()
        fork1.release()
        fork2.release()

    def dining(self):
        print('%s starts eating ' % self.name)
        time.sleep(random.uniform(1, 10))
        print('%s finishes eating and leaves to think.' % self.name)

def DiningPhilosophers():

    forks = [threading.Lock() for _ in range(5)]

    names = ['Mike', 'Bill', 'Kate', 'John', 'Patrick']

    philosophers = []

    for i in range(5):
        philosophers.append(Philosopher(names[i], fork_on_left=forks[i % 5], fork_on_right=forks[(i + 1) % 5]))

    random.seed(123)
    Philosopher.running = True

    for p in philosophers:
        p.start()

    time.sleep(50)

    Philosopher.running = False
    print("Now we're finishing.")

if __name__ == '__main__':
    DiningPhilosophers()


from flask import Flask, render_template
import sqlite3
import json
from werkzeug.exceptions import abort

app = Flask(__name__)

# funciones para conexiones a la db

def get_db_connection():
    conn = sqlite3.connect('db/database.db')
    conn.row_factory = sqlite3.Row
    return conn

def get_db_connection_by_cursor():
    conn = sqlite3.connect('db/database.db')
    return conn.cursor()

# funciones para consultas a la db (ui)

def get_all_posts_ui():
    conn = get_db_connection()
    posts = conn.execute('SELECT * FROM posts').fetchall()
    conn.close()
    if post is None:
        abort(404)
    return posts

def get_post_by_id_ui(post_id):
    conn = get_db_connection()
    post = conn.execute('SELECT * FROM posts WHERE id = ?',
                        (post_id,)).fetchone()
    conn.close()
    if post is None:
        abort(404)
    return post

# funciones para consultas a la db (post)

def get_all_posts_json():
    cursor = get_db_connection_by_cursor()
    cursor.execute('SELECT * FROM posts')
    data = cursor.fetchall()
    return json.dumps(data)

def get_post_by_id_json(post_id):
    cursor = get_db_connection_by_cursor()
    cursor.execute('SELECT * FROM posts WHERE id = ?', [post_id])
    data = cursor.fetchall()
    return json.dumps(data)

# funciones para respuestas (ui)

@app.route('/ui')
def index():
    posts = get_all_posts_ui()
    return render_template('index.html', posts=posts)

@app.route('/ui/<int:post_id>')
def post(post_id):
    post = get_post_by_id_ui(post_id)
    return render_template('post.html', post=post)

# funciones para respuestas (post)

@app.route('/json')
def indexJson():
    return get_all_posts_json()

@app.route('/json/<int:post_id>')
def postJson(post_id):
    return get_post_by_id_json(post_id)

# función index (post)

@app.route("/")
def home():
    return {
        'mensaje': '¡Flask está ejecutándose!',
        'estado': True,
        'menu': '/json, /json/?post_id',
        'menu_ui': '/ui, /ui/?post_id'
    }

if __name__ == "__main__":
    app.run(debug=True)


import heapq
class Solution:
    def findClosestElements(self, arr: List[int], k: int, x: int) -> List[int]:
        heap, res = [], []
        for i in arr:
            heapq.heappush(heap ,(abs(x-i), i))

        for _ in range(k):
            res.append(heapq.heappop(heap)[1])
        res.sort()
        return res


import openai
import sys

# save your OpenAI API key to this file
openai.api_key_path ='.Renviron'

'''
Send in the chat history and user's new input, ChatGPT gives you a response
***Input***:
- chat_history, a list of dictionary. Check https://platform.openai.com/docs/guides/chat
- user_input, a string. User's new input
- print_conversation, bool default to false. If true, print conversation in terminal
***Return***
- chat_history, a list of dictionary. It is extended based on the inputted chat_history, but with user's new input and ChatGPT's new response appended
- gpt_msg, a string, ChatGPT's new response
- total token used: a measurement of cost
'''
def chat_with_gpt(chat_history, user_input, print_conversation=False):
    suffix_phrase = ' Answer me using one sentence.'

    chat_history.append({'role': 'user', 'content': user_input + suffix_phrase})

    response = openai.ChatCompletion.create(
        model = 'gpt-3.5-turbo',
        messages=chat_history,
        temperature = 0.2
    )
    chat_history[-1] = {'role': 'user', 'content': user_input}

    gpt_msg = response['choices'][0]['message']['content']
    chat_history.append({'role': 'system', 'content': gpt_msg})

    if print_conversation:
        print(f'User:\n{user_input}')
        print(f'ChatGPT:\n{gpt_msg}')

    return chat_history, gpt_msg, response['usage']['total_tokens']

'''
This function will setup the beginning of a chat scenario
Input:
- scenario_idx: int
Output:
- a list of dictionary (in this case, there is only one element in the list). The list contains the chat history. This chat history should be fed into the chat_with_gpt function
'''
def setup_chat(scenario_idx=0):
    scenarios = [
        'You will be my Economy professor. I am in your office hour.',
        'You are my roommate. We are doing grocery shopping in Trader Joe\'s.',
        'You are my boyfriend. We are having a date in a restaurant.'
        ]

    return [{'role': 'user', 'content':scenarios[scenario_idx]}]

'''
This function corrects the grammar mistake using GPT3
Input:
- content: the sentence that wants to be checked
Output:
- the sentence with correct grammar
'''
def grammar_check(content):
    prefix_phrase = 'Correct the following sentence\'s grammar: '

    response = openai.Completion.create(
        model = 'text-curie-001',
        prompt = prefix_phrase + content,
        temperature=0
    )

    return response['choices'][0]['text']

if __name__ == '__main__':
    chat_history = setup_chat(2)
    total_tokens = 0

    while True:
        user_input = input('Enter...')

        if user_input == 'exit()':
            break
        else:
            chat_history, gpt_msg, token_used = chat_with_gpt(chat_history, user_input, print_conversation=True)
            total_tokens += token_used

    print(f'Token used in this conversation = {token_used}')