import sys
import traceback

import network
import utils

IS_MISSING = -1

def approxEqual(value, target, tolerance):
   if (abs(target) <= tolerance ): return abs(value) <= tolerance
   return abs(float(value) / target - 1) <= tolerance

def check(name, value, target, tolerance):
   if approxEqual(value, target, tolerance):
      return True
   else:
      print("\nWrong %s: your value %f, correct value %f"
               % (name, value, target))
      return False

def checkExact(name, value, target):
   if value == target:
      return True
   else:
      print("\nWrong %s: your value %s, correct value %s"
               % (name, value, target))
      return False

def TDSP(testFileName):

   print("Running TDSP test: " + str(testFileName) + "...", end='')

   try:
      with open(testFileName, "r") as testFile:
         # Read test information
         try:
            fileLines = testFile.read().splitlines()
            pointsPossible = IS_MISSING
            networkFile = IS_MISSING
            origin = IS_MISSING
            departureTime = IS_MISSING
            correctCost = IS_MISSING
            travelTimes = dict()
            correctBacklink = IS_MISSING
            for line in fileLines:
               # Ignore comments and blank lines
               if len(line.strip()) == 0 or line[0] == '#':
                  continue

               # Set points possible
               if pointsPossible == IS_MISSING:
                  pointsPossible = int(line)
                  continue

               # Set network file
               if networkFile == IS_MISSING:
                  networkFile = line
                  testNetwork = network.Network(networkFile)
                  continue

               # Set origin/departure time
               if origin == IS_MISSING:
                  inputs = line.split(",")
                  origin = int(inputs[0])
                  departureTime = int(inputs[1])
                  continue

               # Set time-dependent travel times
               if len(travelTimes) < testNetwork.numLinks:
                  inputs = line.split(",")
                  testNetwork.links[inputs[0]].travelTime = [int(x) for x in inputs[1:]]
                  travelTimes[inputs[0]]  = True
                  continue

               # Set correct cost labels
               if correctCost == IS_MISSING:
                  inputs = line.split(",")
                  correctCost = [int(x) for x in inputs]
                  continue

               # Set correct backlink labels
               if correctBacklink == IS_MISSING:
                  inputs = line.split(",")
                  correctBacklink = inputs
                  continue

         except:
            print("\nError running test %s, attempting to continue with remaining tests.  Exception details: " % testFileName)
            traceback.print_exc(file=sys.stdout)
            return 0, 0

         # Now run the actual test
         try:
            (studentCost, studentBacklink) = testNetwork.TDSP(origin - 1, departureTime)
            numCorrect = 0
            for i in range(testNetwork.numNodes):
               numCorrect += 1 if check("Node %d cost" % (i+1), studentCost[i], correctCost[i], 0.01)  else 0
               numCorrect += 1 if checkExact("Node %d backlink" % (i+1), studentBacklink[i], correctBacklink[i]) else 0
         except utils.NotYetAttemptedException:
            print("...not yet attempted")
            return 0, pointsPossible
         except:
            print("\nException raised, attempting to continue:")
            traceback.print_exc(file=sys.stdout)
            print("\n...fail")
            return 0, pointsPossible

         if numCorrect < 2 * testNetwork.numNodes:
            print("...fail")
         else:
            print("...pass")
         return pointsPossible * (numCorrect / float(2 * testNetwork.numNodes) ), pointsPossible

   except IOError:
      print("\nError running test %s, attempting to continue with remaining tests.  Exception details: " % testFileName)
      traceback.print_exc(file=sys.stdout)
      return 0, 0

def convexCombo(testFileName):

   print("Running convex combinations test: " + str(testFileName) + "...", end='')

   try:
      with open(testFileName, "r") as testFile:
         # Read test information
         try:
            fileLines = testFile.read().splitlines()
            pointsPossible = IS_MISSING
            networkFile = IS_MISSING
            stepSize = IS_MISSING
            originalPathFlows = dict()
            targetPathFlows = dict()
            correctPathFlows = dict()
            for line in fileLines:
               # Ignore comments and blank lines
               if len(line.strip()) == 0 or line[0] == '#':
                  continue

               # Set points possible
               if pointsPossible == IS_MISSING:
                  pointsPossible = int(line)
                  continue

               # Set network file
               if networkFile == IS_MISSING:
                  networkFile = line
                  testNetwork = network.Network(networkFile)
                  continue

               # Set step size
               if stepSize == IS_MISSING:
                  stepSize = float(line)
                  continue

               # Set original path flows
               if len(originalPathFlows) < sum(len(OD.paths) for OD in testNetwork.ODs):
                  inputs = line.split(",")
                  path = tuple(inputs[:-testNetwork.timeHorizon])
                  flows = inputs[-testNetwork.timeHorizon:]
                  testNetwork.pathFlows[path] = [float(x) for x in flows]
                  originalPathFlows[path]  = True
                  continue

               # Set target path flows
               if len(targetPathFlows) < sum(len(OD.paths) for OD in testNetwork.ODs):
                  inputs = line.split(",")
                  path = tuple(inputs[:-testNetwork.timeHorizon])
                  flows = inputs[-testNetwork.timeHorizon:]
                  targetPathFlows[path] = [float(x) for x in flows]
                  continue

               # Set correct path flows
               if len(correctPathFlows) < sum(len(OD.paths) for OD in testNetwork.ODs):
                  inputs = line.split(",")
                  path = tuple(inputs[:-testNetwork.timeHorizon])
                  flows = inputs[-testNetwork.timeHorizon:]
                  correctPathFlows[path] = [float(x) for x in flows]
                  continue

         except:
            print("\nError running test %s, attempting to continue with remaining tests.  Exception details: " % testFileName)
            traceback.print_exc(file=sys.stdout)
            return 0, 0

         # Now run the actual test
         try:
            testNetwork.updatePathFlows(targetPathFlows, stepSize)
            numCorrect = 0
            for path in targetPathFlows:
               for t in range(testNetwork.timeHorizon):
                  numCorrect += 1 if check("Path %s flow at time %d" % (path, t), testNetwork.pathFlows[path][t], correctPathFlows[path][t], 0.01)  else 0
         except utils.NotYetAttemptedException:
            print("...not yet attempted")
            return 0, pointsPossible
         except:
            print("\nException raised, attempting to continue:")
            traceback.print_exc(file=sys.stdout)
            print("\n...fail")
            return 0, pointsPossible

         if numCorrect < len(targetPathFlows) * testNetwork.timeHorizon:
            print("...fail")
         else:
            print("...pass")
         return pointsPossible * (numCorrect / float(len(targetPathFlows) * testNetwork.timeHorizon) ), pointsPossible

   except IOError:
      print("\nError running test %s, attempting to continue with remaining tests.  Exception details: " % testFileName)
      traceback.print_exc(file=sys.stdout)
      return 0, 0


#!/usr/bin/python3

import numpy as np

import argparse
import logging
import os

import models
import utils

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

POSTURES_TRAINING_DATA = './data/postures/D_train.csv'
POSTURES_TEST_DATA = './data/postures/D_test.csv'

LOGGER = logging.getLogger('main')
LOGGER.setLevel(logging.INFO)
LOGGER_CH = logging.StreamHandler()
LOGGER_CH.setFormatter(logging.Formatter('[%(asctime)s] [%(levelname)s] [%(name)s] %(message)s'))
LOGGER_CH.setLevel(logging.INFO)
LOGGER.addHandler(LOGGER_CH)

def main(clf):
    x_train, y_train = utils.load_csv(POSTURES_TRAINING_DATA, feature_idx = range(2, 39), label_idx = 1)
    x_test, y_test = utils.load_csv(POSTURES_TEST_DATA, feature_idx = range(2, 39), label_idx = 1)
    model = models.PosturesEstimator(clf, aggregation = True, knn_n_neighbors = 9, \
        svm_c = 10 ** 0.6, svm_gamma = 10 ** -2.0, \
        nn_validation = True)

    assert len(x_train) == len(y_train) and len(x_test) == len(y_test), 'Data size not match'

    model.fit(x_train, y_train)
    acc_train = model.evaluate(x_train, y_train, cm = 'training.png')
    LOGGER.info('Training Accuracy: %.6f' % acc_train)

    acc_cv = model.cross_validate(x_train, y_train)
    if acc_cv is not None:
        LOGGER.info('Cross Validation Accuracy: %.6f ± %.6f' % (np.mean(acc_cv), np.std(acc_cv)))

    acc_test = model.evaluate(x_test, y_test, cm = 'test.png')
    LOGGER.info('Test Accuracy: %.6f' % acc_test)

if (__name__ == '__main__'):
    parser = argparse.ArgumentParser()
    parser.add_argument('--clf', help = 'Classifier')
    args = parser.parse_args()

    try:
        main(args.clf)
    except RuntimeError as e:
        print('RuntimeError raised\n', e.args)
        exit(1)
    exit(0)


"""The form for the settings."""

import curses
from general.functions import can_be_dir
from general.functions import acc_list_to_multiline
from general.functions import multiline_to_acc_list
from general.functions import move_list_entry
import npyscreen

class AfaListAction(npyscreen.MultiLineAction):
    """List holding the afa templates."""

    def __init__(self, *args, **kwargs):
        """Initialize the class."""
        super(AfaListAction, self).__init__(*args, **kwargs)

        # set up key shortcuts
        self.add_handlers({
            curses.KEY_IC: self.add_afa_entry,
            curses.KEY_DC: self.delete_afa_entry
        })

    def update_values(self):
        """Update values and refresh view."""
        self.values = self.parent.parentApp.S.get_afa_table()

        self.display()
        self.clear_filter()

    def add_afa_entry(self, keypress=None):
        """Add AfA entry."""
        # get the input from user
        name = npyscreen.notify_input(
            'Name of AfA entry:'
        )

        if not name:
            return

        account = npyscreen.notify_input(
            'Account string:',
            pre_text='afa'
        )

        if not account:
            return

        years = npyscreen.notify_input(
            'Years for AfA:'
        )

        if not years:
            return

        got_it = self.parent.parentApp.S.add_afa_table(
            name=name,
            account=account,
            years=years
        )

        if not got_it:
            npyscreen.notify_confirm(
                'Could not add the AfA table entry, sorry.',
                form_color='WARNING'
            )

        self.update_values()

    def delete_afa_entry(self, keypress=None):
        """Delete AfA entry."""
        # cancel if there are no values
        if len(self.values) < 1:
            return False

        selected = self.values[self.cursor_line]

        really = npyscreen.notify_yes_no(
            'Really delete template "{}"?'.format(selected['name'])
        )

        if really:
            deleted = self.parent.parentApp.S.del_afa_table(index=self.cursor_line)

            if not deleted:
                npyscreen.notify_confirm(
                    'Could not delete the entry, sorry!',
                    form_color='WARNING'
                )

            self.update_values()

    def display_value(self, vl):
        """Display the value."""
        return '[{}]'.format(vl['name'])

    def actionHighlighted(self, act_on_this, keypress):
        """Do something, because a key was pressed."""
        # cancel if there are no values
        if len(self.values) < 1:
            return False

        # get the input from user
        name = npyscreen.notify_input(
            'Name of AfA entry:',
            pre_text=act_on_this['name']
        )

        if not name:
            return

        account = npyscreen.notify_input(
            'Account string:',
            pre_text=act_on_this['account']
        )

        if not account:
            return

        years = npyscreen.notify_input(
            'Years for AfA:',
            pre_text=str(act_on_this['years'])
        )

        if not years:
            return

        got_it = self.parent.parentApp.S.add_afa_table(
            name=name,
            account=account,
            years=years
        )

        if not got_it:
            npyscreen.notify_confirm(
                'Could not modify the AfA table entry, sorry.',
                form_color='WARNING'
            )
        else:
            # delete the old entry
            deleted = self.parent.parentApp.S.del_afa_table(index=self.cursor_line)

            if not deleted:
                npyscreen.notify_confirm(
                    'Something went wrong, sorry!',
                    form_color='WARNING'
                )

        self.update_values()

class TitleAfaList(npyscreen.TitleMultiLine):
    """Inherit from TitleMultiLine, but get MultiLineAction."""

    _entry_type = AfaListAction

class PostingList(npyscreen.MultiLineEditable):
    """PostingList holding teh posts."""

    def __init__(self, *arg, **kwargs):
        """Initialize the class."""
        super(PostingList, self).__init__(*arg, **kwargs)

        # set up key shortcuts
        self.add_handlers({
            '+': self.move_up,
            '-': self.move_down
        })

        # set up additional multiline options
        self.scroll_exit = True

    def move_up(self, keypress=None):
        """Move selected offer up in the list."""
        lis = self.values

        # cancel if list is < 2
        if len(lis) < 2:
            return False

        # move selected item up
        new_index = move_list_entry(
            lis=lis,
            index=self.cursor_line,
            direction=1
        )

        self.cursor_line = new_index

    def move_down(self, keypress=None):
        """Move selected offer down in the list."""
        lis = self.values

        # cancel if list is < 2
        if len(lis) < 2:
            return False

        # move selected item up
        new_index = move_list_entry(
            lis=lis,
            index=self.cursor_line,
            direction=-1
        )

        self.cursor_line = new_index

class TitleMultiLineEdit(npyscreen.TitleText):
    """Titled MultiLineEdit"""

    _entry_type = PostingList

class SettingsForm(npyscreen.FormMultiPageActionWithMenus):
    """Form for the settings."""

    def __init__(self, *args, **kwargs):
        """Initialize the class."""
        super(SettingsForm, self).__init__(*args, **kwargs)

        # set up key shortcuts
        self.add_handlers({
            '^O': self.on_ok,
            '^Q': self.on_cancel
        })

    def add_afa(self):
        """Add afa table entry."""
        self.afa_table.entry_widget.add_afa_entry()

    def del_afa(self):
        """Delete afa table entry."""
        self.afa_table.entry_widget.delete_afa_entry()

    def exit(self):
        """Exit the programm."""
        self.parentApp.setNextForm(None)
        self.parentApp.switchFormNow()

    def create(self):
        """Create the form."""
        # create the menu
        self.m = self.new_menu(name='Menu')
        self.m.addItem(text='Add afa entry', onSelect=self.add_afa, shortcut='a')
        self.m.addItem(text='Del afa entry', onSelect=self.del_afa, shortcut='d')
        self.m.addItem(text='Exit', onSelect=self.exit, shortcut='e')

        # create input widgets
        self.data_path = self.add_widget_intelligent(
            npyscreen.TitleFilenameCombo,
            name='Data path:',
            begin_entry_at=26
        )
        self.ledger_path = self.add_widget_intelligent(
            npyscreen.TitleFilenameCombo,
            name='Ledger path:',
            begin_entry_at=26
        )
        self.def_state = self.add_widget_intelligent(
            npyscreen.TitleSelectOne,
            name='Default state:',
            begin_entry_at=26,
            values=['*', '!'],
            value=[0],
            slow_scroll=True,
            scroll_exit=True,
            max_height=2
        )
        self.def_code = self.add_widget_intelligent(
            npyscreen.TitleText,
            name='Default code:',
            begin_entry_at=26
        )
        self.def_payee = self.add_widget_intelligent(
            npyscreen.TitleText,
            name='Default payee:',
            begin_entry_at=26
        )
        self.def_commodity = self.add_widget_intelligent(
            npyscreen.TitleText,
            name='Default commodity:',
            begin_entry_at=26
        )
        self.def_postings = self.add_widget_intelligent(
            TitleMultiLineEdit,
            name='Default postings:',
            begin_entry_at=26,
            max_height=4
        )
        self.def_force_add = self.add_widget_intelligent(
            npyscreen.TitleMultiSelect,
            name='Force adding:',
            begin_entry_at=26,
            values=['enabled'],
            max_height=2,
            scroll_exit=True
        )
        self.dec_separator = self.add_widget_intelligent(
            npyscreen.TitleText,
            name='Decimal separator:',
            begin_entry_at=26
        )
        self.date_separator = self.add_widget_intelligent(
            npyscreen.TitleText,
            name='Date separator:',
            begin_entry_at=26
        )
        self.date_fmt = self.add_widget_intelligent(
            npyscreen.TitleText,
            name='Date format:',
            begin_entry_at=26
        )
        self.ledger_file = self.add_widget_intelligent(
            npyscreen.TitleText,
            name='Ledger file:',
            begin_entry_at=26
        )
        self.split_years_to_files = self.add_widget_intelligent(
            npyscreen.TitleMultiSelect,
            name='Split years to files:',
            begin_entry_at=26,
            values=['enabled'],
            max_height=2,
            scroll_exit=True
        )
        self.afa_threshold_amount = self.add_widget_intelligent(
            npyscreen.TitleText,
            name='AfA threshold amount:',
            begin_entry_at=26
        )
        self.afa_table = self.add_widget_intelligent(
            TitleAfaList,
            name='AfA table:',
            begin_entry_at=26,
            scroll_exit=True
        )

    def beforeEditing(self):
        """Get values from settings object."""
        # change name and color according to the settings
        if self.parentApp.S._got_arguments:
            self.name = (
                'Ledgeradd > Settings (arguments altered settings - cannot save!'
            )
            self.color = 'DANGER'
        else:
            self.name = 'Ledgeradd > Settings'
            self.color = 'FORMDEFAULT'

        self.data_path.value = self.parentApp.S.data_path
        self.ledger_path.value = self.parentApp.S.ledger_path
        self.def_state.value = [self.def_state.values.index(self.parentApp.S.def_state)]
        self.def_code.value = self.parentApp.S.def_code
        self.def_payee.value = self.parentApp.S.def_payee
        self.def_commodity.value = self.parentApp.S.def_commodity

        self.def_postings.entry_widget.values = acc_list_to_multiline(
            self.parentApp.S.get_def_postings()
        )

        self.def_force_add.value = (
            [0] if self.parentApp.S.get_def_force_add() else []
        )

        self.dec_separator.value = self.parentApp.S.dec_separator
        self.date_separator.value = self.parentApp.S.date_separator
        self.date_fmt.value = self.parentApp.S.date_fmt
        self.ledger_file.value = self.parentApp.S.ledger_file
        self.split_years_to_files.value = (
            [0] if self.parentApp.S.get_split_years_to_files() else []
        )
        self.afa_threshold_amount.value = str(self.parentApp.S.get_afa_threshold_amount())
        self.afa_table.entry_widget.update_values()

    def on_ok(self, keypress=None):
        """Do something because user pressed ok."""
        # get values into temp variables
        data_path = self.data_path.value.rstrip('/')
        ledger_path = self.ledger_path.value.rstrip('/')

        # check correctness of values
        data_path_correct = can_be_dir(data_path)
        ledger_path_correct = can_be_dir(ledger_path)

        # dir is not creatable
        if not data_path_correct or not ledger_path_correct:
            message = npyscreen.notify_ok_cancel(
                'Data/ledger path is no valid folder name! Please change it!',
                title='Wrong folder names!',
                form_color='WARNING'
            )
            if message:
                # ok, I will edit them again
                self.editing = True
            else:
                # no, I will go back to main screen
                self.editing = False
                # swtich back
                self.parentApp.setNextForm('MAIN')
                self.parentApp.switchFormNow()

        # it is creatable, set new values to settings object
        else:
            # new values
            self.parentApp.S.data_path = data_path
            self.parentApp.S.ledger_path = ledger_path

            # defaults
            self.parentApp.S.def_state = self.def_state.values[self.def_state.value[0]]
            self.parentApp.S.def_code = self.def_code.value
            self.parentApp.S.def_payee = self.def_payee.value
            self.parentApp.S.def_commodity = self.def_commodity.value
            self.parentApp.S.set_def_postings(
                multiline_to_acc_list(self.def_postings.entry_widget.values)
            )
            self.parentApp.S.set_def_force_add(
                True if self.def_force_add.value == [0] else False
            )

            # formatting
            self.parentApp.S.dec_separator = self.dec_separator.value
            self.parentApp.S.date_separator = self.date_separator.value
            self.parentApp.S.date_fmt = self.date_fmt.value

            # file
            self.parentApp.S.ledger_file = self.ledger_file.value
            self.parentApp.S.set_split_years_to_files(
                True if self.split_years_to_files.value == [0] else False
            )

            # afa
            self.parentApp.S.set_afa_threshold_amount(self.afa_threshold_amount.value)
            self.parentApp.S.set_afa_table(self.afa_table.entry_widget.values)

            # store it
            self.parentApp.S.save_settings_to_file()

            # switch back
            self.parentApp.setNextForm('MAIN')
            self.parentApp.switchFormNow()

    def on_cancel(self, keypress=None):
        """Go back without changing a thing."""
        # swtich back
        self.parentApp.setNextForm('MAIN')
        self.parentApp.switchFormNow()


from mne.time_frequency import psd_welch
import numpy as np
import pandas as pd
import torch
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix
import itertools

# https://mne.tools/dev/auto_tutorials/sample-datasets/plot_sleep.html#sphx-glr-auto-tutorials-sample-datasets-plot-sleep-py%00
def eeg_power_band(epochs):
    """EEG relative power band feature extraction.

    This function takes an ``mne.Epochs`` object and creates EEG features based
    on relative power in specific frequency bands that are compatible with
    scikit-learn.

    Parameters
    ----------
    epochs : Epochs
        The data.

    Returns
    -------
    X : numpy array of shape [n_samples, 5]
        Transformed data.
    """
    # specific frequency bands
    FREQ_BANDS = {"delta": [0.5, 4.5],
                  "theta": [4.5, 8.5],
                  "alpha": [8.5, 11.5],
                  "sigma": [11.5, 15.5],
                  "beta": [15.5, 30]}

    psds, freqs = psd_welch(epochs, picks='eeg', fmin=0.5, fmax=30.)
    # Normalize the PSDs
    psds /= np.sum(psds, axis=-1, keepdims=True)

    X = []
    for fmin, fmax in FREQ_BANDS.values():
        psds_band = psds[:, :, (freqs >= fmin) & (freqs < fmax)].mean(axis=-1)
        X.append(psds_band.reshape(len(psds), -1))

    return np.concatenate(X, axis=1)

def get_series_and_features(epochs, channels):
    """
    this is to extract label, raw signal and calcuate time domain feature from decrypted edf data
    """
    epoch_dfs = []
    time_features = {"time_min": [], "time_max": [], "time_std": [], "time_kurtosis": [], "time_median": []}
    labels = np.ones(len(epochs))
    for i in range(len(epochs)):
        print("{}th epoch started to be processed.".format(i))
        epoch = epochs[i]
        epoch_df = epoch.to_data_frame()
        epoch_df = epoch_df[channels]
        epoch_dfs.append(epoch_df)
        time_features["time_min"].append(epoch_df.min())
        time_features["time_max"].append(epoch_df.max())
        time_features["time_std"].append(epoch_df.std())
        time_features["time_kurtosis"].append(epoch_df.kurtosis())
        time_features["time_median"].append(epoch_df.median())
        label = list(epoch.event_id.values())[0]
        labels[i] = label
    for key, value in time_features.items():
        new_df = pd.concat(time_features[key], axis=1).transpose()
        new_df.reset_index(drop=True, inplace=True)
        orig_columns = list(new_df.columns)
        new_columns = [column + "_" + key for column in orig_columns]
        new_df.columns = new_columns
        time_features[key] = new_df
    dfs = list(time_features.values())
    time_feature_df = pd.concat(dfs, axis=1)
    return epoch_dfs, time_feature_df, labels

def to_tensor(list_data, device, type="float"):
    """
    function to change from a list to corresponding tenor
    """
    if type == "float":
        return torch.from_numpy(list_data).float().to(device, non_blocking=True)
    elif type == "int":
        return torch.from_numpy(list_data).int().to(device, non_blocking=True)
    elif type == "long":
        return torch.from_numpy(list_data).long().to(device, non_blocking=True)

def plot_confusion_matrix(true_y_label, pred_y_label, class_names, tag, dataset):
    """
    function to plot confusion matrix
    """
    internalMatrixFunction = confusion_matrix(true_y_label, pred_y_label)
    filename = "plot/confusion_" + tag + "_" + str(dataset) + ".png"
    cm = internalMatrixFunction.astype('float') / internalMatrixFunction.sum(axis=1)[:, np.newaxis]
    fig = plt.figure(figsize=(12, 8), tight_layout=True)
    ax = fig.add_subplot(111)
    cax = plt.imshow(cm, interpolation='nearest', cmap=plt.get_cmap('Blues'))
    format_type = '.2f'
    max_limit = cm.max() / 2.
    for x, y in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(y, x, format(cm[x, y], format_type), horizontalalignment="center",
                 color="white" if cm[x, y] > max_limit else "black")
    plt.title('Confusion matrix of the classifier')
    fig.colorbar(cax)
    checkered_boxes = np.arange(len(class_names))
    plt.xticks(checkered_boxes, class_names)
    plt.yticks(checkered_boxes, class_names)
    plt.xlabel('Predicted')
    plt.ylabel('True')
    fig.savefig(filename, dpi=fig.dpi)
    pass


import time

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

from batterycontroller import BatteryController
from central_planner import solve_bat

def get_cost(load, price_buy, price_sell):
    cost = 0
    for l, pb, ps in zip(load, price_buy, price_sell):
        cost += l * pb if l > 0 else l * ps
    return cost

def plot_results(df, day):

    df_ = df[df.date == day].copy()

    net_load = df_[df.type == "load"].iloc[:, 4:].values.sum(axis=0)
    net_batt = df_[df.type == "batt"].iloc[:, 4:].values.sum(axis=0)
    net_cng = df_[df.type == "central_gn"].iloc[:, 4:].values.sum(axis=0)
    net_cgl = df_[df.type == "central_gl"].iloc[:, 4:].values.sum(axis=0)
    net_cgb = df_[df.type == "central_gb"].iloc[:, 4:].values.sum(axis=0)
    fig, ax = plt.subplots()
    ax.plot(net_load, label="Net load {0}".format(np.abs(net_load).sum()))
    ax.plot(net_batt, label="Net batt {0}".format(np.abs(net_batt).sum()))
    ax.plot(net_cng, label="Net cng {0}".format(np.abs(net_cng).sum()))
    ax.plot(net_cgl, label="Net cgl {0}".format(np.abs(net_cgl).sum()))
    ax.plot(net_cgb, label="Net cgb {0}".format(np.abs(net_cgb).sum()))

    ax.legend()

def run_exp():

    ## Config

    SUN_TIMES = (15, 30)
    randomstate = np.random.RandomState(1234)
    T = 48

    price_1 = np.ones(T) * 12.0
    price_1[T // 2 :] = 16.0
    price_2 = np.ones(T) * 14.0
    price_s = np.ones(T) * 10.0

    b_max = 13
    b_min = 0
    e_c = 0.95
    e_d = 0.95
    d_max = 3
    d_min = -3
    battery = BatteryController(0, b_max, b_min, e_c, e_d, d_max, d_min)

    ## Reading data

    df = pd.read_csv("customers_data.csv")
    df["day"] = df.date.map(lambda x: x[:10])

    days_list = df.day.unique()
    users_list = df.customer.unique()
    N = len(users_list)

    ## Processing

    dataset = []

    start = time.time()

    for day in days_list[:5]:

        loads_ = []
        pss_ = []
        pbs_ = []
        costs_load_ = []
        costs_batt_ = []
        for i, user in enumerate(users_list[:]):

            load = df[(df.customer == user) & (df.day == day)].power.values.copy()
            solar = np.zeros_like(load)
            if i < N // 2:
                solar[SUN_TIMES[0] : SUN_TIMES[1]] = randomstate.uniform(
                    -1, 0, SUN_TIMES[1] - SUN_TIMES[0]
                )

            load += solar

            if (i > N // 4) and (i < N // 2):
                pb = price_2
            else:
                pb = price_1
            ps = price_s

            status, obj_bat, sol_bat = battery.find_optimal_step(load, pb, ps)
            if status != "optimal":
                raise ValueError("Optimization problem not optimal")

            cost_load = get_cost(load, pb, price_s)
            dataset.append((day, user, "load", cost_load) + tuple(load))
            dataset.append((day, user, "batt", obj_bat) + tuple(sol_bat + load))

            # Data for central planner
            loads_.append(load.copy())
            pbs_.append(pb.copy())
            pss_.append(ps.copy())
            costs_load_.append(cost_load)
            costs_batt_.append(obj_bat)

        status, obj, sol, om = solve_bat(
            loads_, pbs_, pss_, costs_load_, 0, 13, 0, 0.95, 0.95, 3, -3
        )
        if status != "optimal":
            raise ValueError("The big problem in day {0} broke".format(day))

        for i, s in enumerate(sol):
            net = (s + loads_[i]).copy()
            cost_ = get_cost(net, pbs_[i], pss_[i])
            dataset.append((day, users_list[i], "central_gl", cost_) + tuple(net))

        status, obj, sol, om = solve_bat(
            loads_, pbs_, pss_, costs_batt_, 0, 13, 0, 0.95, 0.95, 3, -3
        )
        if status != "optimal":
            raise ValueError("The big problem in day {0} broke".format(day))

        for i, s in enumerate(sol):
            net = (s + loads_[i]).copy()
            cost_ = get_cost(net, pbs_[i], pss_[i])
            dataset.append((day, users_list[i], "central_gb", cost_) + tuple(net))

        status, obj, sol, om = solve_bat(
            loads_, pbs_, pss_, [None] * len(loads_), 0, 13, 0, 0.95, 0.95, 3, -3
        )
        if status != "optimal":
            raise ValueError("The big problem in day {0} broke".format(day))

        for i, s in enumerate(sol):
            net = (s + loads_[i]).copy()
            cost_ = get_cost(net, pbs_[i], pss_[i])
            dataset.append((day, users_list[i], "central_gn", cost_) + tuple(net))

    columns = ["date", "user", "type", "cost"] + ["var{0}".format(x) for x in range(48)]
    final_dataset = pd.DataFrame(dataset)
    final_dataset.columns = columns

    elapsed = time.time() - start
    print("Elapsed time: {0}".format(elapsed))

    final_dataset.to_csv("final_dataset.csv", index=False)

if __name__ == "__main__":
    run_exp()


from flask import render_template, request, abort, Blueprint, redirect, url_for
from flask_login import login_user, login_required, logout_user
from pydantic import ValidationError

from users.data.login_form import LoginData
from users.services import user_service

blueprint = Blueprint('users', __name__, template_folder='templates')

@blueprint.route('/', methods=["GET"])
def login_get():
    return render_template("login.html")

@blueprint.route('/login', methods=["POST"])
def login_post():
    try:
        data = LoginData(**request.json)
        user = user_service.login(data.username, data.password)
        if not user:
            raise abort(404)

        login_user(user)

        return redirect(url_for('transfers.list_'))

    except ValidationError as e:
        return {"form_errors": e.json()}, 400

@blueprint.route('/logout', methods=["GET"])
@login_required
def logout():
    logout_user()
    return redirect(url_for("users.login_get"))


# -*- coding: utf-8 -*-
# BMS  dlg_draw  show the voltage of battery;

import sys
import random
import numpy as np
import array
import random
import pyqtgraph as pg
from PyQt5.QtWidgets import QApplication, QLabel, QWidget, QPushButton, QVBoxLayout,QGridLayout,QCheckBox,QLineEdit
from PyQt5.QtWidgets import QLayout
from PyQt5.QtCore import QTimer

#idx=0
rand1=random.randint(0,800)
rand2=random.randint(0,100)
vol=[3.5, 3.8, 3.6, 3.7,3.9,3.6,3.8,3.5]
checked=[True,True,True,True,True,True,True,True]
class dlg_qt_draw(QWidget):
    def __init__(self,parent=None):
        super(dlg_qt_draw, self).__init__()
        self.draw2()
        self.initui()

    def draw2(self):
        self.plt2=pg.PlotWidget()
        self.tim1=QTimer()
        self.tim1.timeout.connect(self.update)
        self.tim1.start(100)

        self.x=500
        self.plt2.setRange(xRange=[0,self.x],yRange=[0,5],padding=0)
        self.dat0=[array.array('d'),array.array('d'),array.array('d'),array.array('d'),array.array('d'),array.array('d'),array.array('d'),array.array('d')]
        self.curve0=self.plt2.plot(pen='y')
        self.curve1=self.plt2.plot(pen='r')
        self.curve2=self.plt2.plot(pen='b')
        self.curve3=self.plt2.plot(pen='g')
        self.curve4=self.plt2.plot(pen='y')
        self.curve5=self.plt2.plot(pen='r')
        self.curve6=self.plt2.plot(pen='b')
        self.curve7=self.plt2.plot(pen='g')

    def update(self):
        #global idx
        global rand1,rand2
        global vol
        if rand1%10==0:
            tmp=rand1%8
            if rand2>50:      vol[tmp]=vol[tmp]+0.01
            if rand2<5:      vol[tmp]=vol[tmp]-0.01
            if vol[tmp]>4.1:  vol[tmp]=4.1
            #if vol[tmp]<3.4:  vol[tmp]=3.4
        rand1 = random.randint(0, 1800)
        rand2 = random.randint(0, 100)

        for i in range(8):
            if len(self.dat0[i])<self.x:
                self.dat0[i].append(vol[i])
            else:
                self.dat0[i][:-1]=self.dat0[i][1:]
                self.dat0[i][-1]=vol[i]

        self.curve0.setData(self.dat0[0])
        self.curve1.setData(self.dat0[1])
        self.curve2.setData(self.dat0[2])
        self.curve3.setData(self.dat0[3])
        self.curve4.setData(self.dat0[4])
        self.curve5.setData(self.dat0[5])
        self.curve6.setData(self.dat0[6])
        self.curve7.setData(self.dat0[7])
        #idx+=1;

    def initui(self):
        self.gridlayout = QGridLayout(self)
        self.gridlayout.addWidget(self.plt2, 0, 0, 16, 9)
        self.checkb = [QCheckBox("通道1"),QCheckBox("通道2"),QCheckBox("通道3"), QCheckBox("通道4"),\
            QCheckBox("通道5"), QCheckBox("通道6"), QCheckBox("通道7"), QCheckBox("通道8"),\
                QCheckBox("通道9"),QCheckBox("通道10"),QCheckBox("通道11"), QCheckBox("通道12"),\
                    QCheckBox("通道13"), QCheckBox("通道14"), QCheckBox("通道15"), QCheckBox("通道16")]
        for i in range(16):
            self.gridlayout.addWidget(self.checkb[i], i,10)
            self.checkb[i].stateChanged.connect(self.check_change)
        self.setLayout(self.gridlayout)

    def check_change(self):
        global checked
        for i in range(16):
            checked[i]=self.checkb[i].isChecked()
            #print(i,checked[i])

if __name__ == '__main__':
    app = QApplication(sys.argv)
    win= dlg_qt_draw()
    win.show()
    sys.exit(app.exec_())


import tensorflow as tf
import os
import numpy as np
from matplotlib import pylab as  plt

os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
#产生训练数据集
train_X=np.asarray([3.3,4.4,5.5,6.71,6.93,4.168,9.779,6.182,7.59,2.167,
                   7.042,10.791,5.313,7.997,5.654,9.27,3.1])
train_Y=np.asarray([1.7,2.76,2.09,3.19,1.694,1.573,3.366,2.596,2.53,1.221,
                    2.827,3.465,1.65,2.904,2.42,2.94,1.3])
n_train_sample=train_X.shape[0]
print('训练样本数量为:',n_train_sample)

test_X=np.asarray([6.83,4.668,8.9,7.91,5.7,8.7,3.1,2.1])
test_Y=np.asarray([1.84,2.273,3.2,2.831,2.92,3.24,1.35,1.03])
n_test_sample=test_X.shape[0]
print('测试样本数量为:',n_test_sample)

plt.scatter(train_X,train_Y)
plt.scatter(test_X,test_Y)
plt.show()

with tf.Graph().as_default():
    with tf.name_scope('Input'):
        X=tf.placeholder(tf.float32,name='X')
        Y_true=tf.placeholder(tf.float32,name='Y_true')
    with tf.name_scope('Inference'):
        w=tf.Variable(tf.zeros([1]),name='weight')
        b=tf.Variable(tf.zeros([1]),name='Bias')
        Y_pred=tf.add(tf.multiply(X,w),b)
    with tf.name_scope('Loss'):
        TrainLoss=tf.reduce_mean(tf.pow(Y_true-Y_pred,2))/2
    with tf.name_scope('Train'):
        Optimizer=tf.train.GradientDescentOptimizer(learning_rate=0.01)
        TrainOp=Optimizer.minimize(TrainLoss)
    with tf.name_scope('Evaluate'):
        EvalLoss=tf.reduce_mean(tf.pow(Y_true-Y_pred,2))/2

    initOp=tf.global_variables_initializer()

    writer=tf.summary.FileWriter(logdir='Log_linear_regression',graph=tf.get_default_graph())
    writer.flush()

    print('开启会话，运行计算图，训练模型！')

    with tf.Session() as sess:
        sess.run(initOp)
        for step in range(1000):         #训练1000次
            for tx,ty in zip(train_X,train_Y):
                _,train_loss,train_w,train_b=sess.run([TrainOp,TrainLoss,w,b],feed_dict={X:tx,Y_true:ty})

            if(step+1)%5==0:
                print('step:','%04d'%(step+1),'train_loss=','{:.9f}'.format(train_loss),'w=',train_w,'b=',train_b)
            if (step+1)%10==0:
                test_loss=sess.run(EvalLoss,feed_dict={X:test_X,Y_true:test_Y})
                print('step:','%04d'%(step+1),'test_loss=','{:.9f}'.format(test_loss),
                      'w=',train_w,'b=',train_b)

        print('训练完毕！！')
        w,b=sess.run([w,b])
        print('模型参数:','w=',w,'b=',b)
        train_loss=sess.run(TrainLoss,feed_dict={X:train_X,Y_true:train_Y})
        print('训练集上的损失:',train_loss)
        test_loss=sess.run(EvalLoss,feed_dict={X:test_X,Y_true:test_Y})
        print('测试集上面的损失:',test_loss)

        plt.plot(train_X, train_Y, 'ro', label='Origin Train Points')
        plt.plot(test_X, test_Y, 'b*', label='Origin Test Points')
        plt.plot(train_X, w * train_X + b, label='Fitted Line')
        plt.legend()
        plt.show()


import argparse, os, pickle, sys
sys.path.append('/home/om2382/vanilla-rtrl/')
from wrappers import cross_compare_analyzed_checkpoints

parser = argparse.ArgumentParser()
parser.add_argument('--name', dest='name')

args = parser.parse_args()

args_path = os.path.join('/home/om2382/learning-dynamics/args/', args.name)

with open(args_path, 'rb') as f:
    all_args = pickle.load(f)

compare_args = {k.split('compare_')[1]: all_args[k]
                for k in all_args.keys() if 'compare_' in k}

cross_compare_analyzed_checkpoints(args.name,
                                   compare_args=compare_args,
                                   notebook_dir=all_args['notebook_dir'])


import cv2
import numpy as np

cap = cv2.VideoCapture(0)
bars = cv2.namedWindow("bars")

def hello(x):
    pass

cv2.createTrackbar("upper_hue","bars",130,180,hello)
cv2.createTrackbar("upper_sat","bars",255,255,hello)
cv2.createTrackbar("upper_val","bars",255,255,hello)
cv2.createTrackbar("lower_hue","bars",70,180,hello)
cv2.createTrackbar("lower_sat","bars",50,255,hello)
cv2.createTrackbar("lower_val","bars",50,255,hello)

while True:
    cv2.waitKey(1000)
    ret,init_frame = cap.read()
    if ret:
        break
while True:
    _,frame = cap.read()
    inspect = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)

    upper_hue = cv2.getTrackbarPos("upper_hue", "bars")
    upper_sat = cv2.getTrackbarPos("upper_sat", "bars")
    upper_val = cv2.getTrackbarPos("upper_val", "bars")
    lower_hue = cv2.getTrackbarPos("lower_hue", "bars")
    lower_sat = cv2.getTrackbarPos("lower_sat", "bars")
    lower_val = cv2.getTrackbarPos("lower_val", "bars")
    upper_hsv = np.array([upper_hue,upper_sat,upper_val])
    lower_hsv = np.array([lower_hue,lower_sat,lower_val])

    kernel = np.ones((3,3),np.uint8)

    mask = cv2.inRange(inspect ,lower_hsv,upper_hsv)
    mask = cv2.medianBlur(mask,3)
    mask = cv2.dilate(mask,kernel)
    mask_inv = 255-mask

    b = frame[:, :, 0]
    g = frame[:, :, 1]
    r = frame[:, :, 2]

    b = cv2.bitwise_and(mask_inv, b)
    g = cv2.bitwise_and(mask_inv, g)
    r = cv2.bitwise_and(mask_inv, r)
    frame_inv = cv2.merge((b,g,r))
    b = init_frame[:, :, 0]
    g = init_frame[:, :, 1]
    r = init_frame[:, :, 2]
    b = cv2.bitwise_and(mask, b)
    g = cv2.bitwise_and(mask, g)
    r = cv2.bitwise_and(mask, r)
    blanket_area = cv2.merge((b,g,r))
    final = cv2.bitwise_or(blanket_area,frame_inv)

    cv2.imshow("Invisble cloak",final)
    cv2.imshow("Original frame",frame)

    if (cv2.waitKey(1) == 27):
        break
cv2.destroyAllWindows()
cap.release()


from typing import List

class Solution:
    def getRow(self, rowIndex: int) -> List[int]:
        if rowIndex == 0:
            return [1]
        elif rowIndex == 1:
            return [1, 1]
        lastLine = [1, 1]
        for i in range(2, rowIndex + 1):
            line = []
            for j in range(i + 1):
                if j == 0 or j == i:
                    line.append(1)
                else:
                    line.append(lastLine[j - 1] + lastLine[j])
            lastLine = line
        return line

s = Solution()
print(s.getRow(2))


"""
This script produces completions from Codex, or any model that fudges the
completions API.

To run this script, create a file called model_keys.csv with the columns:

```
Label,Model,Key
My OpenAI Key,,sk-YOUR-OPENAI-KEY
A100,codegen,http://localhost:8080/v1/completions
A40,incoder,http://localhost:8080/v1/completions
```

OpenAI API keys will only work if you are in the Codex beta.

Then run:

python3 completions_codex.py --dir <TARGET_DIR> --max-samples=32

The max_samples argument should be a reasonable number. Too small, and
you won't be using your GPU very efficently. Too high, and you'll crash
a naive implementation.
"""
import csv
import pdb
from typing import Dict
import os

import openai_multimodel_multikey
import asyncio
import tqdm.asyncio
import argparse
import json
import sys
from pathlib import Path
import logging

from dataset_builder.utils import TOFILL_TOKEN, MULTI_INTERMEDIATE_GENERATION_FLAG

MAX_TO_GENERATE = 750 # 512

# problem is a dict. Relevant keys are "name" and "prompt".
async def process_problem_json(completion, problem, args, max_to_generate):
    target_dir_path = Path(args.target_dir)
    completions_path = target_dir_path / (problem["name"] + ".json")
    os.makedirs(target_dir_path, exist_ok=True)

    if completions_path.exists():
        with completions_path.open() as f:
            try:
                completion_results = json.load(f)
            except:
                print(f"json load error {f}")
    else:
        # Copy problem to completion_results
        completion_results = problem.copy()
        completion_results["completions"] = []

    # completion_results has the same keys as problem, and one extra key "completions".
    num_completions_required = args.limit_completions - len(completion_results["completions"])

    if num_completions_required < 1:
        return

    # nicer to have print message updating status of 20 beam w/ intermediate generation
    verbose = False
    if args.max_samples == 1 and isinstance(problem["translation_prompt"], list):
        verbose = True

    while num_completions_required > 0:
        num_samples = min(num_completions_required, args.max_samples)
        prompt, prompt_idx, num_incomplete_prompts = "", 0, 0
        if "translation_prompt" not in problem:
            prompt = problem["prompt"]
        elif isinstance(problem["translation_prompt"], str):
            prompt = problem["translation_prompt"] if TOFILL_TOKEN in completion_results["translation_prompt"] else completion_results["translation_prompt"]
        elif isinstance(problem["translation_prompt"], list):
            # if there are incomplete prompts, do 1 time intermedidate generation with multiple generations to
            # generate all different intermediate steps at once, then generate the rest 1 by 1
            num_incomplete_prompts = len([p for p in completion_results["translation_prompt"] if TOFILL_TOKEN in p])

            # once all intermediate steps are generated, generate the rest 1 by 1
            prompt_idx = len(completion_results["completions"]) % len(problem["translation_prompt"])
            prompt = completion_results["translation_prompt"][prompt_idx]
            if num_incomplete_prompts > 0:
                prompt = MULTI_INTERMEDIATE_GENERATION_FLAG+prompt
                num_samples = num_incomplete_prompts
            # num_samples will be number of intermediate steps needs to generate, but entire generation number will be 1
            # assert num_samples == 1, "with multi-intermediate step, can only generate 1 sample at a time"
        else:
            raise NotImplementedError("Do not recognize translation prompt data type")
        updated_prompt, completions = await completion(
            model=args.model,
            prompt=prompt,
            max_tokens=max_to_generate,
            temperature=args.temperature,
            n=num_samples,
            top_p=0.95,
            stop=[s for s in problem["stop_tokens"]] if problem["stop_tokens"] else None,
        )
        completion_results["completions"].extend(completions)
        if "translation_prompt" in problem and updated_prompt:
            if isinstance(problem["translation_prompt"], str) and TOFILL_TOKEN in completion_results["translation_prompt"]:
                # explicitely updating the translation prompt, otherwise it is only sometimes updated, weird
                completion_results["translation_prompt"] = updated_prompt
            elif isinstance(problem["translation_prompt"], list) and num_incomplete_prompts > 0:
                # if we have list of intermediate steps, only when it's not stored, we update the corresponding prompt
                completion_results["translation_prompt"][-num_incomplete_prompts:] = updated_prompt
                if verbose:
                    print(f"Finished intermediate for {problem['name']}: num_samples_required={num_completions_required}")
                num_samples = 1
        with completions_path.open("w") as f:
            f.write(json.dumps(completion_results, indent=2))

        num_completions_required -= num_samples
        if verbose:
            print(f"completed 1 for {problem['name']}: num_samples_required={num_completions_required}")

def configure_logging(args):
    format_str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    if args.log_file:
        logging.basicConfig(
            filename=args.log_file, level=args.log_level, format=format_str
        )
    else:
        logging.basicConfig(level=args.log_level, format=format_str)

def get_args():
    args = argparse.ArgumentParser()
    args.add_argument("--prompts-file", type=str, required=True, help="File of prompts")
    args.add_argument(
        "--target-dir",
        type=str,
        required=True,
        help="Directory to write completions to",
    )
    args.add_argument("--temperature", type=float, required=True)
    args.add_argument("--max-samples", type=int, required=True)
    args.add_argument("--model", type=str, required=True)
    args.add_argument("--limit-completions", type=int, default=200)
    args.add_argument("--log-file", type=str, default=None)
    args.add_argument("--log-level", type=str, default="INFO")
    args.add_argument(
        "--local-model",
        action="store_true",
        help="If set, --model is the name of a model file to load",
    )
    args = args.parse_args()
    args.process_function = process_problem_json
    return args

async def main(args):
    prompts_file = Path(args.prompts_file)
    if not prompts_file.exists():
        print("File does not exist: {}".format(prompts_file))
        sys.exit(1)

    if args.model == "davinci":
        args.model = "code-davinci-002"

    configure_logging(args)

    with prompts_file.open() as f:
        problems = json.load(f)

    if args.local_model:
        completions = __import__(args.model).completion
        for problem in problems:
            await args.process_function(
                completions, problem, args, max_to_generate=MAX_TO_GENERATE
            )
    else:
        # Load the model keys from the CSV file.
        with open("model_keys_azure.csv") as f:
            reader = csv.DictReader(f)
            rows = list(reader)
        model_keys = [
            row["Key"] for row in rows if not row["Key"].startswith("http://")
        ]
        other_models = [
            (row["Model"], row["Key"])
            for row in rows
            if row["Key"].startswith("http://")
        ]
        async with openai_multimodel_multikey.MultiModelMultiKeyCompletion(
            model_keys, other_models
        ) as completions:
            problem_completions = [
                args.process_function(
                    completions.completion,
                    problem,
                    args,
                    max_to_generate=MAX_TO_GENERATE,
                )
                for problem in problems
            ]
            # await asyncio.gather(*problem_completions)
            pbar = tqdm.tqdm(total=len(problems))
            for f in asyncio.as_completed(problem_completions):
                value = await f
                pbar.set_description(value)
                pbar.update()

if __name__ == "__main__":
    asyncio.run(main(get_args()))


import matplotlib.pyplot as plt
import torch as th
import numpy as np

from glob import glob
from tqdm import tqdm
from time import sleep
import os

from IPython.display import clear_output
# it is needed only to refresh the losses plots by "flag_while", unnecessary.

def show(images, titles=None, cmaps=None, crops=None,
    figsize=None, fontsize=None, set_title=None):
    '''
    Makes the pleasant figure of images, optionally with custom titles, colormaps, crops.

    If the number of images to show is more than one, then "images" is supposed to be a list.
    The titles must be either a string (1 image for input) or a list of strings.
    '''
    if not isinstance(images, list):
        images = [images]

    images_recon = []
    for ind, image in enumerate(images):
        if len(image.shape) == 4:
            image = image[0]

        if not isinstance(image, np.ndarray): # assimed to be torch.Tensor
            if image.is_cuda:
                image = image.cpu()
            image = image.detach().numpy()

        if image.shape[0] == 1:
            image = image[0]

        if crops is not None:
        # assumed to be only from left-right corner
        # and only being only squared
            crop = crops[ind] if isinstance(crops, list) else crops
            image = image[..., :crop,:crop]

        images_recon.append(image)
    images = images_recon

    if fontsize is None:
        fontsize = 15

    num_images = len(images)

    if figsize is None:
        figsize = (8+num_images,8*num_images)
        if num_images == 3:
            figsize = (15,5)
        if num_images == 4:
            figsize = (20,5)

    fig, ax = plt.subplots(1, num_images, figsize=figsize)
    fig.patch.set_facecolor('white')

    if num_images == 1:
        ax = [ax]

    if cmaps is None:
        cmaps = ['depth']*num_images # Maybe, use 'gray' as default?

    elif isinstance(cmaps, str):
        cmaps = [cmaps]

    for i, (img, cmap) in enumerate(zip(images, cmaps)):
        if cmap == 'depth':
            cmap = 'jet'
        ax[i].imshow(img, cmap=cmap)
        ax[i].set_axis_off()

    # Now only titles have to be distributed.
    if titles is not None:

        if titles == 'shapes':
            titles = [str(img.shape) for img in images]

        elif isinstance(titles, str): # Title for one image
            ax[0].set_title(titles)

        if isinstance(titles, list):
            for i, title in enumerate(titles):
                ax[i].set_title(title, fontsize=fontsize)

            if len(titles) < num_images:
                for i in range(len(titles), num_images):
                    ax[i].set_title('', fontsize=fontsize)

    if set_title is not None:
        fig.suptitle(set_title, fontsize=fontsize)
    # fig.tight_layout()
    plt.subplots_adjust(wspace=0, hspace=0)
    plt.show()
    return

def show_losses(exp_name='EXP', flag_while=False, log=False, loglog=False,\
                path2folder='./saved_models/MSGNet/',\
                last_epochs=5, only_val=False):
    '''
    It is used for losses trends visulisation.
    The usage example is provided in the model_test.ipynb.
    '''

    path2folder += exp_name+'/'

    fontsize = 20
    while True:
        fig, ax = plt.subplots(1, 2, figsize=(15,5))
        train = np.load(path2folder+'train_losses.npy')
        val   = np.load(path2folder+'val_losses.npy')
        num_epochs = np.load(path2folder+'last_saved_epoch.npy')

        train_x = np.linspace(0, num_epochs, num=len(train))
        val_x   = np.linspace(0, num_epochs, num=len(val))

        train_x_last = int(len(train)/num_epochs*(num_epochs-last_epochs-1))
        val_x_last   = int(len(val)  /num_epochs*(num_epochs-last_epochs-1))

        if loglog:
            ax[0].loglog(train_x, train)
            ax[0].loglog(val_x, val)

            if not only_val:
                ax[1].loglog(train_x[train_x_last:], train[train_x_last:])
            ax[1].loglog(val_x[val_x_last:], val[val_x_last:])

        if log:
            ax[0].semilogy(train_x, train)
            ax[0].semilogy(val_x, val)

            if not only_val:
                ax[1].semilogy(train_x[train_x_last:], train[train_x_last:])
            ax[1].semilogy(val_x[val_x_last:], val[val_x_last:])

        else:
            ax[0].plot(train_x, train)
            ax[0].plot(val_x, val)

            if not only_val:
                ax[1].plot(train_x[train_x_last:], train[train_x_last:])
            ax[1].plot(val_x[val_x_last:], val[val_x_last:])

        # show only last last_epochs epochs
        ax[1].set_xlim((np.maximum(num_epochs-last_epochs, 0), num_epochs))

        if not only_val and len(val) > 0:
            min_y = np.minimum(train[train_x_last:].min(), val[val_x_last:].min())*0.9
            max_y = np.maximum(train[train_x_last:].max(), val[val_x_last:].max())*1.1
            ax[1].set_ylim(min_y, max_y)

        if min(train) > 0:
            min_val = min(val) if len(val)>0 else 0
            ax[0].set_title('min train=  {:3.3e} | min val= {:3.3e}'\
                    .format(min(train), min_val), fontsize=fontsize)
            last_val = val[-1] if len(val)>0 else 0
            ax[1].set_title('last train= {:3.3e} | last val= {:3.3e}'\
                    .format(train[-1], last_val), fontsize=fontsize)
        fig.tight_layout()
        plt.show()

        params = np.load(path2folder+'exp_params.npy').item()
        print('num images train = ', params['num_images_train'])
        print('num images val = ', params['num_images_val'])
        print('train size = {}, val size = {}'\
                .format(params['train_batchsize'], params['val_batchsize']))

        if flag_while:
            sleep(2)
            clear_output()
        else:
            break

def save_infer_imgs(exp_name, net, rgb, depth,
            mode='gaus', sigma=1, do_filtering=False,
            path2net_folder='./saved_models/MSGNet/', crop=None):
    '''
    Runs given [rgb, depth] through each saved model state
    and puts resultive images in the folder.
    '''

    path2folder = path2net_folder+exp_name+'/state_'
    state_paths = sorted(glob(path2folder+'*.pth'))
    state_names = [state_path[len(path2folder):-4] for state_path in state_paths]

    if not os.path.isdir(path2net_folder+exp_name+'/InferImgs_'+exp_name):
        os.mkdir(path2net_folder+exp_name+'/InferImgs_'+exp_name)

    for state_name, state_path in tqdm(zip(state_names, state_paths)):
        state = th.load(state_path, map_location=th.device('cpu'))
        net.load_state_dict(state['model_state_dict'])
        res = net.do_inference(rgb, depth, mode=mode, sigma=sigma,
                                    do_filtering=do_filtering)
        res[res < depth.min()] = depth.min()
        res[res > depth.max()] = depth.max()
        if crop is not None:
            res = res[:crop, :crop]
        plt.imsave(path2net_folder+exp_name+'/InferImgs_'+exp_name+'/'+state_name,
                    res, cmap='jet')


import matplotlib.pyplot as plt
import matplotlib.patches as patches
from PIL import Image
import numpy as np
import json
from collections import OrderedDict
import torch
import json

#plot bbox for prediction result, bbox_data includes the dictionary of pred_bboxes with confidence score
def plot_bbox(image, bbox_data, result_path="somewhere"):
    # image = np.array(Image.open(img_path), dtype=np.uint8)
    try:
        fig, ax = plt.subplots(1)
        ax.imshow(image)

        for bbox in bbox_data:
            x1 = bbox['xmin']
            y1 = bbox['ymin']
            x2 = bbox['xmax']
            y2 = bbox['ymax']
            score = bbox['confidence_score']
            rect = patches.Rectangle((x1, y1), x2-x1+1, y2-y1+1, linewidth=1, edgecolor='b', facecolor='none')
            ax.add_patch(rect)
            plt.text(x1, y1, score, color='red', verticalalignment='top')

        # plt.show()
        plt.axis('off')
        plt.savefig(result_path, dpi=200, bbox_inches='tight', pad_inches=0.0)
        plt.close()
    except:
        pass

def compute_IoU(boxA, boxB):
    # determine the (x, y)-coordinates of the intersection rectangle
    xA = max(boxA[0], boxB[0])
    yA = max(boxA[1], boxB[1])
    xB = min(boxA[2], boxB[2])
    yB = min(boxA[3], boxB[3])

    # compute the area of intersection rectangle
    interArea = max(0, xB - xA + 1) * max(0, yB - yA + 1)

    # compute the area of both the prediction and ground-truth
    # rectangles
    boxAArea = (boxA[2] - boxA[0] + 1) * (boxA[3] - boxA[1] + 1)
    boxBArea = (boxB[2] - boxB[0] + 1) * (boxB[3] - boxB[1] + 1)

    # compute the intersection over union by taking the intersection
    # area and dividing it by the sum of prediction + ground-truth
    # areas - the interesection area
    iou = interArea / (boxAArea + boxBArea - interArea)

    # return the intersection over union value
    return iou

def visualize_both_detection(img_path, gt_bboxs, pred_bboxs):
    img = Image.open(img_path)
    pixdata = img.load()
    (w, h) = img.size

    for bbox in gt_bboxs:
        [xmin, ymin, xmax, ymax] = bbox[1]
        xmin, ymin = max(0, xmin), max(0, ymin)
        xmax, ymax = min(w, xmax), min(h, ymax)
        xmax -= 1
        ymax -= 1
        for i in range(xmin, xmax + 1):
            for j in range(3):
                pixdata[i, ymin+j] = RED
                pixdata[i, ymax-j] = RED

        for i in range(3):
            for j in range(ymin, ymax + 1):
                pixdata[xmin+i, j] = RED
                pixdata[xmax-i, j] = RED

    for bbox in pred_bboxs:
        [xmin, ymin, xmax, ymax] = bbox[1]
        xmin, ymin = max(0, xmin), max(0, ymin)
        xmax, ymax = min(w, xmax), min(h, ymax)
        xmax -= 1
        ymax -= 1
        for i in range(xmin, xmax + 1):
            for j in range(3):
                pixdata[i, ymin+j] = BLUE
                pixdata[i, ymax-j] = BLUE

        for i in range(3):
            for j in range(ymin, ymax + 1):
                pixdata[xmin+i, j] = BLUE
                pixdata[xmax-i, j] = BLUE

    return img

def verify(x, w):
    return min(max(int(x), 0), w-1)

def get_gt_bbox(label_path):
    bboxes = list(open(label_path, 'r'))
    gt_bboxes = []
    for bbox in bboxes:
        bbox = bbox.strip().split(' ')
        bbox = [int(item) for item in bbox]

        gt_bboxes.append(bbox[:-1])

    return gt_bboxes

def visualize_bbox(image, bboxes):
    RED = (255, 0, 0)
    pixdata = image.load()
    (w, h) = image.size

    for bbox in bboxes:
        [xmin, ymin, xmax, ymax] = bbox

        for i in range(xmin, xmax + 1):
            for j in range(3):
                pixdata[i, ymin+j] = RED
                pixdata[i, ymax-j] = RED

        for i in range(3):
            for j in range(ymin, ymax + 1):
                pixdata[xmin+i, j] = RED
                pixdata[xmax-i, j] = RED

    return image

def visualize_bboxes(sk_image, bboxes, color):
    def relocate(x, t):
        x = max(0, x)
        x = min(t-1, x)
        return x
    color = np.array(color)
    (height, width, _) = sk_image.shape
    for bbox in bboxes:
        x1 = bbox['x']
        y1 = bbox['y']
        x2 = x1 + bbox['w'] - 1
        y2 = y1 + bbox['h'] - 1
        sk_image[y1:y2, relocate(x1-3, width):relocate(x1+3, width)] = color
        sk_image[y1:y2, relocate(x2-3, width):relocate(x2+3, width)] = color

        sk_image[relocate(y1-3, height):relocate(y1+3, height), x1:x2] = color
        sk_image[relocate(y2-3, height):relocate(y2+3, height), x1:x2] = color

    return sk_image

class KeepAspect(object):
    def __init__(self):
        pass

    def __call__(self, sample):
        image = sample['image']

        h, w, _ = image.shape
        dim_diff = np.abs(h - w)
        # Upper (left) and lower (right) padding
        pad1, pad2 = dim_diff // 2, dim_diff - dim_diff // 2
        # Determine padding
        pad = ((pad1, pad2), (0, 0), (0, 0)) if h <= w else ((0, 0), (pad1, pad2), (0, 0))
        # Add padding
        image_new = np.pad(image, pad, 'constant', constant_values=128)

        return {'image': image_new, 'padding': pad}

def bbox_iou(box1, box2, x1y1x2y2=True):
    """
    Returns the IoU of two bounding boxes
    """
    if not x1y1x2y2:
        # Transform from center and width to exact coordinates
        b1_x1, b1_x2 = box1[:, 0] - box1[:, 2] / 2, box1[:, 0] + box1[:, 2] / 2
        b1_y1, b1_y2 = box1[:, 1] - box1[:, 3] / 2, box1[:, 1] + box1[:, 3] / 2
        b2_x1, b2_x2 = box2[:, 0] - box2[:, 2] / 2, box2[:, 0] + box2[:, 2] / 2
        b2_y1, b2_y2 = box2[:, 1] - box2[:, 3] / 2, box2[:, 1] + box2[:, 3] / 2
    else:
        # Get the coordinates of bounding boxes
        b1_x1, b1_y1, b1_x2, b1_y2 = box1[:,0], box1[:,1], box1[:,2], box1[:,3]
        b2_x1, b2_y1, b2_x2, b2_y2 = box2[:,0], box2[:,1], box2[:,2], box2[:,3]

    # get the corrdinates of the intersection rectangle
    inter_rect_x1 =  torch.max(b1_x1, b2_x1)
    inter_rect_y1 =  torch.max(b1_y1, b2_y1)
    inter_rect_x2 =  torch.min(b1_x2, b2_x2)
    inter_rect_y2 =  torch.min(b1_y2, b2_y2)
    # Intersection area
    inter_area =    torch.clamp(inter_rect_x2 - inter_rect_x1 + 1, min=0) * \
                    torch.clamp(inter_rect_y2 - inter_rect_y1 + 1, min=0)
    # Union Area
    b1_area = (b1_x2 - b1_x1 + 1) * (b1_y2 - b1_y1 + 1)
    b2_area = (b2_x2 - b2_x1 + 1) * (b2_y2 - b2_y1 + 1)

    iou = inter_area / (b1_area + b2_area - inter_area + 1e-16)

    return iou

def non_max_suppression(prediction, num_classes, conf_thres=0.5, nms_thres=0.4):
    """
    Removes detections with lower object confidence score than 'conf_thres' and performs
    Non-Maximum Suppression to further filter detections.
    Returns detections with shape:
        (x1, y1, x2, y2, object_conf, class_score, class_pred)
    """

    # From (center x, center y, width, height) to (x1, y1, x2, y2)
    box_corner = prediction.new(prediction.shape)
    box_corner[:, :, 0] = prediction[:, :, 0] - prediction[:, :, 2] / 2
    box_corner[:, :, 1] = prediction[:, :, 1] - prediction[:, :, 3] / 2
    box_corner[:, :, 2] = prediction[:, :, 0] + prediction[:, :, 2] / 2
    box_corner[:, :, 3] = prediction[:, :, 1] + prediction[:, :, 3] / 2
    prediction[:, :, :4] = box_corner[:, :, :4]

    output = [None for _ in range(len(prediction))]
    for image_i, image_pred in enumerate(prediction):
        # Filter out confidence scores below threshold
        conf_mask = (image_pred[:, 4] >= conf_thres).squeeze()
        image_pred = image_pred[conf_mask]
        # If none are remaining => process next image
        if not image_pred.size(0):
            continue
        # Get score and class with highest confidence
        class_conf, class_pred = torch.max(image_pred[:, 5:5 + num_classes], 1,  keepdim=True)
        # Detections ordered as (x1, y1, x2, y2, obj_conf, class_conf, class_pred)
        detections = torch.cat((image_pred[:, :5], class_conf.float(), class_pred.float()), 1)
        # Iterate through all predicted classes
        unique_labels = detections[:, -1].cpu().unique()
        if prediction.is_cuda:
            unique_labels = unique_labels.cuda()
        for c in unique_labels:
            # Get the detections with the particular class
            detections_class = detections[detections[:, -1] == c]
            # Sort the detections by maximum objectness confidence
            _, conf_sort_index = torch.sort(detections_class[:, 4], descending=True)
            detections_class = detections_class[conf_sort_index]
            # Perform non-maximum suppression
            max_detections = []
            while detections_class.size(0):
                # Get detection with highest confidence and save as max detection
                max_detections.append(detections_class[0].unsqueeze(0))
                # Stop if we're at the last detection
                if len(detections_class) == 1:
                    break
                # Get the IOUs for all boxes with lower confidence
                ious = bbox_iou(max_detections[-1], detections_class[1:])
                # Remove detections with IoU >= NMS threshold
                detections_class = detections_class[1:][ious < nms_thres]

            max_detections = torch.cat(max_detections).data
            # Add max detections to outputs
            output[image_i] = max_detections if output[image_i] is None else torch.cat((output[image_i], max_detections))

    return output

def get_bbox_data(pred_bboxes_data):
    """
    input: prediction bbox list
    output: pred_bboxes, json_bboxes
    """
    pred_bboxes = pred_bboxes_data.bbox
    pred_confidences = pred_bboxes_data.extra_fields['scores']
    num_pred_bboxes = pred_bboxes.size(0)

    pred_bboxes_list = [[] for _ in range(num_pred_bboxes)]
    for i in range(num_pred_bboxes):
        pred_bbox = []
        for j in range(4):
            pred_bbox.append(int(pred_bboxes[i][j]))
        pred_bboxes_list[i] = pred_bbox
    pred_bboxes = pred_bboxes_list

    json_bboxes = {"bboxes": []}
    for pred_id, [x1, y1, x2, y2] in enumerate(pred_bboxes):
        json_bbox = OrderedDict()
        json_bbox['x1'] = x1
        json_bbox['y1'] = y1
        json_bbox['x2'] = x2
        json_bbox['y2'] = y2
        json_bbox['confidence'] = pred_confidences[pred_id].item()

        json_bboxes["bboxes"].append(json_bbox)

    return pred_bboxes, json_bboxes


'''
利用预训练的wav2vec模型，在本数据集上做VA回归任务
'''
import torch
import os
import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
from transformers import Wav2Vec2Model
from torch.nn.utils.rnn import pad_sequence
import math

import sys
sys.path.append('/data2/hzp/ABAW_VA_2022/code/')#
from models.base_model import BaseModel#
from models.networks.regressor import FcRegressor#

class Wav2vecModel(BaseModel):
    @staticmethod
    def modify_commandline_options(parser, is_train=True):
        parser.add_argument('--regress_layers', default='256', type=str,
                            help='size of classifier hidden size, split by comma')
        parser.add_argument('--dropout_rate', default=0.3, type=float, help='drop out rate')
        parser.add_argument('--loss_type', type=str, default='mse', choices=['mse', 'l1'], help='use MSEloss or L1loss')
        parser.add_argument('--task', type=str, default='v+a', choices=['v', 'a', 'v+a'], help='the task target.')
        return parser

    def __init__(self, opt, logger=None):
        """Initialize the BaselineModel class

        Parameters:
            opt (Option class)-- stores all the experiment flags; needs to be a subclass of BaseOptions
        """
        super().__init__(opt, logger)
        self.loss_names = [opt.loss_type] # get_current_losses: getattr(self, 'loss_' + name)
        self.regress_layers = list(map(lambda x: int(x), opt.regress_layers.split(',')))
        self.dropout_rate = opt.dropout_rate
        self.task = opt.task
        self.label_fps = 30 # 标签频率每秒30帧
        self.frame_rate = 0.02 # wav2vec 0.02s一帧
        self.model_names = ['_wav2vec', '_reg']
        self.pretrained_model = ['_wav2vec']
        self.net_wav2vec = Wav2Vec2Model.from_pretrained("facebook/wav2vec2-base")

        if self.task == 'v' or self.task == 'a':
            self.net_reg = FcRegressor(768, self.regress_layers, 1, dropout=self.dropout_rate)
        else:
            self.net_reg = FcRegressor(768, self.regress_layers, 2, dropout=self.dropout_rate)

        #settings
        if self.isTrain:
            if opt.loss_type == 'mse':
                self.criterion_reg = torch.nn.MSELoss(reduction='sum')
            else:
                self.criterion_reg = torch.nn.L1Loss(reduction='sum')

            # initialize optimizers; schedulers will be automatically created by function <BaseModel.setup>.
            paremeters = [{'params': getattr(self, 'net'+net).parameters()} for net in self.model_names]
            self.optimizer = torch.optim.Adam(paremeters, lr=opt.lr, betas=(opt.beta1, 0.999))
            self.optimizers.append(self.optimizer)

    def set_input(self, input, load_label=True):
        """Unpack input data from the dataloader and perform necessary pre-processing steps.

        Parameters:
            input (dict): include the data itself and its metadata information.

        """
        self.len_speech = input['len_speech'].to(self.device) # (bs,)
        self.speech = input['speech'].to(self.device) # (bs, len_speech)
        if load_label:
            self.valid = input['valid'].to(self.device) # (bs, max_clip_length*30)
            if self.task == 'v':
                self.target = input['label'].permute(2, 0, 1)[0].to(self.device) # (bs, max_clip_length*30)
            elif self.task == 'a':
                self.target = input['label'].permute(2, 0, 1)[1].to(self.device) # (bs, max_clip_length*30)
            else:
                self.target = input['label'].to(self.device) # (bs, max_clip_length*30, 2)

    def run(self):
        """After feed a batch of samples, Run the model."""
        # forward
        prediction = self.forward_step() # (bs, aligned_len_speech, 2) or (bs, aligned_len_speech, 1)
        if self.task == 'v' or self.task == 'a':
            prediction = prediction.squeeze(dim=-1) # (bs, aligned_len_speech)

        # backward
        if self.isTrain:
            self.optimizer.zero_grad()
            self.backward_step(prediction, self.target, self.valid)
            self.optimizer.step()

        self.output = prediction

    def align_timestamp(self, batch_ft, num_frames):
        '''
        The wav2vec has 50 fts per second. There are 30 labels per second.
        We need to align the feature frequency to the label frequency.
        '''
        start_time_list = [i * (1.0/self.label_fps) for i in range(num_frames)]
        end_time_list = [((1.0/self.label_fps) + i * (1.0/self.label_fps)) for i in range(num_frames)]

        # 把每个时刻的值精度缩小一下，防止因为float本身有些小数最后一位不够精确导致多算一条frame
        start_time_list = [round(i, 4) for i in start_time_list]
        end_time_list = [round(i, 4) for i in end_time_list]

        # 确保 batch_ft pad到足够长
        finish_idx = math.ceil(end_time_list[-1] / self.frame_rate)
        if batch_ft.shape[1] < finish_idx:
            pad_num = finish_idx + 1 - batch_ft.shape[0]
            pad_ft = batch_ft[:, -1, :] # (bs, dim)
            pad_ft = pad_ft.unsqueeze(1).repeat(1, pad_num, 1) # (bs, pad_num, dim)
            batch_ft = torch.cat((batch_ft, pad_ft), dim=1)

        segment_ft = []
        for start, end in zip(start_time_list, end_time_list):
            start_idx = math.floor(round(start / self.frame_rate, 4)) # 同样也需要在这里缩小一下精度
            end_idx = math.ceil(round(end / self.frame_rate, 4))
            frame_ft = batch_ft[:, start_idx: end_idx, :]
            frame_ft = frame_ft.mean(dim=1)
            segment_ft.append(frame_ft)
        segment_ft = torch.stack(segment_ft, dim=1)
        assert segment_ft.shape[1] == num_frames

        return segment_ft # (bs, num_frames, dim)

    def forward_step(self):
        batch_ft = self.net_wav2vec(self.speech).last_hidden_state # (bs, len_speech, dim=768)
        aligned_len = self.target.shape[1]
        batch_ft = self.align_timestamp(batch_ft, aligned_len) # (bs, num_frames, dim=768)

        pred, _ = self.net_reg(batch_ft) # (bs, aligned_len_speech, 2) or (bs, aligned_len_speech, 1)
        return pred

    def backward_step(self, pred, target, mask):
        """Calculate the loss for back propagation"""
        if self.task == 'v+a':
            mask = mask.unsqueeze(2).repeat(1, 1, 2)

        pred = pred * mask
        target = target * mask
        valid_data_num = torch.sum(mask)
        self.loss_mse = self.criterion_reg(pred, target) / valid_data_num
        self.loss_mse.backward(retain_graph=False)

if __name__ == '__main__':
    import sys
    sys.path.append('/data8/hzp/ABAW_Expression_2022/code/utils')#
    from data import create_dataset, create_dataset_with_args

    class test:
        feature_set = 'None'
        input_dim = None
        lr = 1e-4
        beta1 = 0.5
        batch_size = 2
        epoch_count = 1
        niter = 20
        niter_decay=30
        gpu_ids = [1]
        isTrain = True
        checkpoints_dir = ''
        name = ''
        cuda_benchmark = ''
        max_read_num = 10
        max_clip_length = 10
        dataset_mode = 'audio_clip_toy'
        num_threads = 0
        max_dataset_size = float("inf")
        serial_batches = True
        lr_policy = ''
        init_type = 'kaiming'
        init_gain = 0.02
        verbose = ''

        regress_layers = '256'
        dropout_rate = 0.3
        loss_type = 'mse'
        task = 'v'

    opt = test()
    net_a = Wav2vecModel(opt)

    # dataset, val_dataset = create_dataset_with_args(opt, set_name=['train', 'val'])  # create a dataset given opt.dataset_mode and other options
    dataset = create_dataset_with_args(opt, set_name=['train'])[0]  # create a dataset given opt.dataset_mode and other options

    net_a.setup(opt)                            # regular setup: load and print networks; create schedulers

    total_iters = 0                             # the total number of training iterations

    for epoch in range(opt.epoch_count, opt.niter + opt.niter_decay + 1):    # outer loop for different epochs; we save the model by <epoch_count>, <epoch_count>+<save_latest_freq>
        epoch_iter = 0                  # the number of training iterations in current epoch, reset to 0 every epoch
        for i, data in enumerate(dataset, 1):  # inner loop within one epoch
            total_iters += 1                # opt.batch_size
            epoch_iter += opt.batch_size
            net_a.set_input(data)           # unpack data from dataset and apply preprocessing
            net_a.run()

            print(net_a.output)
            print(net_a.output.shape)

    # for epoch in range(opt.epoch_count, opt.niter + opt.niter_decay + 1):    # outer loop for different epochs; we save the model by <epoch_count>, <epoch_count>+<save_latest_freq>
    #     epoch_iter = 0                  # the number of training iterations in current epoch, reset to 0 every epoch
    #     for i, data in enumerate(val_dataset, 1):  # inner loop within one epoch
    #         total_iters += 1                # opt.batch_size
    #         epoch_iter += opt.batch_size
    #         net_a.set_input(data)           # unpack data from dataset and apply preprocessing
    #         net_a.run()

    #         print(net_a.output)
    #         print(net_a.output.shape) # (1, 2)


from pynput import keyboard
from Hotkeys import hot_keys

def listener(open_ui, ui):
    combinations = hot_keys

    pressed_keys = set()

    def get_vk(key):
        # gets virtual key allowing pressed keys to easily be compared
        return key.vk if hasattr(key, 'vk') else key.value.vk

    def is_combination_pressed(combination):
        return all([get_vk(key) in pressed_keys for key in combination])

    def on_press(key):
        try:
            print("Added key")
            pressed_keys.add(get_vk(key))
        except:
            None

        for combination in combinations:  # Loop though each combination
            if is_combination_pressed(combination["shortcut"]):
                print("Got combination")

                if combination["input_required"]:
                    ui.set_event(combination["event"])
                    open_ui()
                else:
                    combination["event"]()

    def on_release(key):
        try:
            pressed_keys.remove(get_vk(key))
            print("Removed")
        except:
            pressed_keys.clear()

    with keyboard.Listener(on_press=on_press, on_release=on_release) as listen:
        listen.join()


from typing import List

# Definition for a binary tree node.
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        pPath = self.getPathToNode(root, p)
        qPath = self.getPathToNode(root, q)

        for i in range(min(len(pPath), len(qPath)) - 1, -1, -1):
            if pPath[i].val == qPath[i].val:
                return pPath[i]

        return pPath[0]

    def getPathToNode(self, start: 'TreeNode', target: 'TreeNode') -> List:
        path = []

        while start != target:
            path.append(start)

            if start.val > target.val:
                start = start.left
            else:
                start = start.right

        path.append(target)

        return path


import urllib.request, urllib.parse, http.client
import json
import hmac, hashlib
import sys

import pwned.competitions

class Pwned:
    __version = '0'

    def __init__(self, base_url, public_key, private_key):
        if not base_url.endswith('/'):
            base_url = base_url + '/'

        self.base_url = base_url
        self.public_key = public_key
        self.private_key = private_key

    def create_tournament(self, tournament):
        response = self._request('tournaments', 'POST', tournament.get_api_dict())

        if response:
            return pwned.competitions.Tournament.from_api_call(response, client=self)

    def create_league(self, league):
        response = self._request('leagues', 'POST', league.get_api_dict())

        if response:
            return pwned.competitions.League.from_api_call(response, client=self)

    def get(self, type, id):
        if hasattr(self, 'get_' + str(type)):
            return getattr(self, 'get_' + str(type))(id)

        raise PwnedAPIException('Unknown type for get: ' + str(type))

    def get_league(self, id):
        response = self._get_competition('league', id)

        if response:
            return pwned.competitions.League.from_api_call(response, client=self)

    def get_tournament(self, id):
        response = self._get_competition('tournament', id)

        if response:
            return pwned.competitions.Tournament.from_api_call(response, client=self)

    def get_tournament_templates(self):
        response = self._request('tournaments/templates')

        if not response is None:
            templates = []

            for template in response:
                templates.append(pwned.support.TournamentTemplate.from_api_call(template))

            return templates

    def update(self, type, id, competition):
        return self._request(type + 's/' + str(id), 'POST', competition.get_api_dict())

    def start(self, type, id):
        return self._request(type + 's/' + str(id), 'POST', {'status': 'live'})

    def add_signups(self, type, competition_id, signups):
        data = []

        for signup in signups:
            data.append(signup.get_api_dict())

        return self._request(type + 's/' + str(competition_id) + '/signups', 'POST', data)

    def get_signups(self, type, competition_id):
        response = self._request(type + 's/' + str(competition_id) + '/signups')

        if not response is None:
            signups = []

            for el in response:
                signups.append(pwned.support.Signup.from_api_call(el))

            return signups

    def remove_signup(self, type, competition_id, signup_id):
        return self._request(type + 's/' + str(competition_id) + '/signups/' + str(signup_id), 'DELETE')

    def get_round(self, type, competition_id, round_index):
        response = self._request(type + 's/' + str(competition_id) + '/rounds/' + str(round_index))

        if not response is None:
            return pwned.support.Round.from_api_call(response)

    def get_rounds(self, type, competition_id):
        response = self._request(type + 's/' + str(competition_id) + '/rounds')

        if not response is None:
            rounds = []

            for el in response:
                rounds.append(pwned.support.Round.from_api_call(el))

            return rounds

    def get_match(self, type, competition_id, match_id):
        response = self._request(type + 's/' + str(competition_id) + '/matches/' + str(match_id))

        if not response is None:
            return pwned.support.Match.from_api_call(response)

    def update_match(self, type, competition_id, match):
        return self._request(type + 's/' + str(competition_id) + '/matches/' + str(match.id), 'POST', match.get_api_dict())

    def update_round(self, type, competition_id, round):
        return self._request(type + 's/' + str(competition_id) + '/rounds/' + round.round_number, 'POST', round.get_api_dict())

    def get_league_table(self, league_id):
        response = self._request('leagues/' + str(league_id) + '/table')

        if not response is None:
            table = []

            for position in response:
                table.append(pwned.support.LeagueTablePosition.from_api_call(position))

            return table

    def get_league_scoring_models(self, type=None):
        if type:
            response = self._request('leagues/scoringmodels/' + type)
        else:
            response = self._request('leagues/scoringmodels', 'GET')

        if not response is None:
            scoring_models = []

            for scoring_model in response:
                scoring_models.append(pwned.support.LeagueScoringModel.from_api_call(scoring_model))

            return scoring_models

    def get_league_scoring_model(self, id):
        response = self._request('leagues/scoringmodels/' + str(id), 'GET')

        if not response is None:
            return pwned.support.LeagueScoringModel.from_api_call(response)

    def create_league_scoring_model(self, scoring_model):
        response = self._request('leagues/scoringmodels/', 'POST', scoring_model.get_api_dict())

        if not response is None:
            return pwned.support.LeagueScoringModel.from_api_call(response)

    def update_league_scoring_model(self, scoring_model):
        return self._request('leagues/scoringmodels/' + str(scoring_model.id), 'POST', scoring_model.get_api_dict())

    def delete_league_scoring_model(self, scoring_model_id):
        return self._request('leagues/scoringmodels/' + str(scoring_model_id), 'DELETE')

    def league_set_championship_round_results(self, league_id, round_number, results):
        data = []

        for result in results:
            val = result.get_api_dict()
            val['signupId'] = val['signup']['id']
            data.append(val)

        return self._request('leagues/' + str(league_id) + '/rounds/' + str(round_number) + '/results', 'POST', data)

    def get_games(self):
        response = self._request('games')

        if not response is None:
            games = []

            for game in response:
                games.append(pwned.support.Game.from_api_call(game))

            return games

    def get_countries(self):
        response = self._request('countries')

        if not response is None:
            countries = []

            for country in response:
                countries.append(pwned.support.Country.from_api_call(country))

            return countries

    def _get_competition(self, type, id):
        return self._request(type + 's/' + str(id))

    def _request(self, resource, request_method = 'GET', data = None):
        if data:
            data = json.dumps(data)
        else:
            data = ''

        url = self.base_url + resource + self._url_query_string(resource, request_method, data)
        headers = {'Content-Type': 'application/json', 'User-Agent': self._user_agent(), }
        response = None

        try:
            if data:
                data = bytes(data.encode("utf-8"))
            else:
                data = None

            if request_method in ('GET', 'POST'):
                request = urllib.request.Request(url, data=data, headers=headers)
                response = urllib.request.urlopen(request).read()
            else:
                url_info = urllib.parse.urlparse(url)
                path = url_info.path

                if url_info.query:
                    path = path + '?' + url_info.query

                connection = http.client.HTTPConnection(url_info.netloc)
                connection.request(request_method, path, body=data, headers=headers)

                response = connection.getresponse().read()
                connection.close()
        except urllib.error.HTTPError as e:
            response = e.read()

        try:
            response = json.loads(response.decode("utf-8"))
        except ValueError:
            print(response)
            raise PwnedAPIException('Invalid JSON returned from server.', response)

        if ('error' in response) and response['error']:
            raise PwnedAPIException(response['error']['reason'])

        if 'result' in response:
            return response['result']

        return response

    def _url_query_string(self, resource, request_method, data):
        return '?' + urllib.parse.urlencode({
            'publicKey': self.public_key,
            'signature': self._signature(resource, request_method, data)
        })

    def _signature(self, resource, request_method, data):
        return hmac.new(self.private_key.encode('ascii'), bytes((self.public_key + '|' + request_method + '|' + resource + '|' + data).encode("utf-8")), hashlib.sha256).hexdigest()

    def _user_agent(self):
        return 'python-pwned-api/' + self.__version + '/' + '.'.join(str(x) for x in sys.version_info[0:3])

class PwnedAPIException(Exception):
    def __init__(self, message, raw_response = None):
        Exception.__init__(self, message)

        if raw_response:
            self.raw_response = raw_response
        else:
            self.raw_response = None

    def __repr__(self):
        if self.raw_response:
            return self.message + "\n\n" + raw_response

        return self.message


import sys
import os
import time
import atexit
import signal
import logging

class Daemon:
    EXIT_OK = 0
    EXIT_OTHER_ERROR = 1
    EXIT_PARAM_ERROR = 2

    def __init__(self, pidfile):
        self.pidfile = pidfile

    def daemonize(self):
        try:
            pid = os.fork()
            if pid > 0:
                sys.exit(self.EXIT_OK)
        except OSError as err:
            logging.error('fork #1 failed: {0}'.format(err))
            sys.exit(self.EXIT_OTHER_ERROR)

        os.chdir('/')
        os.setsid()
        os.umask(0)

        try:
            pid = os.fork()
            if pid > 0:
                sys.exit(self.EXIT_OK)
        except OSError as err:
            logging.error('fork #2 failed: {0}'.format(err))
            sys.exit(self.EXIT_OTHER_ERROR)

        sys.stdout.flush()
        sys.stderr.flush()
        si = open(os.devnull, 'r')
        so = open(os.devnull, 'a+')
        se = open(os.devnull, 'a+')

        os.dup2(si.fileno(), sys.stdin.fileno())
        os.dup2(so.fileno(), sys.stdout.fileno())
        os.dup2(se.fileno(), sys.stderr.fileno())

        atexit.register(self.delpid)

        pid = str(os.getpid())
        with open(self.pidfile, 'w+') as f:
            f.write(pid + '\n')

    def delpid(self):
        os.remove(self.pidfile)

    def start(self):
        try:
            with open(self.pidfile, 'r') as pf:

                pid = int(pf.read().strip())
        except IOError:
            pid = None

        if pid:
            logging.warning("pidfile {0} already exist. Daemon already running?".format(self.pidfile))
            sys.exit(self.EXIT_OTHER_ERROR)

        self.daemonize()
        self.run()

    def stop(self):
        try:
            with open(self.pidfile, 'r') as pf:
                pid = int(pf.read().strip())
        except IOError:
            pid = None

        if not pid:
            logging.warning("pidfile {0} does not exist. Daemon not running?".format(self.pidfile))
            return

        try:
            while 1:
                os.kill(pid, signal.SIGTERM)
                time.sleep(0.1)
        except OSError as err:
            e = str(err.args)
            if e.find("No such process") > 0:
                if os.path.exists(self.pidfile):
                    os.remove(self.pidfile)
            else:
                logging.error(str(err.args))
                sys.exit(self.EXIT_OTHER_ERROR)

    def restart(self):
        self.stop()
        self.start()

    def status(self):
        try:
            with open(self.pidfile, 'r') as pf:
                pid = int(pf.read().strip())
        except IOError:
            pid = None

        if not pid:
            logging.error("Service not running".format(self.pidfile))
            sys.exit(self.EXIT_OTHER_ERROR)

        try:
            os.kill(pid, 0)
        except OSError as err:
            logging.error("Service not running".format(self.pidfile))
            sys.exit(self.EXIT_OTHER_ERROR)

        logging.info("Service running".format(self.pidfile))
        sys.exit(self.EXIT_OTHER_ERROR)

    def run(self):
        pass


import csv
import time
import requests
import os
from bs4 import BeautifulSoup
import lxml
import json

def get_pages():
    headers = {
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"
    }

    req = requests.get(url="https://swisstime.by/catalog/filter/gender-is-muzhskie/apply/", headers=headers)

    if not os.path.exists("data"):
        os.mkdir("data")

    with open("data/page_1.html", "w", encoding="UTF-8") as file:
        file.write(req.text)

    with open("data/page_1.html", encoding="UTF-8") as file:
        src = file.read()

    soup = BeautifulSoup(src, "lxml")
    pages_count = int(soup.find("li", class_="pagination-item pages col-06").find_all("a")[-2].text)

    for i in range(1, pages_count + 1):
        url = f"https://swisstime.by/catalog/filter/gender-is-muzhskie/apply/?PAGEN_1={i}"

        r = requests.get(url=url, headers=headers)
        with open(f"data/page_{i}.html", "w", encoding="UTF-8") as file:
            file.write(r.text)

        time.sleep(2)

    return pages_count

def collect_options(pages_count):
    with open("data_results.csv", "w", encoding="UTF-8") as file:
        writer = csv.writer(file)
        writer.writerow(
            (
                "Бренд",
                "Модель",
                "Цена",
                "Имеется в продаже"
            )
        )

    data = []
    for page in range(1, pages_count + 1):
        with open(f"data/page_{page}.html", encoding="UTF-8") as file:
            src = file.read()

        soup = BeautifulSoup(src, "lxml")
        watch_cards = soup.find_all("a", class_="st-card__link")

        for item in watch_cards:
            watch_brand = item.find("div", class_="st-card__brand").text
            watch_model = item.find("div", class_="st-card__model").text
            watch_price = item.find("div", class_="st-card__price").text
            watch_stock = item.find("div", class_="st-card__stock").text.strip()
            watch_url = f'https://swisstime.by{item.get("href")}'

            data.append(
                {
                    "watch_brand": watch_brand,
                    "watch_model": watch_model,
                    "watch_price": watch_price,
                    "watch_stock": watch_stock,
                    "watch_url": watch_url
                }
            )

            with open("data_results.csv", "a", encoding="UTF-8") as file:
                writer = csv.writer(file)
                writer.writerow(
                    (
                        watch_brand,
                        watch_model,
                        watch_price,
                        watch_stock
                    )
                )

    with open("parsing_results.json", "a", encoding="UTF-8") as file:
        json.dump(data, file, indent=4, ensure_ascii=False)

    print(f"The work has done")

def main():
    pages_count = get_pages()
    collect_options(pages_count=pages_count)

if __name__ == '__main__':
    main()


import torch

import warnings
from scipy.spatial.distance import cdist

# supress UserWarning
warnings.filterwarnings("ignore", category=UserWarning)
from pyannote.audio.pipelines.speaker_verification import PretrainedSpeakerEmbedding
model = PretrainedSpeakerEmbedding(
    "speechbrain/spkrec-ecapa-voxceleb",
    device="cuda" if torch.cuda.is_available() else "cpu",)

from pyannote.audio import Audio

audio = Audio(sample_rate=16000, mono="downmix")

waveform1, sample_rate = audio({"audio": "../taylor-swift/data/vocals30.wav"})
embedding1 = model(waveform1[None])

import os

all_sims = []

for file in os.listdir("../taylor-swift/data/"):
    if file.endswith(".wav") and "_m" not in file:
        waveform2, sample_rate = audio({"audio": "../taylor-swift/data/" + file})
        embedding2 = model(waveform2[None])

        # compare embeddings using "cosine" distance
        distance = cdist(embedding1, embedding2, metric="cosine")

        all_sims.append(distance[0][0])

avg = sum(all_sims) / len(all_sims)

print(avg)


'''
Created on 2012-7-2

@author: guoxc
'''
import json
import Tkinter
test_tree = json.load(open("root_frame.json"))
def tree_print(tr, intend=0):
    if not isinstance(tr, dict):
        raise Exception("tree not a dict")
    if "type" not in tr.keys() or "id" not in tr.keys():
        raise Exception("syntax Error")
    attr_list =  [(str(attr) +":"+str(tr[attr])) for attr in tr if attr not in ("menu","type","id","items")]
    print ("|   " * (intend - 1 if intend > 1 else 0) +
        "|___" * ( 1 if intend >= 1 else 0) + tr["type"] +
        ":" + tr["id"] + "  " +str(attr_list))
    if "menu" in tr.keys():
        tree_print(tr["menu"], intend +1)
    if "items" in tr.keys():
        for item in tr["items"]:
            tree_print(item, intend +1)

def get_menu(tr, parent):
    new_menu = Tkinter.Menu(parent, tearoff=0)
    if "items" in tr.keys():
        for item in tr["items"]:
            if item["type"] == "Menu":
                new_menu.add_cascade(menu=get_menu(item, new_menu),
                                     label=get_menu_text(item))
            elif item["type"] == "MenuItem":
                new_menu.add_command(label=item["text"], command=get_cmd_by_id(item["id"]))
    return new_menu

def get_button(tr, parent):
    opt = get_options(tr)
    new_button = Tkinter.Button(parent, **opt)
    return new_button

def get_entry(tr, parent):
    opt = get_options(tr)
    new_entry = Tkinter.Entry(parent, **opt)
    return new_entry

def get_label(tr, parent):
    opt = get_options(tr)
    new_label = Tkinter.Label(parent, **opt)
    return new_label

def get_options(opdict):
    opt = {}
    for key in opdict.keys():
        if key not in ["type", "id","position","items","class","sticky"]:
            opt[key] = opdict[key]
    return opt

def get_cmd_by_id(id_):
    if id_ +"_cmd" in globals():
        return globals()[id_ +"_cmd"]
    else:
        return None

def menu1_1_3_cmd():
    root.destroy()

def get_menu_text(tr):
    if not tr["text"]:
        return None
    return tr["text"]

def parse_position(text):
    rlist = text.split(" ")
    rlist = [int(item) for item in rlist]
    if len(rlist) == 2:
        return {"row": rlist[0],"column":rlist[1]}
    elif len(rlist) == 4:
        return {"row": rlist[0],"column":rlist[1],"rowspan":rlist[2],"columnspan":rlist[3]}

def tree_parse(tr):
    if tr["menu"]:
        root.config(menu=get_menu(tr["menu"], root))
    if tr["items"] and tr["layout"]:
        if tr["layout"] == "grid":
            for item in tr["items"]:
                position_dict = parse_position(item["position"])
                if "sticky" in item.keys():
                    position_dict["sticky"] = item["sticky"]
                if item["type"] == "Button":
                    get_button(item, root).grid(**position_dict)
                elif item["type"] == "Entry":
                    get_entry(item, root).grid(**position_dict)
                elif item["type"] == "Label":
                    get_label(item, root).grid(**position_dict)

root = Tkinter.Tk()
tree_print(test_tree)
tree_parse(test_tree)
root.mainloop()