from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import _init_paths

import os

import torch
import torch.utils.data
from opts import opts
from models.model import create_model, load_model, save_model
from models.data_parallel import DataParallel
from logger import Logger
from datasets.dataset_factory import get_dataset
from trains.train_factory import train_factory

def main(opt):
  #torch.manual_seed(opt.seed)
  torch.backends.cudnn.benchmark = not opt.not_cuda_benchmark and not opt.test

  if opt.task != 'reweight_paper':
    Dataset = get_dataset(opt.dataset, opt.task)
  else:
    #python main_ep.py reweight_paper --load_model ../models/best_resmeta_50/model_last.pth  --fewshot_data basenovel_fewshot --master_batch_size 1 --batch_size 8 --head_conv 0 --cat_spec_wh --lr 1e-5 --gpus 0,1,2,3,4,5,6,7,8
    Dataset = get_dataset('coco_mixed', 'mixdet')

  opt = opts().update_dataset_info_and_set_heads(opt, Dataset)
  print(opt)

  logger = Logger(opt)

  os.environ['CUDA_VISIBLE_DEVICES'] = opt.gpus_str
  opt.device = torch.device('cuda' if opt.gpus[0] >= 0 else 'cpu')

  print('Creating model...')
  if opt.task != 'reweight_paper':
    model = create_model(opt.arch, opt.heads, opt.head_conv, extras={'learnable': opt.learnable, 'metasize': opt.metasize})
  else:
    print(100*'=')
    print(opt.heads, opt.head_conv)
    print(Dataset.num_classes)
    model = create_model('resmeta_50', opt.heads, opt.head_conv, extras={'learnable': opt.learnable, 'metasize': opt.metasize})

  if opt.task != 'reweight_paper':
    optimizer = torch.optim.Adam(model.meta_params, opt.lr)
  else:
    optimizer = torch.optim.Adam(model.parameters(), opt.lr)

  start_epoch = 0
  if opt.task != 'reweight_paper':
    if opt.load_model != '':
      model, optimizer, start_epoch = load_model(
        model, opt.load_model, optimizer, opt.resume, opt.lr, opt.lr_step)
  else:
    if opt.load_model != '':
      l = torch.load(opt.load_model)['state_dict']
      mk,uk = model.load_state_dict(l, strict=False)
      print('Missing Keys for model:    ',mk)
      print('')
      print('Unknown Keys for model:    ',uk)

  if opt.task != 'reweight_paper' and opt.task != 'ctdet':
    Trainer = train_factory[opt.task]
  else:
    Trainer = train_factory['epdet']

  trainer = Trainer(opt, model, optimizer)
  trainer.set_device(opt.gpus, opt.chunk_sizes, opt.device)

  print('Setting up data...')
  if opt.task != 'reweight_paper' and opt.task != 'ctdet':
    val_loader = torch.utils.data.DataLoader(
        Dataset(opt, 'val', base=True), #the 20 left-out classes are only for testing
        batch_size=1,
        shuffle=False,
        num_workers=1,
        pin_memory=True
    )
    train_loader = torch.utils.data.DataLoader(
        Dataset(opt, 'train', base=True),
        batch_size=opt.batch_size,
        shuffle=True,
        num_workers=opt.num_workers,
        pin_memory=True,
        drop_last=True
    )
  else:
    val_loader = torch.utils.data.DataLoader(
        Dataset(opt, 'val'),
        batch_size=1,
        shuffle=False,
        num_workers=1,
        pin_memory=True
    )

    train_loader = torch.utils.data.DataLoader(
        Dataset(opt, 'train'),
        batch_size=opt.batch_size,
        shuffle=True,
        num_workers=opt.num_workers,
        pin_memory=True,
        drop_last=True
    )

  if opt.task != 'reweight_paper':
    if opt.load_basemodel:
      print('=====> Loading pretrained models')
      l = torch.load(opt.load_basemodel)['state_dict']
      mk,uk = model.load_state_dict(l, strict=False)
      print('Missing Keys for base model:    ',mk)
      print('')
      print('Unknown Keys for base model:    ',uk)

    if opt.load_metamodel:
      print('=====> Loading meta-pretrained models')
      l = torch.load(opt.load_metamodel)['state_dict']
      mk,uk = model.rw.load_state_dict(l, strict=False)
      print('Missing Keys for meta model:    ',mk)
      print('')
      print('Unknown Keys for meta model:    ',uk)

  print('Starting training...')
  best = 1e10
  for epoch in range(start_epoch + 1, opt.num_epochs + 1):

    # hardcoded warmpup
    if opt.task != 'reweight_paper':
      if epoch == 1:
        lr = opt.lr/100
        print('**** Warmup LR to', lr)
        for param_group in optimizer.param_groups:
            param_group['lr'] = lr
      elif epoch == 2:
        lr = opt.lr
        print('**** Warmup finished to', lr)
        for param_group in optimizer.param_groups:
            param_group['lr'] = lr

    mark = epoch if opt.save_all else 'last'
    log_dict_train, _ = trainer.train(epoch, train_loader)
    logger.write('epoch: {} |'.format(epoch))
    for k, v in log_dict_train.items():
      logger.scalar_summary('train_{}'.format(k), v, epoch)
      logger.write('{} {:8f} | '.format(k, v))
    if opt.val_intervals > 0 and epoch % opt.val_intervals == 0:
      save_model(os.path.join(opt.save_dir, 'model_{}.pth'.format(mark)),
                 epoch, model, optimizer)
      with torch.no_grad():
        log_dict_val, preds = trainer.val(epoch, val_loader)
      for k, v in log_dict_val.items():
        logger.scalar_summary('val_{}'.format(k), v, epoch)
        logger.write('{} {:8f} | '.format(k, v))
      if log_dict_val[opt.metric] < best:
        best = log_dict_val[opt.metric]
        save_model(os.path.join(opt.save_dir, 'model_best.pth'),
                   epoch, model)
    else:
      save_model(os.path.join(opt.save_dir, 'model_last.pth'),
                 epoch, model, optimizer)
    logger.write('\n')
    if epoch in opt.lr_step:
      save_model(os.path.join(opt.save_dir, 'model_{}.pth'.format(epoch)),
                 epoch, model, optimizer)
      lr = opt.lr * (0.1 ** (opt.lr_step.index(epoch) + 1))
      print('Drop LR to', lr)
      for param_group in optimizer.param_groups:
          param_group['lr'] = lr
  logger.close()

if __name__ == '__main__':
  opt = opts().parse()
  main(opt)


import math
import pyautogui
from time import sleep
import paperclip
import pandas as pd
import re
from pynput import keyboard
from threading import Thread, Lock

is_running = True
stationed = False
stop_key = keyboard.Key.esc
path = pd.read_csv('path.csv')
# window = WindowCapture('Albion Online Client')

class Pather:
    lock = None
    def __init__(self, wincap):
        print(path)
        sleep(2)
        pyautogui.press('enter')
        sleep(0.1)
        pyautogui.press('#')
        pyautogui.press('w')
        pyautogui.press('h')
        pyautogui.press('e')
        pyautogui.press('r')
        pyautogui.press('e')
        pyautogui.press('enter')
        sleep(2)
        self.index = 0
        self.window = wincap
        self.lock = Lock()

    @staticmethod
    def create_vector(point1, point2):
        x1, y1 = point1
        x2, y2 = point2

        vx = x2 - x1
        vy = y2 - y1

        return vx, vy

    @staticmethod
    def angle_with_x_axis(vector):
        # Extract the x-component and y-component of the vector
        vx, vy = vector

        # Calculate the magnitude of the vector
        magnitude = math.sqrt(vx ** 2 + vy ** 2)

        # Calculate the angle with the x-axis using the arccos function
        if magnitude == 0:
            return 0
        if vy >= 0:
            angle_radians = math.acos(vx / magnitude)
        else:
            angle_radians = -math.acos(vx / magnitude)

        return angle_radians - math.pi / 4
        # + math.pi - math.pi/4

    @staticmethod
    def extract_numbers(input_string):
        # Define the regular expression pattern to find two floating-point numbers
        pattern = r"-?\d+\.\d+"

        # Find all occurrences of the pattern in the input string
        numbers = re.findall(pattern, input_string)

        # Convert the found strings to floating-point numbers
        numbers = [float(num) for num in numbers]

        return numbers

    @staticmethod
    def move_player(angle, radius, monitor):
        # Calculate X and Y offsets using trigonometry
        x_offset = radius * math.cos(angle)
        y_offset = -radius * math.sin(angle)

        # Get the current mouse position
        player_x, player_y = monitor['left'] + monitor['width'] / 2, monitor['top'] + monitor['height'] / 2

        # Calculate the new position around the player
        new_x = player_x + x_offset
        new_y = player_y + y_offset

        # Move the mouse to the new position
        pyautogui.moveTo(new_x, new_y)

    def pathing(self):
        # self.lock.acquire()

        def on_press(key):
            global is_running

            if key == stop_key:
                is_running = False

                pyautogui.mouseUp(button='right')

                return False

        # with keyboard.Listener(on_press=on_press) as listener:
        while is_running and not stationed:
            # pyautogui.mouseUp(button='right')
            print('go')
            self.window.get_screenshot()
            pyautogui.press('enter')
            pyautogui.press('up')
            pyautogui.press('enter')
            my_pos = paperclip.paste()
            my_pos = self.extract_numbers(my_pos)

            print(self.index)
            print("my pos: " + str(my_pos))
            row = path.iloc[self.index]
            x, y, station = row['x'], row['y'], row['station']
            destination = (x, y)
            print("destination: " + str(destination))

            vector = self.create_vector(my_pos, destination)
            vx, vy = vector
            magnitude = math.sqrt(vx ** 2 + vy ** 2)
            angle = self.angle_with_x_axis(vector)

            print("magnitude: " + str(magnitude))
            print("angle: " + str(math.degrees(angle)))
            print()

            if station:
                pyautogui.mouseUp(button='right')
                self.index += 1
                row = path.iloc[self.index-1]
                x, y = row['x'], row['y']
                station_point = (x, y)
                return station_point

            monitor = self.window.monitor
            self.move_player(angle, 20, monitor)

            if magnitude >= 6:
                pyautogui.mouseUp(button='right')
                pyautogui.mouseDown(button='right')
                continue
            elif magnitude < 6:
                self.index += 4
                pass
            # index += 1
        # self.lock.release()

    def where(self):
        pyautogui.press('enter')
        pyautogui.press('up')
        pyautogui.press('enter')
        my_pos = paperclip.paste()
        my_pos = self.extract_numbers(my_pos)
        return my_pos

    def backtrack(self):
        row = path.iloc[self.index]
        point = (row['x'], row['y'])

        while True:
            # pyautogui.mouseUp(button='right')
            self.window.get_screenshot()
            pyautogui.press('enter')
            pyautogui.press('up')
            pyautogui.press('enter')
            my_pos = paperclip.paste()
            my_pos = self.extract_numbers(my_pos)
            print("my pos: " + str(my_pos))
            x, y = point
            destination = (x, y)
            print("destination: " + str(destination))
            vector = self.create_vector(my_pos, destination)
            vx, vy = vector
            magnitude = math.sqrt(vx ** 2 + vy ** 2)
            angle = self.angle_with_x_axis(vector)
            print("magnitude: " + str(magnitude))
            print("angle: " + str(math.degrees(angle)))
            monitor = self.window.monitor
            self.move_player(angle, 20, monitor)

            if magnitude >= 3:
                pyautogui.mouseUp(button='right')
                pyautogui.mouseDown(button='right')
                continue
            else:
                return

    # t 3209 208.9543 386.1061


from __future__ import unicode_literals
import urllib.request, json
import youtube_dl

def download_my_music(music_directory,list_music):
    ydl_opts = {
        'outtmpl': music_directory+'%(title)s.%(ext)s',
        'format': 'bestaudio/best',
        'postprocessors': [{
            'key': 'FFmpegExtractAudio',
            'preferredcodec': 'mp3',
            'preferredquality': '192',
        }],
    }
    with youtube_dl.YoutubeDL(ydl_opts) as ydl:
        ydl.download(list_music)
def getListMymusic(url_music):
    with urllib.request.urlopen(url_music) as url:
        data = json.loads(url.read().decode())
        return data['playlist']['trackIds']
def parseListSongs(listSong):
    listUrl = []
    for song in listSong:
        songname    = song.split(":")[0]
        album       = song.split(":")[1]
        listUrl.append( "https://music.yandex.ru/album/"+album+"/track/"+songname)
    return listUrl

download_my_music('/home/sivannikov/Music/ya_music/',parseListSongs(getListMymusic("https://music.yandex.ru/handlers/playlist.jsx?owner=nepneppen&kinds=3&light=true")))


from collections import deque

t = int(input())

dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
w = []

def bfs(s, cabbage):
    queue = deque([s])
    cabbage[s[0]][s[1]] = 0

    while queue:
        q = queue.popleft()

        for i in range(4):
            nx = q[0] + dx[i]
            ny = q[1] + dy[i]

            if(0 <= nx < n) and (0 <= ny < m) and (cabbage[nx][ny] == 1):
                cabbage[nx][ny] = 0
                queue.append([nx, ny])

for i in range(t):
    m, n, k = map(int, input().split())
    cabbage = [[0]*m for i in range(n)]
    cnt = 0

    for j in range(k):
        x, y = map(int, input().split())
        cabbage[y][x] = 1

    for a in range(n):
        for b in range(m):
            if (cabbage[a][b] == 1):
                cnt += 1
                bfs([a, b], cabbage)
    w.append(cnt)

for i in w:
    print(i)


#!/usr/bin/env python
#
# Note from Milena: this script should be combined with
# compute_transects.py to be able to:
# 1) compute mass transport for each year and save it
# 2) read the transports from tile if previously computed
# 3) plot it
# I am taking a shortcut now for lack of time... ==> this
# script should be run after compute_transects because it reads
# the data computed there.
#

# ensure plots are rendered on ICC
from __future__ import absolute_import, division, print_function, \
    unicode_literals
import os
import matplotlib as mpl
import numpy as np
import xarray as xr
import pandas as pd
import matplotlib.pyplot as plt

#casename1 = 'E3SM-Arctic-OSI_60to10'
#casename2 = 'E3SM60to30'
#maxYears = 177
casename1 = 'Interface.piControl'
casename2 = 'v2.LR.piControl'
maxYears = 200

monthsNum4runavg_yearly  = 12 # 1 year
monthsNum4runavg  = 5*12 # 5 years

infile1 = './transectsTransport_{}.nc'.format(casename1)
infile2 = './transectsTransport_{}.nc'.format(casename2)
outfile1 = 'meanTransportsArctic_{}.txt'.format(casename1)
outfile2 = 'meanTransportsArctic_{}.txt'.format(casename2)
f1 = open(outfile1, 'w')
f1.write('TransectName VolTransportNet_mean VolTransportNet_rms VolTransportIn_mean VolTransportIn_rms VolTransportOut_mean VolTransportOut_rms HeatTransportNet_mean HeatTransportNet_rms HeatTransportIn_mean HeatTransportIn_rms HeatTransportOut_mean HeatTransportOut_rms HeatTransportTfpNet_mean HeatTransportTfpNet_rms HeatTransportTfpIn_mean HeatTransportTfpIn_rms HeatTransportTfpOut_mean HeatTransportTfpOut_rms FWTransportNet_mean FWTransportNet_rms FWTransportIn_mean FWTransportIn_rms FWTransportOut_mean FWTransportOut_rms\n')
f2 = open(outfile2, 'w')
f2.write('TransectName VolTransportNet_mean VolTransportNet_rms VolTransportIn_mean VolTransportIn_rms VolTransportOut_mean VolTransportOut_rms HeatTransportNet_mean HeatTransportNet_rms HeatTransportIn_mean HeatTransportIn_rms HeatTransportOut_mean HeatTransportOut_rms HeatTransportTfpNet_mean HeatTransportTfpNet_rms HeatTransportTfpIn_mean HeatTransportTfpIn_rms HeatTransportTfpOut_mean HeatTransportTfpOut_rms FWTransportNet_mean FWTransportNet_rms FWTransportIn_mean FWTransportIn_rms FWTransportOut_mean FWTransportOut_rms\n')

figdir = './transects'
if not os.path.isdir(figdir):
    os.mkdir(figdir)
figsize = (20, 10)
figdpi = 150
fontsize_smallLabels = 18
fontsize_labels = 20
fontsize_titles = 24
legend_properties = {'size':fontsize_smallLabels, 'weight':'bold'}

# Define some dictionaries for transect plotting
volobsDict = {'Drake Passage':[120, 184], 'Tasmania-Ant':[147, 167], 'Africa-Ant':None, 'Antilles Inflow':[-23.1, -13.7], \
              'Mona Passage':[-3.8, -1.4],'Windward Passage':[-7.2, -6.8], 'Florida-Cuba':[24.7, 35.3], 'Florida-Bahamas':[28.8, 35.4], \
              'Indonesian Throughflow':[-20, -10], 'Agulhas':[-90, -50], 'Mozambique Channel':[-20, -8], \
              'Bering Strait':[0.6, 1.0], 'Lancaster Sound':[-1.0, -0.5], 'Fram Strait':[-4.7, 0.7], \
              'Robeson Channel':None, 'Davis Strait':[-1.1, -2.1], 'Barents Sea Opening':[1.4, 2.6], 'Barents Strait Opening':[1.4, 2.6],\
              'Nares Strait':[-1.1, -0.5], 'Denmark Strait':None, 'Iceland-Faroe-Scotland':None}
heatobsDict = {'Drake Passage':None, 'Tasmania-Ant':None, 'Africa-Ant':None, 'Antilles Inflow':None, \
               'Mona Passage':None,'Windward Passage':None, 'Florida-Cuba':None, 'Florida-Bahamas':None, \
               'Indonesian Throughflow':None, 'Agulhas':None, 'Mozambique Channel':None, \
               'Bering Strait':[10, 20], 'Lancaster Sound':None, 'Fram Strait':[30, 42], \
               'Robeson Channel':None, 'Davis Strait':[1, 35], 'Barents Sea Opening':[50, 70], 'Barents Strait Opening':[50, 70], \
               'Nares Strait':None, 'Denmark Strait':None, 'Iceland-Faroe-Scotland':None}
FWobsDict = {'Drake Passage':None, 'Tasmania-Ant':None, 'Africa-Ant':None, 'Antilles Inflow':None, \
             'Mona Passage':None,'Windward Passage':None, 'Florida-Cuba':None, 'Florida-Bahamas':None, \
             'Indonesian Throughflow':None, 'Agulhas':None, 'Mozambique Channel':None, \
             'Bering Strait':[2200, 2800], 'Lancaster Sound':[-1900, -950], 'Fram Strait':[-3188, -2132], \
             'Robeson Channel':None, 'Davis Strait':[-3120, -2740], 'Barents Sea Opening':[-184, 4], 'Barents Strait Opening':[-184, 4],\
             'Nares Strait':[-1700, -1000], 'Denmark Strait':None, 'Iceland-Faroe-Scotland':None}
labelDict = {'Drake Passage':'drake', 'Tasmania-Ant':'tasmania', 'Africa-Ant':'africaAnt', 'Antilles Inflow':'antilles', \
             'Mona Passage':'monaPassage', 'Windward Passage':'windwardPassage', 'Florida-Cuba':'floridaCuba', \
             'Florida-Bahamas':'floridaBahamas', 'Indonesian Throughflow':'indonesia', 'Agulhas':'agulhas', \
             'Mozambique Channel':'mozambique', 'Bering Strait':'beringStrait', 'Lancaster Sound':'lancasterSound', \
             'Fram Strait':'framStrait', 'Robeson Channel':'robeson', 'Davis Strait':'davisStrait', 'Barents Sea Opening':'BarentsSea', 'Barents Strait Opening':'BarentsStrait', \
             'Nares Strait':'naresStrait', 'Denmark Strait':'denmarkStrait', 'Iceland-Faroe-Scotland':'icelandFaroeScotland'}

# Read data in from previously compute mass transports
ds1 = xr.open_dataset(infile1)
time1 = ds1.Time.values # Simulated days/365 (will want to change this eventually)
volTransports1 = ds1.volTransport.values # dims=[Time, nTransects], units=Sv
volTransportsIn1 = ds1.volTransportIn.values
volTransportsOut1 = ds1.volTransportOut.values
heatTransports1 = ds1.heatTransport.values
heatTransportsIn1 = ds1.heatTransportIn.values
heatTransportsOut1 = ds1.heatTransportOut.values
heatTransportsTfp1 = ds1.heatTransportTfp.values
heatTransportsTfpIn1 = ds1.heatTransportTfpIn.values
heatTransportsTfpOut1 = ds1.heatTransportTfpOut.values
FWTransports1 = ds1.FWTransport.values
FWTransportsIn1 = ds1.FWTransportIn.values
FWTransportsOut1 = ds1.FWTransportOut.values
nTimes1, nTransects = np.shape(volTransports1)

transectNames = [str(ds1.TransectNames.values[k], encoding='UTF-8')[2:] for k in range(nTransects)]

ds2 = xr.open_dataset(infile2)
time2 = ds2.Time.values # Simulated days/365 (will want to change this eventually)
volTransports2 = ds2.volTransport.values # dims=[Time, nTransects], units=Sv
volTransportsIn2 = ds2.volTransportIn.values
volTransportsOut2 = ds2.volTransportOut.values
heatTransports2 = ds2.heatTransport.values
heatTransportsIn2 = ds2.heatTransportIn.values
heatTransportsOut2 = ds2.heatTransportOut.values
heatTransportsTfp2 = ds2.heatTransportTfp.values
heatTransportsTfpIn2 = ds2.heatTransportTfpIn.values
heatTransportsTfpOut2 = ds2.heatTransportTfpOut.values
FWTransports2 = ds2.FWTransport.values
FWTransportsIn2 = ds2.FWTransportIn.values
FWTransportsOut2 = ds2.FWTransportOut.values
nTimes2, nTransects = np.shape(volTransports2)

for i in range(nTransects):
    if transectNames[i] in labelDict:
        transectName_forfigfile = labelDict[transectNames[i]]
    else:
        transectName_forfigfile = transectNames[i].replace(" ", "")

    if transectNames[i] in volobsDict:
        bounds = volobsDict[transectNames[i]]
    else:
        bounds = None
    if transectNames[i] in heatobsDict:
        heatbounds = heatobsDict[transectNames[i]]
    else:
        heatbounds = None
    if transectNames[i] in FWobsDict:
        FWbounds = FWobsDict[transectNames[i]]
    else:
        FWbounds = None

    print(transectNames[i], transectName_forfigfile, bounds, heatbounds, FWbounds)

    volTransports_runavg_yearly1 = pd.Series.rolling(ds1.volTransport[:, i].to_pandas(),
                                                     monthsNum4runavg_yearly, center=True).mean()
    volTransports_runavg_yearly2 = pd.Series.rolling(ds2.volTransport[:, i].to_pandas(),
                                                     monthsNum4runavg_yearly, center=True).mean()
    volTransports_runavg1 = pd.Series.rolling(ds1.volTransport[:, i].to_pandas(),
                                              monthsNum4runavg, center=True).mean()
    volTransports_runavg2 = pd.Series.rolling(ds2.volTransport[:, i].to_pandas(),
                                              monthsNum4runavg, center=True).mean()

    # Plot Volume transport
    figfile = '{}/volTransport_{}_{}_{}.png'.format(figdir, transectName_forfigfile,
                                                    casename1, casename2)
    fig =  plt.figure(figsize=figsize, dpi=figdpi)
    ax = fig.add_subplot()
    for tick in ax.xaxis.get_ticklabels():
        tick.set_fontsize(fontsize_smallLabels)
        tick.set_weight('bold')
    for tick in ax.yaxis.get_ticklabels():
        tick.set_fontsize(fontsize_smallLabels)
        tick.set_weight('bold')
    ax.yaxis.get_offset_text().set_fontsize(fontsize_smallLabels)
    ax.yaxis.get_offset_text().set_weight('bold')

    ax.plot(time1, volTransports_runavg_yearly1, color='firebrick', linewidth=3,
            label='{} annual mean ({:5.2f} $\pm$ {:5.2f} Sv)'.format(casename1,
            np.nanmean(volTransports_runavg_yearly1), np.nanstd(volTransports_runavg_yearly1)))
    #ax.plot(time1, volTransports1[:, i], color='salmon', alpha=0.5, linewidth=1.5,
    #        label='{} monthly'.fotmat(casename1))
    #if transectNames[i] != 'Nares Strait': # skip plotting of Nares Strait for E3SM-LR (strait is closed)
    #    ax.plot(time2, volTransports_runavg_yearly2, color='k', linewidth=3,
    #            label='E3SM-LR-OSI annual mean ({:5.2f} $\pm$ {:5.2f} Sv)'.format(
    #            np.nanmean(volTransports_runavg_yearly2), np.nanstd(volTransports_runavg_yearly2)))
    ax.plot(time2, volTransports_runavg_yearly2, color='k', linewidth=3,
            label='{} annual mean ({:5.2f} $\pm$ {:5.2f} Sv)'.format(casename2,
            np.nanmean(volTransports_runavg_yearly2), np.nanstd(volTransports_runavg_yearly2)))
    xmin = np.amax([np.amin(time1), np.amin(time2)])
    xmax = np.amax([np.amax(time1), np.amax(time2)])
    if bounds is not None:
        #fig.gca().fill_between(range(1, maxYears+1),
        #                       bounds[0]*np.ones_like(range(1, maxYears+1)),
        #                       bounds[1]*np.ones_like(range(1, maxYears+1)),
        fig.gca().fill_between([xmin, xmax], [bounds[0], bounds[0]], [bounds[1], bounds[1]],
                               color='limegreen', alpha=0.3, label='obs variability')
    if np.max(volTransports1[:, i])>0.0 and np.min(volTransports1[:, i])<0:
        ax.axhline(y=0, color='k', linewidth=1)
    #ax.axvline(x=59, color='blueviolet', linewidth=5)
    #ax.axvline(x=118, color='blueviolet', linewidth=5)
    ax.set_xlabel('Time (Years)', fontsize=fontsize_labels, fontweight='bold')
    ax.set_ylabel('Volume transport (Sv)', fontsize=fontsize_labels, fontweight='bold')
    ax.set_title('Volume transport for {}'.format(transectNames[i]), fontsize=fontsize_titles, fontweight='bold')
    ax.legend(prop=legend_properties)
    #ax.set_xlim(1, maxYears)
    ax.set_xlim(xmin, xmax)
    ##ax.autoscale(enable=True, axis='x', tight=True)
    fig.savefig(figfile, bbox_inches='tight')
    plt.close(fig)

    # Plot Freshwater and Heat transport for Arctic gateways only
    if transectNames[i]=='Bering Strait' or transectNames[i]=='Lancaster Sound' or \
       transectNames[i]=='Fram Strait' or transectNames[i]=='Davis Strait' or \
       transectNames[i]=='Barents Sea Opening' or transectNames[i]=='Barents Strait Opening' or transectNames[i]=='Nares Strait':
        heatTransports_runavg_yearly1 = pd.Series.rolling(ds1.heatTransport[:, i].to_pandas(),
                                                          monthsNum4runavg_yearly, center=True).mean()
        heatTransports_runavg_yearly2 = pd.Series.rolling(ds2.heatTransport[:, i].to_pandas(),
                                                          monthsNum4runavg_yearly, center=True).mean()
        heatTransports_runavg1 = pd.Series.rolling(ds1.heatTransport[:, i].to_pandas(),
                                                   monthsNum4runavg, center=True).mean()
        heatTransports_runavg2 = pd.Series.rolling(ds2.heatTransport[:, i].to_pandas(),
                                                   monthsNum4runavg, center=True).mean()
        heatTransportsTfp_runavg_yearly1 = pd.Series.rolling(ds1.heatTransportTfp[:, i].to_pandas(),
                                                             monthsNum4runavg_yearly, center=True).mean()
        heatTransportsTfp_runavg_yearly2 = pd.Series.rolling(ds2.heatTransportTfp[:, i].to_pandas(),
                                                             monthsNum4runavg_yearly, center=True).mean()
        heatTransportsTfp_runavg1 = pd.Series.rolling(ds1.heatTransportTfp[:, i].to_pandas(),
                                                      monthsNum4runavg, center=True).mean()
        heatTransportsTfp_runavg2 = pd.Series.rolling(ds2.heatTransportTfp[:, i].to_pandas(),
                                                      monthsNum4runavg, center=True).mean()
        FWTransports_runavg_yearly1 = pd.Series.rolling(ds1.FWTransport[:, i].to_pandas(),
                                                        monthsNum4runavg_yearly, center=True).mean()
        FWTransports_runavg_yearly2 = pd.Series.rolling(ds2.FWTransport[:, i].to_pandas(),
                                                        monthsNum4runavg_yearly, center=True).mean()
        FWTransports_runavg1 = pd.Series.rolling(ds1.FWTransport[:, i].to_pandas(),
                                                 monthsNum4runavg, center=True).mean()
        FWTransports_runavg2 = pd.Series.rolling(ds2.FWTransport[:, i].to_pandas(),
                                                 monthsNum4runavg, center=True).mean()

        f1.write('%s %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f\n' % \
                 (transectName_forfigfile, np.nanmean(volTransports1[:, i]), np.nanstd(volTransports1[:, i]), \
                 np.nanmean(volTransportsIn1[:, i]), np.nanstd(volTransportsIn1[:, i]), np.nanmean(volTransportsOut1[:, i]), np.nanstd(volTransportsOut1[:, i]), \
                 np.nanmean(heatTransports1[:, i]), np.nanstd(heatTransports1[:, i]), np.nanmean(heatTransportsIn1[:, i]), \
                 np.nanstd(heatTransportsIn1[:, i]), np.nanmean(heatTransportsOut1[:, i]), np.nanstd(heatTransportsOut1[:, i]), \
                 np.nanmean(heatTransportsTfp1[:, i]), np.nanstd(heatTransportsTfp1[:, i]), np.nanmean(heatTransportsTfpIn1[:, i]), \
                 np.nanstd(heatTransportsTfpIn1[:, i]), np.nanmean(heatTransportsTfpOut1[:, i]), np.nanstd(heatTransportsTfpOut1[:, i]), \
                 np.nanmean(FWTransports1[:, i]), np.nanstd(FWTransports1[:, i]), np.nanmean(FWTransportsIn1[:, i]), \
                 np.nanstd(FWTransportsIn1[:, i]), np.nanmean(FWTransportsOut1[:, i]), np.nanstd(FWTransportsOut1[:, i])))
        f2.write('%s %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f\n' % \
                 (transectName_forfigfile, np.nanmean(volTransports2[:, i]), np.nanstd(volTransports2[:, i]), \
                 np.nanmean(volTransportsIn2[:, i]), np.nanstd(volTransportsIn2[:, i]), np.nanmean(volTransportsOut2[:, i]), np.nanstd(volTransportsOut2[:, i]), \
                 np.nanmean(heatTransports2[:, i]), np.nanstd(heatTransports2[:, i]), np.nanmean(heatTransportsIn2[:, i]), \
                 np.nanstd(heatTransportsIn2[:, i]), np.nanmean(heatTransportsOut2[:, i]), np.nanstd(heatTransportsOut2[:, i]), \
                 np.nanmean(heatTransportsTfp2[:, i]), np.nanstd(heatTransportsTfp2[:, i]), np.nanmean(heatTransportsTfpIn2[:, i]), \
                 np.nanstd(heatTransportsTfpIn2[:, i]), np.nanmean(heatTransportsTfpOut2[:, i]), np.nanstd(heatTransportsTfpOut2[:, i]), \
                 np.nanmean(FWTransports2[:, i]), np.nanstd(FWTransports2[:, i]), np.nanmean(FWTransportsIn2[:, i]), \
                 np.nanstd(FWTransportsIn2[:, i]), np.nanmean(FWTransportsOut2[:, i]), np.nanstd(FWTransportsOut2[:, i])))

        figfile = '{}/heatTransport_{}_{}_{}.png'.format(figdir, transectName_forfigfile,
                                                         casename1, casename2)
        fig =  plt.figure(figsize=figsize, dpi=figdpi)
        ax = fig.add_subplot()
        for tick in ax.xaxis.get_ticklabels():
            tick.set_fontsize(fontsize_smallLabels)
            tick.set_weight('bold')
        for tick in ax.yaxis.get_ticklabels():
            tick.set_fontsize(fontsize_smallLabels)
            tick.set_weight('bold')
        ax.yaxis.get_offset_text().set_fontsize(fontsize_smallLabels)
        ax.yaxis.get_offset_text().set_weight('bold')

        ax.plot(time1, heatTransports_runavg_yearly1, color='firebrick', linewidth=3,
                label='{} annual mean ({:5.2f} $\pm$ {:5.2f} TW)'.format(casename1,
                np.nanmean(heatTransports_runavg_yearly1), np.nanstd(heatTransports_runavg_yearly1)))
        #ax.plot(time1, heatTransports1[:, i], color='salmon', alpha=0.5, linewidth=1.5,
        #        label='{} monthly'.format(casename1)
        #if transectNames[i] != 'Nares Strait': # skip plotting of Nares Strait for E3SM-LR (strait is closed)
        #    ax.plot(time2, heatTransports_runavg_yearly2, color='k', linewidth=3,
        #            label='E3SM-LR-OSI annual mean ({:5.2f} $\pm$ {:5.2f} TW)'.format(
        #            np.nanmean(heatTransports_runavg_yearly2), np.nanstd(heatTransports_runavg_yearly2)))
        ax.plot(time2, heatTransports_runavg_yearly2, color='k', linewidth=3,
                label='{} annual mean ({:5.2f} $\pm$ {:5.2f} TW)'.format(casename2,
                np.nanmean(heatTransports_runavg_yearly2), np.nanstd(heatTransports_runavg_yearly2)))
        if heatbounds is not None:
            #fig.gca().fill_between(range(1, maxYears+1),
            #                       heatbounds[0]*np.ones_like(range(1, maxYears+1)),
            #                       heatbounds[1]*np.ones_like(range(1, maxYears+1)),
            fig.gca().fill_between([xmin, xmax], [heatbounds[0], heatbounds[0]], [heatbounds[1], heatbounds[1]],
                                   color='limegreen', alpha=0.3, label='obs variability')
        if np.max(heatTransports1[:, i])>0.0 and np.min(heatTransports1[:, i])<0:
            ax.axhline(y=0, color='k', linewidth=1)
        #ax.axvline(x=59, color='blueviolet', linewidth=5)
        #ax.axvline(x=118, color='blueviolet', linewidth=5)
        ax.set_xlabel('Time (Years)', fontsize=fontsize_labels, fontweight='bold')
        ax.set_ylabel('Heat transport (TW)', fontsize=fontsize_labels, fontweight='bold')
        ax.set_title('Heat transport wrt 0 $^\circ$C for {}'.format(transectNames[i]), fontsize=fontsize_titles, fontweight='bold')
        ax.legend(prop=legend_properties)
        #ax.set_xlim(1, maxYears)
        ax.set_xlim(xmin, xmax)
        fig.savefig(figfile, bbox_inches='tight')
        plt.close(fig)

        figfile = '{}/heatTransportTfp_{}_{}_{}.png'.format(figdir, transectName_forfigfile,
                                                            casename1, casename2)
        fig =  plt.figure(figsize=figsize, dpi=figdpi)
        ax = fig.add_subplot()
        for tick in ax.xaxis.get_ticklabels():
            tick.set_fontsize(fontsize_smallLabels)
            tick.set_weight('bold')
        for tick in ax.yaxis.get_ticklabels():
            tick.set_fontsize(fontsize_smallLabels)
            tick.set_weight('bold')
        ax.yaxis.get_offset_text().set_fontsize(fontsize_smallLabels)
        ax.yaxis.get_offset_text().set_weight('bold')

        ax.plot(time1, heatTransportsTfp_runavg_yearly1, color='firebrick', linewidth=3,
                label='{} annual mean ({:5.2f} $\pm$ {:5.2f} TW)'.format(casename1,
                np.nanmean(heatTransportsTfp_runavg_yearly1), np.nanstd(heatTransportsTfp_runavg_yearly1)))
        #ax.plot(time1, heatTransportsTfp1[:, i], color='salmon', alpha=0.5, linewidth=1.5,
        #        label='{} monthly'.format(casename1))
        #if transectNames[i] != 'Nares Strait': # skip plotting of Nares Strait for E3SM-LR (strait is closed)
        #    ax.plot(time2, heatTransportsTfp_runavg_yearly2, color='k', linewidth=3,
        #            label='E3SM-LR-OSI annual mean ({:5.2f} $\pm$ {:5.2f} TW)'.format(
        #            np.nanmean(heatTransportsTfp_runavg_yearly2), np.nanstd(heatTransportsTfp_runavg_yearly2)))
        ax.plot(time2, heatTransportsTfp_runavg_yearly2, color='k', linewidth=3,
                label='{} annual mean ({:5.2f} $\pm$ {:5.2f} TW)'.format(casename2,
                np.nanmean(heatTransportsTfp_runavg_yearly2), np.nanstd(heatTransportsTfp_runavg_yearly2)))
        if heatbounds is not None:
            #fig.gca().fill_between(range(1, maxYears+1),
            #                       heatbounds[0]*np.ones_like(range(1, maxYears+1)),
            #                       heatbounds[1]*np.ones_like(range(1, maxYears+1)),
            fig.gca().fill_between([xmin, xmax], [heatbounds[0], heatbounds[0]], [heatbounds[1], heatbounds[1]],
                                   color='limegreen', alpha=0.3, label='obs variability')
        if np.max(heatTransportsTfp1[:, i])>0.0 and np.min(heatTransportsTfp1[:, i])<0:
            ax.axhline(y=0, color='k', linewidth=1)
        #ax.axvline(x=59, color='blueviolet', linewidth=5)
        #ax.axvline(x=118, color='blueviolet', linewidth=5)
        ax.set_xlabel('Time (Years)', fontsize=fontsize_labels, fontweight='bold')
        ax.set_ylabel('Heat transport (TW)', fontsize=fontsize_labels, fontweight='bold')
        ax.set_title('Heat transport wrt freezing point for {}'.format(transectNames[i]), fontsize=fontsize_titles, fontweight='bold')
        ax.legend(prop=legend_properties)
        #ax.set_xlim(1, maxYears)
        ax.set_xlim(xmin, xmax)
        fig.savefig(figfile, bbox_inches='tight')
        plt.close(fig)

        figfile = '{}/FWTransport_{}_{}_{}.png'.format(figdir, transectName_forfigfile,
                                                       casename1, casename2)
        fig =  plt.figure(figsize=figsize, dpi=figdpi)
        ax = fig.add_subplot()
        for tick in ax.xaxis.get_ticklabels():
            tick.set_fontsize(fontsize_smallLabels)
            tick.set_weight('bold')
        for tick in ax.yaxis.get_ticklabels():
            tick.set_fontsize(fontsize_smallLabels)
            tick.set_weight('bold')
        ax.yaxis.get_offset_text().set_fontsize(fontsize_smallLabels)
        ax.yaxis.get_offset_text().set_weight('bold')

        ax.plot(time1, FWTransports_runavg_yearly1, color='firebrick', linewidth=3,
                label='{} annual mean ({:5.2f} $\pm$ {:5.2f} km$^3$/year)'.format(casename1,
                np.nanmean(FWTransports_runavg_yearly1), np.nanstd(FWTransports_runavg_yearly1)))
        #ax.plot(time1, FWTransports1[:, i], color='salmon', alpha=0.5, linewidth=1.5,
        #        label='{} monthly'.format(casename1))
        #ax.plot(time1, FWTransports_runavg1, color='k', linewidth=3,
        #        label='60to10 5-year mean ({:5.2f} $\pm$ {:5.2f} km$^3$/year)'.format(
        #        np.nanmean(FWTransports_runavg1), np.nanstd(FWTransports_runavg1)))
        #ax.plot(time2, FWTransports_runavg2, color='firebrick', linewidth=3,
        #        label='60to6 5-year mean ({:5.2f} $\pm$ {:5.2f} km$^3$/year)'.format(
        #        np.nanmean(FWTransports_runavg2), np.nanstd(FWTransports_runavg2)))
        #if transectNames[i] != 'Nares Strait': # skip plotting of Nares Strait for E3SM-LR (strait is closed)
        #    ax.plot(time2, FWTransports_runavg_yearly2, color='k', linewidth=3,
        #            label='E3SM-LR-OSI annual mean ({:5.2f} $\pm$ {:5.2f} km$^3$/year)'.format(
        #            np.nanmean(FWTransports_runavg_yearly2), np.nanstd(FWTransports_runavg_yearly2)))
        ax.plot(time2, FWTransports_runavg_yearly2, color='k', linewidth=3,
                label='{} annual mean ({:5.2f} $\pm$ {:5.2f} km$^3$/year)'.format(casename2,
                np.nanmean(FWTransports_runavg_yearly2), np.nanstd(FWTransports_runavg_yearly2)))
        if FWbounds is not None:
            #fig.gca().fill_between(range(1, maxYears+1),
            #                       FWbounds[0]*np.ones_like(range(1, maxYears+1)),
            #                       FWbounds[1]*np.ones_like(range(1, maxYears+1)),
            fig.gca().fill_between([xmin, xmax], [FWbounds[0], FWbounds[0]], [FWbounds[1], FWbounds[1]],
                                   color='limegreen', alpha=0.3, label='obs variability')
        if np.max(FWTransports1[:, i])>0.0 and np.min(FWTransports1[:, i])<0:
            ax.axhline(y=0, color='k', linewidth=1)
        #ax.axvline(x=59, color='blueviolet', linewidth=5)
        #ax.axvline(x=118, color='blueviolet', linewidth=5)
        ax.set_xlabel('Time (Years)', fontsize=fontsize_labels, fontweight='bold')
        ax.set_ylabel('Freshwater transport (km$^3$/year)', fontsize=fontsize_labels, fontweight='bold')
        ax.set_title('Freshwater transport for {}'.format(transectNames[i]), fontsize=fontsize_titles, fontweight='bold')
        ax.legend(prop=legend_properties)
        #ax.set_xlim(1, maxYears)
        ax.set_xlim(xmin, xmax)
        fig.savefig(figfile, bbox_inches='tight')
        plt.close(fig)
f1.close()
f2.close()


#!bin/python

import os
import sys
import numpy as np
import cmath
from numpy import linalg as LA

sys.path.append('../../0/emitchell/')
from molecule import Molecule

class Frequency(object):   # Builds Frequency class
	def __init__(self,hess_file,xyz_file):   # Initializes class with Hessian file specified and .xyz file specified
		with open(hess_file) as f:   # Reads in Hessian file
			hess = [line.split() for line in f]   # Makes Hessian into a list of lists
		try:   # Makes sure Hessian is only numbers
			hess = [list(map(float,i)) for i in hess]   # Makes Hessian into numbers
		except:
			sys.exit("Error: Hessian file must consist of real numbers only.")
		self.hess = np.array(hess)
		try:   # Reads in .xyz file and checks if file exists
			self.mol = Molecule(xyz_file)   # Sends .xyz file to molecule.py
		except:
			sys.exit("Error: xyz file given cannot be found.")

	def frequencies(self,Mol,Hess):   # Gets the normal modes and coordinates to be put into a usable JMOL file
		# Constants
		Eh = 4.359784E-18
		BohrR = 5.29177249E-11
		c = 2.99792458E10
		amu_to_kg = 1.6605402E-27
		# Builds mass matrix
		M = [i for i in Mol.masses for j in range(Mol.natom)]
		M = np.array(M) ** (-1/2)
		M = np.diag(M)
		try:   # Creates the mass-weighted Hessian and checks if the matrices have compatible dimensions
			self.mwHess = LA.multi_dot([M,Hess,M])
		except:
			sys.exit("Error: Dimensions of molecule and Hessian do not match. Check files.")
		vals, vecs = LA.eigh(self.mwHess)   # Solves the mass-weighted Hessian and returns the eigenvalues and eigenvectors
		evecs = M.dot(vecs)   # Builds the un-mass-weighted eigenvectors
		Q = np.transpose(evecs)   # Puts the eigenvectors into columns
		evals = vals * (Eh / ((BohrR ** (2)) * amu_to_kg ))   # Converts the eigenvalues into rad^2 / s^2 units
		k = [cmath.sqrt(i) for i in evals]
		K = []
		for i in k:   #   Checks if imaginary frequencies are present
			if np.imag(i) != 0:
				i = np.imag(i)*1j   # Makes the imaginary value usable
			else:
				i = np.real(i)
			K.append((1 / (2 * np.pi * c)) * i)   # Converts eigenvalues into wavenumbers
		self.Jmol(K,Q,Mol)

	def Jmol(self,Evals,Evecs,Mol):   # Writes a usable JMOL file with the values and vectors from frequencies
		f = open('JMOL','w')
		Mol.to_Angstrom()   # Changes coordinates to Angstroms
		string = ""
		for i in range(3 * Mol.natom):    # Loop to create the file
			string += str(Mol.natom) + "\n"
			if np.imag(Evals[i]) != 0:
				string += "{:7.2f}i cm^-1\n".format(np.imag(Evals[i]))
			else:
				string += "{:7.2f} cm^-1\n".format(Evals[i])
			k = 0   # Allows normal coordinates to be written in the same loop as the geometric coordinates
			for j in range(Mol.natom):
				string += "{:<2} {: 14.10f} {: 14.10f} {: 14.10f} {: 14.10f} {: 14.10f} {: 14.10f}\n".format(Mol.labels[j],Mol.geom[j][0],Mol.geom[j][1],Mol.geom[j][2],Evecs[i][k],Evecs[i][k+1],Evecs[i][k+2])
				k += 3
			string += "\n"
		f.write(string)
		f.close()

if __name__ == "__main__":
	freq = Frequency('../../extra-files/hessian.dat','../../extra-files/molecule.xyz')
	freq.frequencies(freq.mol,freq.hess)


import os, sys
import json
from pychatworkAPI.pychatworkAPI import api as cwapi

# read config
backslash = ""
if os.name == "nt":
    backslash = os.path.dirname(os.path.abspath(__file__)) + ".\\"

def main():
    message = read_message(retrieve_arg())
    send_message(message)

def retrieve_arg(): return str(sys.argv[1]) if len(sys.argv) > 1 else ""

def read_message(id):
    ''' read a text in messages.json '''
    if id == "":
        print("This script needs to take an argument.")
        return

    # read
    with open(backslash + 'messages.json', "r", encoding="utf-8") as f:
        messages = json.load(f)["messages"]
        for message in messages:
            if message["id"] == id: return message

def send_message(message):
    ''' send a message on Chatowork'''
    if message == None:
        return
    chatwork = cwapi.Chatwork(message["api_key"])
    chatwork.send_message(message["room_id"], message["body"])

if __name__ == "__main__":
    main()


from typing import List

def get_matrix_from_string_list(str_list):
    grid = []
    for i, ele in enumerate(str_list):
        grid.append([int(char) for char in ele])
    return grid

#
# def dfs(idx, length, matrix):
#     if matrix[idx][idx] == 0:
#         return
#     for i in range(length):
#         if matrix[idx][i] == 1:
#             matrix[idx][i] = 0
#             dfs(i, length, matrix)
#
#
# def countGroups(related):
#     grid = get_matrix_from_string_list(related)
#     for ele in grid:
#         print(ele)
#
#     count = 0
#     length = len(related)
#     for indx in range(length):
#         if related[indx][indx] == 1:
#             count += 1
#             dfs(indx, length, related)
#     return count
#
#
# def findCircleNum(related):
#     grid = get_matrix_from_string_list(related)
#     visited = set()
#
#     def dfs(node):
#         print("grid[i] = ", grid[i])
#         for neighbour, adj in enumerate(grid[node]):
#             print(neighbour, adj)
#
#             if adj and neighbour not in visited:
#                 visited.add(neighbour)
#                 dfs(neighbour)
#
#     group_count = 0
#     for i in range(len(grid)):
#         print("for row:", i)
#         if i not in visited:
#             dfs(i)
#             group_count += 1
#     return group_count

def findCircleNum2(grid: List[List[int]]) -> int:
    if not grid:
        return 0

    grid_len = len(grid)
    visited = [False] * grid_len

    def dfs(i):
        for j in range(grid_len):
            if grid[i][j] == 1 and not visited[j]:
                visited[j] = True
                dfs(j)

    group_count = 0
    for i in range(grid_len):
        print("i", i)
        if not visited[i]:
            # Increment count for each unvisited person (and his group) and mark them visited
            group_count += 1
            visited[i] = True
            # Use dfs to mark his relations/group visited
            dfs(i)

    return group_count

print(findCircleNum2(get_matrix_from_string_list(['1100', '1110', '0110', '0001'])))


import numpy as np
import matplotlib.pyplot as plt
from scipy import sparse
from CSMSSMTools import *
import time

def getContinuousRuns(x):
    """
    Given a 1D array, find all of the continuous runs
    of 1s, and count the numbers with a certain length
    :param x: 1D array
    :returns Runs: A frequency distribution dictionary of
        the form {length:counts}
    """
    Runs = {}
    (IN_ZEROS, IN_ONES) = (0, 1)
    state = IN_ZEROS
    count = 0
    for i in range(len(x)):
        if state == IN_ZEROS:
            if x[i] == 1:
                state = IN_ONES
                count = 1
        elif state == IN_ONES:
            if x[i] == 0:
                if not count in Runs:
                    Runs[count] = 0
                Runs[count] += 1
                state = IN_ZEROS
            elif x[i] == 1:
                count += 1
    return Runs

def getRQAVerts(R):
    """
    Return a frequency distribution of the vertical 1s
    in an RQA plot
    :param R: An RQA Plot
    :returns Runs: A frequency distribution dictionary of
        the form {length:counts}
    """
    N = R.shape[0]
    D = np.zeros((N+1, N+1))
    D[0:N, 0:N] = R
    return getContinuousRuns(D.flatten())

def getRQADiags(R):
    """
    Return a frequency distribution of the diagonal 1s
    in an RQA plot
    :param R: An RQA Plot
    :returns Runs: A frequency distribution dictionary of
        the form {length:counts}
    """
    x = []
    for i in range(1, R.shape[1]):
        x += np.diagonal(R, i).tolist() + [0]
    return getContinuousRuns(x)

def zeroDenom(x):
    if x == 0:
        return 1.0
    return x

def getRQAStats(R, dmin, vmin):
    """
    Compute different recurrence quantification statistics.
    See http://www.recurrence-plot.tk/ for more details
    :param R: NxN RQA plot (binary matrix)
    :param dmin: Minimum diagonal length
    :param vmin: Minimum vertical length
    :returns: Dictionary of features
    """
    Verts = getRQAVerts(R)
    Diags = getRQADiags(R)
    N = R.shape[0]
    [I, J] = np.meshgrid(np.arange(N), np.arange(N))

    #Expected value of diagonal lengths above a certain length
    SumDiags = np.sum(np.array([c*Diags[c] for c in Diags if c >= dmin]))
    SumDiags = float(SumDiags)
    #Expected value of vertical lengths above a certain length
    SumVerts = np.sum(np.array([c*Verts[c] for c in Verts if c >= vmin]))
    SumVerts = float(SumVerts)

    #Recurrence rate
    RR = np.sum(R == 1)/float(R.size)

    #Determinism
    DET = SumDiags/zeroDenom(float(np.sum(R[I > J])))

    #Laminarity
    denom = np.sum(np.array([c*Verts[c] for c in Verts]))
    LAM = SumVerts/zeroDenom(denom)

    #Ratio
    denom = (np.sum(np.array([Diags[c] for c in Diags])))**2
    RATIO = float(R.size)*SumDiags/zeroDenom(denom)

    #Average diag length
    NDiags = np.sum(np.array([Diags[c] for c in Diags if c >= dmin]))
    NDiags = zeroDenom(float(NDiags))
    L = SumDiags / NDiags

    #Trapping Time (Average vertical length)
    NVerts = np.sum(np.array([Verts[c] for c in Verts if c >= vmin]))
    NVerts = zeroDenom(float(NVerts))
    TT = SumVerts / NVerts

    #Entropy
    ps = np.array([Diags[c]/NDiags for c in Diags if c >= dmin])
    ENTR = -np.sum(ps*np.log(ps))

    #Longest diag line
    Lmax = 0
    if len(Diags) > 0:
        Lmax = np.max(np.array([c for c in Diags]))

    #Longest vert line
    Vmax = 0
    if len(Verts) > 0:
        Vmax = np.max(np.array([c for c in Verts]))

    return {'RR':RR, 'DET':DET, 'LAM':LAM, 'RATIO':RATIO, 'L':L, 'TT':TT, 'ENTR':ENTR, 'Lmax':Lmax, 'Vmax':Vmax}

if __name__ == '__main__':
    t = np.linspace(0, 2*np.pi, 200)
    X = np.cos(4*t)
    D = np.abs(X[:, None] - X[None, :])
    R = CSMToBinaryMutual(D, 0.2)
    stats = getRQAStats(R, 5, 5)
    for s in stats:
        print("%s: %.3g"%(s, stats[s]))
    plt.imshow(R)
    plt.show()


import click
import json
from utils import connect_serial

@click.command()
@click.argument('target', default="FF-FF-FF-FF-FF-FF") # Setup your default Macs here
@click.argument('ap', default="") # Setup your default Macs here
@click.argument("ssid", default="None") # Setup your default Evil SSID here
@click.argument('chan', default=11) # Setup your default Chan here
@click.argument('delay', default=1000) # Setup your default delay here
def main(target, ap, chan, ssid, delay):
	try:
		targetInput = input(
			"[?] Select a target (default '%s'): " % target)
		if targetInput != "":
			target = targetInput
	except KeyboardInterrupt:
		print("\n[+] Exiting...")
		exit()

	try:
		apInput = input("[?] Select an AP (default '%s'): " % ap)
		if apInput != "":
			ap = apInput
	except KeyboardInterrupt:
		print("\n[+] Exiting...")
		exit()

	try:
		delayInput = input("[?] Select delay (default '%s'): " % delay)
		if delayInput != "":
			delay = int(delayInput)
	except KeyboardInterrupt:
		print("\n[+] Exiting...")
		exit()

	apInput = apInput.upper().replace(":", "-").replace(" ", "-")
	targetInput = targetInput.upper().replace(":", "-").replace(" ", "-")

	country = "FR"
	try:
		countryInput = input("[?] Select a country (default '%s'): " % country)
		if countryInput != "":
			country = countryInput
	except KeyboardInterrupt:
		print("\n[+] Exiting...")
		exit()

	try:
		chanInput = input("[?] Select a channel (default '%d'): " % chan)
		if chanInput != "":
			chan = int(chanInput)
	except KeyboardInterrupt:
		print("\n[+] Exiting...")
		exit()

	try:
		ssidInput = input("[?] Select a twin ssid (default '%s'): " % ssid)
		ssid = ssidInput
	except KeyboardInterrupt:
		print("\n[+] Exiting...")
		exit()

	ser, filename = connect_serial(timeout=1)

	f = open(filename, 'wb')

	# set country
	ser.write(("set country %s\r\n" % country).encode())
	ln = ser.read_until(b"\r\n").decode("utf-8")
	try:
		if (ln == None or len(ln) == 0):
			print("Empty country setting, exiting...")
			exit()
		try:
			j = json.loads(ln)
			recv_country = j.get("WIFI_COUNTRY")
			if recv_country != country:
				print("Error 1 setting country, exiting...")
				exit()
		except:
			print("Error 2 setting country, exiting...")
			exit()
	except:
		print("Error 3 setting country, exiting...")
		exit()

	# set channel
	ser.write(("set chan %d\r\n" % (chan)).encode())
	ln = ser.read_until(b"\r\n").decode("utf-8")
	try:
		if (ln == None or len(ln) == 0):
			print("Empty channel setting, exiting...")
			exit()
		try:
			j = json.loads(ln)
			recv_chan = j.get("WIFI_CHANNEL")
			if recv_chan != chan:
				print("Error 1 setting channel, exiting...")
				exit()
		except:
			print("Error 2 setting channel, exiting...")
			exit()
	except:
		print("Error 3 setting channel, exiting...")
		exit()

	ser.write(("wifi_deauth %s %s %s %d 1\r\n" % (target, ap, ssid, delay)).encode())
	print("[+] Deauther started...")

	try:
		while True:
			ln = ser.read_until(b"<STOP>")
			f.write(ln.replace(b"<STOP>", b""))
			f.flush()
	except KeyboardInterrupt:
		ser.write("stop\r\n".encode())
		print("[+] Stopping...")

	f.close()
	ser.close()
	print("[+] Done.")

if __name__ == "__main__":
    main()


from typing import List
import matplotlib.pyplot as plt
import os

class Plotter():

    def __init__(self, figures_path: str):

        self.figures_path = figures_path

    def save_plots(self,
                   iteration: int,
                   p_train_losses: List[float],
                   p_val_losses: List[float],
                   v_train_losses: List[float],
                   v_val_losses: List[float],
                   v_train_acc: List[float],
                   v_val_acc: List[float]):

        x = [i for i in range(len(p_train_losses))]

        p_loss_fig = plt.figure()
        p_loss_fig_axis = p_loss_fig.add_subplot()
        p_loss_fig_axis.plot(x, p_train_losses)
        p_loss_fig_axis.plot(x, p_val_losses)
        p_loss_fig.savefig(os.path.join(self.figures_path, f'{iteration}_P_loss.png'))

        v_loss_fig = plt.figure()
        v_loss_fig_axis = v_loss_fig.add_subplot()
        v_loss_fig_axis.plot(x, v_train_losses)
        v_loss_fig_axis.plot(x, v_val_losses)
        v_loss_fig.savefig(os.path.join(self.figures_path, f'{iteration}_V_loss.png'))

        v_acc_fig = plt.figure()
        v_acc_fig_axis = v_acc_fig.add_subplot()
        v_acc_fig_axis.plot(x, v_train_acc)
        v_acc_fig_axis.plot(x, v_val_acc)
        v_acc_fig.savefig(os.path.join(self.figures_path, f'{iteration}_V_acc.png'))
        plt.close('all')


import numpy as np
import matplotlib.pyplot as plt
import datetime
import sys

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D
from tensorflow.keras.layers import Activation, Dropout, Flatten, Dense
from tensorflow.keras import backend as K

from sklearn.pipeline import make_pipeline
from sklearn.model_selection import StratifiedKFold, cross_val_score

import mne
from pyts.image import RecurrencePlot
import gc

import os
import glob
import sys
sys.path.append('.')
from braininvaders2014a.dataset import BrainInvaders2014a
from pathlib import Path

def multivariateRP(sample, electrodes, dimension, time_delay, percentage):

    channels_N = sample.shape[0]

    #Time window = T
    #delta = 40, the interval T is chpped into epochs of delta elements
    #T is the time interval to be taken from the epoch sample beginning

    delta = time_delay
    points_n = dimension

    #we need to leave enough space for the last space at the end to perform n=dimension jumps over time_delay data
    T = sample.shape[1] - ((dimension-1) * time_delay)

    #T = ((dimension-1) * time_delay)

    print("T=",T)
    X_traj = np.zeros((T,points_n * channels_N))

    for i in range(0,T): #delta is number of vectors with  length points_n

        for j in range(0,points_n): #j is inside the sample data and jumps over the points
            start_pos = j * delta
            pos = start_pos + i

            for e in electrodes:
                #print(e)
                pos_e = (e * points_n) + j
                #print(pos_e)
                #all points first channel,
                print(i, pos_e, e, pos)
                X_traj[i, pos_e ] = sample[e,pos] #i is the vector, j is indexing isnide the vector
            #print(pos)

    X_dist = np.zeros((T,T))

    #calculate distances
    for i in range(0,T): #i is the vector
        for j in range(0,T):
             v1 = X_traj[i,:]
             v2 = X_traj[j,:]
             X_dist[i,j] = np.sqrt( np.sum((v1 - v2) ** 2) )

    percents = np.percentile(X_dist,percentage)

    X_rp = X_dist < percents

    return X_rp

dataset = BrainInvaders2014a() #https://hal.archives-ouvertes.fr/hal-02171575/document

def CreateData(m, tau , filter_fmin, filter_fmax, electrodes, n_subjects, percentage, max_epochs_per_subject):

    folder = "D:\Work\ML_examples\EEG\py.BI.EEG.2014a-GIPSA\data"

    folder = folder + "\\rp_m_" + str(m) + "_tau_" + str(tau) + "_f1_"+str(filter_fmin) + "_f2_"+ str(filter_fmax) + "_el_" + str(len(electrodes)) + "_nsub_" + str(n_subjects) + "_per_" + str(percentage) + "_nepo_" + str(max_epochs_per_subject)

    # print(folder)

    # if not os.path.exists(folder):
    #     os.makedirs(folder)

    # print("Clean data:")

    # files = glob.glob(folder + "\\*")
    # for f in files:
    #     if f.endswith(".npy"):
    #         os.remove(f)

    print("Write rp image data:")

    for subject in range(1,2):

        #load data
        print("Subject =",subject)
        sessions = dataset._get_single_subject_data(subject)
        raw = sessions['session_1']['run_1']

        # filter data and resample
        fmin = filter_fmin
        fmax = filter_fmax
        raw.filter(fmin, fmax, verbose=False)

        # detect the events and cut the signal into epochs
        events = mne.find_events(raw=raw, shortest_event=1, verbose=False)
        event_id = {'NonTarget': 1, 'Target': 2}
        epochs = mne.Epochs(raw, events, event_id, tmin=0.0, tmax=0.8, baseline=None, verbose=False, preload=True)
        epochs.pick_types(eeg=True)

        # get trials and labels

        epochs_subject = epochs

        epochs_class_1 = 0
        epochs_class_2 = 0

        for i in range(0, 1):

            single_epoch_subject_data = epochs_subject[i]._data[0,:,:]

            label = list(epochs_subject[i].event_id.values())[0]-1 #sigmoid requires that labels are [0..1]

            #save
            if (label==0 and epochs_class_1 < max_epochs_per_subject) or (label==1 and epochs_class_2 < max_epochs_per_subject):

                single_epoch_subject_rp = multivariateRP(single_epoch_subject_data, electrodes, m, tau, percentage)

                plt.imshow(single_epoch_subject_rp, cmap='binary', origin='lower')

#m, tau , filter_fmin, filter_fmax, electrodes, n_subjects, percentage, max_epochs_per_subject

CreateData(4,30,1,20,[6,13,14,15],10,20,20)


import csv
import json
import os
from collections import defaultdict

import jinja2
import webapp2

from models import Orders

JE = jinja2.Environment(
    loader = jinja2.FileSystemLoader(os.path.join(os.path.dirname(__file__), 'templates')),
    extensions = ['jinja2.ext.autoescape'],
    autoescape = True,
    variable_start_string = '[[',
    variable_end_string = ']]'
)

class Handler(webapp2.RequestHandler):
    def write(self, *a, **kw):
        self.response.write(*a, **kw)

    def render_str(self, template, **params):
        t = JE.get_template(template)
        return t.render(params)

    def render(self, template, **kw):
        self.write(self.render_str(template, **kw))

class Form(Handler):
    def get(self):
        payload = { 'ctrl': 'formCtrl' }
        self.render('form.html', **payload)

    def post(self):
        data = json.loads(self.request.body)
        name = data['name']
        phone = data['phone']
        email = data['email']
        orders = data['orders']
        Orders.set_order(name, phone, email, orders)
        self.response.write(json.dumps({ "done": True }))

class Index(Handler):
    def get(self):
        payload = { 'ctrl': 'indexCtrl' }
        self.render('index.html', **payload)

    def post(self):
        data = json.loads(self.request.body)
        phone = data['phone']
        orders = Orders.get_order(phone)
        print(orders)
        if orders is None:
            self.response.write(json.dumps({ 'orders': None }))
        else:
            self.response.write(json.dumps(orders.to_dict()))

class Summary(Handler):
    def get(self):
        payload = { 'ctrl': 'SummaryCtrl' }
        self.render('summary.html', **payload)

    def post(self):
        orders = Orders.get_all()
        ret = []
        dd = defaultdict(int)

        for i in orders:
            ret.append(i.to_dict())
            for j in i.orders:
                value1 = 0 if j['qty'] is None else j['qty']
                dd[j['name']] += value1

        agg = []
        for key, value in dd.items():
            agg.append({ 'name': key, 'qty': value })
        if len(ret) > 0:
            self.response.write(json.dumps({ 'ret': ret, 'agg': agg }))
        else:
            self.response.write(json.dumps(None))

class Download(Handler):
    def get(self):
        self.response.headers['Content-Type'] = 'application/csv'
        self.response.headers['Content-Disposition'] = 'attachment; filename=summary.csv'
        orders = Orders.get_all()
        writer = csv.writer(self.response.out)
        writer.writerow(['Name', 'Email', 'Phone', 'Orders', "Total"])
        for i in orders:
            items = ""
            total = 0
            for j in i.orders:
                value1 = 0 if j['qty'] is None else j['qty']
                total += (value1 * j['price'])
                items += "%s %s ; " % (j['name'], value1)
            row = i.name, i.email, i.phone, items, total
            writer.writerow(row)

class Persist(Handler):
    def post(self):
        data = json.loads(self.request.body)
        phone = data['phone']
        try:
            phone = int(phone)
        except:
            self.response.write(json.dumps({'data': False}))
        orders = Orders.get_order(phone).orders
        self.response.write(json.dumps({'data': orders}))

app = webapp2.WSGIApplication([
    webapp2.Route('/', handler = Index, name = "Index"),
    webapp2.Route('/form', handler = Form, name = "Form"),
    webapp2.Route('/all', handler = Summary),
    webapp2.Route('/summary', handler = Summary),
    webapp2.Route('/all/download', handler = Download, name = "Download"),
    webapp2.Route('/summary/download', handler = Download, name = "Download"),
    webapp2.Route('/past', handler = Persist, name = "Persist")
], debug = True)


import boto3
import time
import subprocess
from send_email import send_email
from datetime import datetime,timedelta
import json

def lambda_handler(event,context):

    s3_file_list = []

    s3_client=boto3.client('s3')
    for object in s3_client.list_objects_v2(Bucket='mid-term-wh-dump')['Contents']:
        s3_file_list.append(object['Key'])
    print('s3_file_list:', s3_file_list)

    # datestr = datetime.date.today()
    tomorrow=datetime.now() + timedelta(1)
    datestr = tomorrow.strftime("%Y%m%d")

    required_file_list = [f'sales_{datestr}.csv.gz',f'inventory_{datestr}.csv.gz',f'product_{datestr}.csv.gz',
    f'store_{datestr}.csv.gz',f'calendar_{datestr}.csv.gz']

    # required_file_list = [f'sales_inv_store_wk_{datestr}.csv.gz',f'sales_inv_store_dy_{datestr}.csv.gz']

    # required_file_list=[f'sales_{datestr}.csv.gz']

    print("required_file_list:",required_file_list)

    # scan S3 bucket
    if set(s3_file_list)==set(required_file_list):
        s3_file_url = ['s3://' + 'mid-term-wh-dump/' + a for a in s3_file_list]
        print(s3_file_url)
        table_name = [a[:-16] for a in s3_file_list]
        print(table_name)

        data = json.dumps({'conf':{a: b for a,b in zip(table_name,s3_file_url)}})
        print(data)
    # send signal to Airflow
        endpoint= 'http://44.207.230.54/api/v1/dags/a_midterm_dag/dagRuns'

        subprocess.run(["curl","-X","POST", endpoint,"-H","Content-Type:application/json","--user","airflow:airflow","-d", data])
        print('File are send to Airflow')
    else:
        send_email()


import random
from collections import defaultdict
from copy import deepcopy
from typing import Any, Dict, List, Union

import boto3
from botocore.exceptions import ClientError
from chaoslib.exceptions import ActivityFailed, FailedActivity
from chaoslib.types import Configuration, Secrets
from logzero import logger

from chaosaws import aws_client
from chaosaws.types import AWSResponse

__all__ = [
    "stop_instance",
    "stop_instances",
    "terminate_instances",
    "terminate_instance",
    "start_instances",
    "restart_instances",
    "detach_random_volume",
    "attach_volume",
]

def stop_instance(
    instance_id: str = None,
    az: str = None,
    force: bool = False,
    filters: List[Dict[str, Any]] = None,
    configuration: Configuration = None,
    secrets: Secrets = None,
) -> List[AWSResponse]:
    """
    Stop a single EC2 instance.

    You may provide an instance id explicitly or, if you only specify the AZ,
    a random instance will be selected. If you need more control, you can
    also provide a list of filters following the documentation
    https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Client.describe_instances
    """

    if not az and not instance_id and not filters:
        raise FailedActivity(
            "To stop an EC2 instance, you must specify either the instance id,"
            " an AZ to pick a random instance from, or a set of filters."
        )

    if az and not instance_id and not filters:
        logger.warning(
            "Based on configuration provided I am going to "
            "stop a random instance in AZ %s!" % az
        )

    client = aws_client("ec2", configuration, secrets)

    if not instance_id:
        filters = deepcopy(filters) if filters else []

        if az:
            filters.append({"Name": "availability-zone", "Values": [az]})
        instance_types = pick_random_instance(filters, client)

        if not instance_types:
            raise FailedActivity(f"No instances in availability zone: {az}")
    else:
        instance_types = get_instance_type_by_id([instance_id], client)

    logger.debug(f"Picked EC2 instance '{instance_types}' from AZ '{az}' to be stopped")

    return stop_instances_any_type(
        instance_types=instance_types, force=force, client=client
    )

def stop_instances(
    instance_ids: List[str] = None,
    az: str = None,
    filters: List[Dict[str, Any]] = None,
    force: bool = False,
    configuration: Configuration = None,
    secrets: Secrets = None,
) -> List[AWSResponse]:
    """
    Stop the given EC2 instances or, if none is provided, all instances
    of the given availability zone. If you need more control, you can
    also provide a list of filters following the documentation
    https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Client.describe_instances
    """

    if not az and not instance_ids and not filters:
        raise FailedActivity(
            "To stop EC2 instances, you must specify either the instance ids,"
            " an AZ to pick random instances from, or a set of filters."
        )

    if az and not instance_ids and not filters:
        logger.warning(
            "Based on configuration provided I am going to "
            "stop all instances in AZ %s!" % az
        )

    client = aws_client("ec2", configuration, secrets)

    if not instance_ids:
        filters = deepcopy(filters) if filters else []

        if az:
            filters.append({"Name": "availability-zone", "Values": [az]})
        instance_types = list_instances_by_type(filters, client)

        if not instance_types:
            raise FailedActivity(f"No instances in availability zone: {az}")
    else:
        instance_types = get_instance_type_by_id(instance_ids, client)

    logger.debug(
        "Picked EC2 instances '{}' from AZ '{}' to be stopped".format(
            str(instance_types), az
        )
    )

    return stop_instances_any_type(
        instance_types=instance_types, force=force, client=client
    )

def terminate_instance(
    instance_id: str = None,
    az: str = None,
    filters: List[Dict[str, Any]] = None,
    configuration: Configuration = None,
    secrets: Secrets = None,
) -> List[AWSResponse]:
    """
    Terminates a single EC2 instance.

    An instance may be targeted by specifying it by instance-id. If only the
    availability-zone is provided, a random instances in that AZ will be
    selected and terminated. For more control, please reference the available
    filters found:
    https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Client.describe_instances
    """

    if not any([instance_id, az, filters]):
        raise FailedActivity(
            "To terminate an EC2, you must specify the "
            "instance-id, an Availability Zone, or provide a "
            "set of filters"
        )

    if az and not any([instance_id, filters]):
        logger.warning(
            "Based on configuration provided I am going to "
            "terminate a random instance in AZ %s!" % az
        )

    client = aws_client("ec2", configuration, secrets)
    if not instance_id:
        filters = deepcopy(filters) or []

        if az:
            filters.append({"Name": "availability-zone", "Values": [az]})
            logger.debug("Looking for instances in AZ: %s" % az)

        # Randomly select an instance
        instance_types = pick_random_instance(filters, client)

        if not instance_types:
            raise FailedActivity(
                "No instances found matching filters: %s" % str(filters)
            )

        logger.debug("Instance selected: %s" % str(instance_types))
    else:
        instance_types = get_instance_type_by_id([instance_id], client)

    return terminate_instances_any_type(instance_types, client)

def terminate_instances(
    instance_ids: List[str] = None,
    az: str = None,
    filters: List[Dict[str, Any]] = None,
    configuration: Configuration = None,
    secrets: Secrets = None,
) -> List[AWSResponse]:
    """
    Terminates multiple EC2 instances

    A set of instances may be targeted by providing them as the instance-ids.

    WARNING: If  only an Availability Zone is specified, all instances in
    that AZ will be terminated.

    Additional filters may be used to narrow the scope:
    https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Client.describe_instances
    """
    if not any([instance_ids, az, filters]):
        raise FailedActivity(
            "To terminate instances, you must specify the "
            "instance-id, an Availability Zone, or provide a "
            "set of filters"
        )

    if az and not any([instance_ids, filters]):
        logger.warning(
            "Based on configuration provided I am going to "
            "terminate all instances in AZ %s!" % az
        )

    client = aws_client("ec2", configuration, secrets)
    if not instance_ids:
        filters = deepcopy(filters) or []

        if az:
            filters.append({"Name": "availability-zone", "Values": [az]})
            logger.debug("Looking for instances in AZ: %s" % az)

        # Select instances based on filters
        instance_types = list_instances_by_type(filters, client)

        if not instance_types:
            raise FailedActivity(
                "No instances found matching filters: %s" % str(filters)
            )

        logger.debug(f"Instances in AZ {az} selected: {str(instance_types)}}}.")
    else:
        instance_types = get_instance_type_by_id(instance_ids, client)

    return terminate_instances_any_type(instance_types, client)

def start_instances(
    instance_ids: List[str] = None,
    az: str = None,
    filters: List[Dict[str, Any]] = None,
    configuration: Configuration = None,
    secrets: Secrets = None,
) -> List[AWSResponse]:
    """
    Starts one or more EC2 instances.

    WARNING: If only an Availability Zone is provided, all instances in the
    provided AZ will be started.

    Additional filters may be used to narrow the scope:
    https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Client.describe_instances
    """
    if not any([instance_ids, az, filters]):
        raise FailedActivity(
            "To start instances, you must specify the "
            "instance-id, an Availability Zone, or provide a "
            "set of filters"
        )

    if az and not any([instance_ids, filters]):
        logger.warning(
            "Based on configuration provided I am going to "
            "start all instances in AZ %s!" % az
        )

    client = aws_client("ec2", configuration, secrets)

    if not instance_ids:
        filters = deepcopy(filters) or []

        if az:
            filters.append({"Name": "availability-zone", "Values": [az]})
            logger.debug("Looking for instances in AZ: %s" % az)

        # Select instances based on filters
        instance_types = list_instances_by_type(filters, client)

        if not instance_types:
            raise FailedActivity(
                "No instances found matching filters: %s" % str(filters)
            )

        logger.debug(f"Instances in AZ {az} selected: {str(instance_types)}}}.")
    else:
        instance_types = get_instance_type_by_id(instance_ids, client)
    return start_instances_any_type(instance_types, client)

def restart_instances(
    instance_ids: List[str] = None,
    az: str = None,
    filters: List[Dict[str, Any]] = None,
    configuration: Configuration = None,
    secrets: Secrets = None,
) -> List[AWSResponse]:
    """
    Restarts one or more EC2 instances.

    WARNING: If only an Availability Zone is provided, all instances in the
    provided AZ will be restarted.

    Additional filters may be used to narrow the scope:
    https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Client.describe_instances
    """
    if not any([instance_ids, az, filters]):
        raise FailedActivity(
            "To restart instances, you must specify the "
            "instance-id, an Availability Zone, or provide a "
            "set of filters"
        )

    if az and not any([instance_ids, filters]):
        logger.warning(
            "Based on configuration provided I am going to "
            "restart all instances in AZ %s!" % az
        )

    client = aws_client("ec2", configuration, secrets)

    if not instance_ids:
        filters = deepcopy(filters) or []

        if az:
            filters.append({"Name": "availability-zone", "Values": [az]})
            logger.debug("Looking for instances in AZ: %s" % az)

        # Select instances based on filters
        instance_types = list_instances_by_type(filters, client)

        if not instance_types:
            raise FailedActivity(
                "No instances found matching filters: %s" % str(filters)
            )

        logger.debug(f"Instances in AZ {az} selected: {str(instance_types)}}}.")
    else:
        instance_types = get_instance_type_by_id(instance_ids, client)
    return restart_instances_any_type(instance_types, client)

def detach_random_volume(
    instance_ids: List[str] = None,
    filters: List[Dict[str, Any]] = None,
    force: bool = True,
    configuration: Configuration = None,
    secrets: Secrets = None,
) -> List[AWSResponse]:
    """
    Detaches a random ebs volume (non root) from one or more EC2 instances

    Parameters:
        One of:
            instance_ids: a list of one or more ec2 instance ids
            filters: a list of key/value pairs to pull ec2 instances

        force: force detach volume (default: true)

    Additional filters may be used to narrow the scope:
    https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Client.describe_instances
    """
    if not any([instance_ids, filters]):
        raise FailedActivity(
            "To detach volumes, you must specify the "
            "instance_id or provide a set of filters"
        )

    client = aws_client("ec2", configuration, secrets)

    if not instance_ids:
        filters = deepcopy(filters) or []
        instances = list_instance_volumes(client, filters=filters)
    else:
        instances = list_instance_volumes(client, instance_ids=instance_ids)

    results = []
    for e in instances:
        results.append(detach_instance_volume(client, force, e))
    return results

def attach_volume(
    instance_ids: List[str] = None,
    filters: List[Dict[str, Any]] = None,
    configuration: Configuration = None,
    secrets: Secrets = None,
) -> List[AWSResponse]:
    """
    Attaches a previously detached EBS volume to its associated EC2 instance.

    If neither 'instance_ids' or 'filters' are provided, all detached volumes
    will be reattached to their respective instances

    Parameters:
        One of:
            instance_ids: list: instance ids
            filters: list: key/value pairs to pull ec2 instances
    """
    client = aws_client("ec2", configuration, secrets)

    if not instance_ids and not filters:
        instances = []
    elif not instance_ids and filters:
        filters = deepcopy(filters) or []
        instances = list_instances(client, filters=filters)
    else:
        instances = list_instances(client, instance_ids=instance_ids)

    volumes = get_detached_volumes(client)
    results = []
    for volume in volumes:
        for t in volume["Tags"]:
            if t["Key"] != "ChaosToolkitDetached":
                continue
            attach_data = t["Value"].split(";")
            device_name = attach_data[0].split("=")[-1]
            instance_id = attach_data[1].split("=")[-1]

            if not instances or instance_id in [e["InstanceId"] for e in instances]:
                results.append(
                    attach_instance_volume(
                        client, instance_id, volume["VolumeId"], device_name
                    )
                )
    return results

###############################################################################
# Private functions
###############################################################################
def list_instances_by_type(
    filters: List[Dict[str, Any]], client: boto3.client
) -> Dict[str, Any]:
    """
    Return all instance ids matching the given filters by type
    (InstanceLifecycle) ie spot, on demand, etc.
    """
    logger.debug(f"EC2 instances query: {str(filters)}")
    res = client.describe_instances(Filters=filters)
    logger.debug(f"Instances matching the filter query: {str(res)}")

    return get_instance_type_from_response(res)

def list_instances(
    client: boto3.client,
    filters: List[Dict[str, Any]] = None,
    instance_ids: List[str] = None,
) -> List[Dict[str, Any]]:
    """
    Return all instance ids matching either the filters or provided list of ids

    Does not group instances by type
    """
    if filters:
        params = dict(Filters=filters)
    else:
        params = dict(InstanceIds=instance_ids)

    results = []
    response = client.describe_instances(**params)["Reservations"]
    for r in response:
        for e in r["Instances"]:
            results.append(e)
    return results

def list_instance_volumes(
    client: boto3.client,
    instance_ids: List[str] = None,
    filters: List[Dict[str, Any]] = None,
) -> List[AWSResponse]:
    """
    Return all (non root) instance volumes for instances matching either
    the provided filters or instance ids (do not group by type)
    """
    if filters:
        params = dict(Filters=filters)
    else:
        params = dict(InstanceIds=instance_ids)

    response = client.describe_instances(**params)["Reservations"]

    if not response:
        raise FailedActivity("no instances found matching: %s" % str(params))

    results = {}
    for r in response:
        for e in r["Instances"]:
            instance_id = e["InstanceId"]
            bdm = e.get("BlockDeviceMappings", [])
            for b in bdm:
                if b["DeviceName"] in ("/dev/sda1", "/dev/xvda"):
                    continue
                results.setdefault(instance_id, []).append(
                    {b["DeviceName"]: b["Ebs"]["VolumeId"]}
                )

    volumes = []
    for r in results:
        # select 1 volume at random
        volume = random.sample(results[r], 1)[0]
        for k, v in volume.items():
            volumes.append({"InstanceId": r, "DeviceName": k, "VolumeId": v})
    return volumes

def pick_random_instance(
    filters: List[Dict[str, Any]], client: boto3.client
) -> Union[str, dict, None]:
    """
    Select an instance at random based on the returned list of instances
    matching the given filter.
    """
    instances_type = list_instances_by_type(filters, client)
    if not instances_type:
        return

    random_id = random.choice(
        [item for sublist in instances_type.values() for item in sublist]
    )

    for k, v in instances_type.items():
        if random_id in v:
            return {k: [random_id]}

def get_instance_type_from_response(response: Dict) -> Dict:
    """
    Transform list of instance IDs to a dict with IDs by instance type
    """
    instances_type = defaultdict(List)
    # reservations are instances that were started together

    for reservation in response["Reservations"]:
        for inst in reservation["Instances"]:
            # when this field is missing, we assume "normal"
            # which means On-Demand or Reserved
            # this seems what the last line of the docs imply at
            # https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-purchasing-options.html
            lifecycle = inst.get("InstanceLifecycle", "normal")

            if lifecycle not in instances_type.keys():
                # adding empty list (value) for new instance type (key)
                instances_type[lifecycle] = []

            instances_type[lifecycle].append(inst["InstanceId"])

    return instances_type

def get_spot_request_ids_from_response(response: Dict) -> List[str]:
    """
    Return list of all spot request ids from AWS response object
    (DescribeInstances)
    """
    spot_request_ids = []

    for reservation in response["Reservations"]:
        for inst in reservation["Instances"]:
            # when this field is missing, we assume "normal"
            # which means On-Demand or Reserved
            lifecycle = inst.get("InstanceLifecycle", "normal")

            if lifecycle == "spot":
                spot_request_ids.append(inst["SpotInstanceRequestId"])

    return spot_request_ids

def get_instance_type_by_id(instance_ids: List[str], client: boto3.client) -> Dict:
    """
    Return dict object with instance ids grouped by instance types
    """
    res = client.describe_instances(InstanceIds=instance_ids)

    return get_instance_type_from_response(res)

def stop_instances_any_type(
    instance_types: dict = None, force: bool = False, client: boto3.client = None
) -> List[AWSResponse]:
    """
    Stop instances regardless of the instance type (on demand, spot)
    """

    response = []
    if "normal" in instance_types:
        logger.debug("Stopping instances: {}".format(instance_types["normal"]))

        response.append(
            client.stop_instances(InstanceIds=instance_types["normal"], Force=force)
        )

    if "spot" in instance_types:
        # TODO: proper support for spot fleets
        # https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-fleet.html

        # To properly stop spot instances have to cancel spot requests first
        spot_request_ids = get_spot_request_ids_from_response(
            client.describe_instances(InstanceIds=instance_types["spot"])
        )

        logger.debug(f"Canceling spot requests: {spot_request_ids}")
        client.cancel_spot_instance_requests(SpotInstanceRequestIds=spot_request_ids)
        logger.debug("Terminating spot instances: {}".format(instance_types["spot"]))

        response.append(client.terminate_instances(InstanceIds=instance_types["spot"]))

    if "scheduled" in instance_types:
        # TODO: add support for scheduled instances
        # https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-scheduled-instances.html
        raise FailedActivity("Scheduled instances support is not implemented")
    return response

def terminate_instances_any_type(
    instance_types: dict = None, client: boto3.client = None
) -> List[AWSResponse]:
    """
    Terminates instance(s) regardless of type
    """
    response = []

    for k, v in instance_types.items():
        logger.debug(f"Terminating {k} instance(s): {instance_types[k]}")
        if k == "spot":
            instances = get_spot_request_ids_from_response(
                client.describe_instances(InstanceIds=v)
            )
            # Cancel spot request prior to termination
            client.cancel_spot_instance_requests(SpotInstanceRequestIds=instances)
            response.append(client.terminate_instances(InstanceIds=v))
            continue
        response.append(client.terminate_instances(InstanceIds=v))
    return response

def start_instances_any_type(
    instance_types: dict, client: boto3.client
) -> List[AWSResponse]:
    """
    Starts one or more instances regardless of type
    """
    results = []
    for k, v in instance_types.items():
        logger.debug(f"Starting {k} instance(s): {v}")
        response = client.start_instances(InstanceIds=v)
        results.extend(response.get("StartingInstances", []))
    return results

def restart_instances_any_type(instance_types: dict, client: boto3.client):
    """
    Restarts one or more instances regardless of type
    """
    results = []
    for k, v in instance_types.items():
        logger.debug(f"Restarting {k} instance(s): {v}")
        client.reboot_instances(InstanceIds=v)
    return results

def detach_instance_volume(
    client: boto3.client, force: bool, volume: Dict[str, str]
) -> AWSResponse:
    """
    Detach volume from an instance
    """
    try:
        response = client.detach_volume(
            Device=volume["DeviceName"],
            InstanceId=volume["InstanceId"],
            VolumeId=volume["VolumeId"],
            Force=force,
        )

        # tag volume with instance information (to reattach on rollback)
        client.create_tags(
            Resources=[volume["VolumeId"]],
            Tags=[
                {
                    "Key": "ChaosToolkitDetached",
                    "Value": "DeviceName=%s;InstanceId=%s"
                    % (volume["DeviceName"], volume["InstanceId"]),
                }
            ],
        )
        return response
    except ClientError as e:
        raise FailedActivity(
            "unable to detach volume %s from %s: %s"
            % (volume["VolumeId"], volume["InstanceId"], e.response["Error"]["Message"])
        )

def get_detached_volumes(client: boto3.client):
    results = []
    paginator = client.get_paginator("describe_volumes")
    for p in paginator.paginate(
        Filters=[{"Name": "tag-key", "Values": ["ChaosToolkitDetached"]}]
    ):
        for v in p["Volumes"]:
            results.append(v)
    return results

def attach_instance_volume(
    client: boto3.client, instance_id: str, volume_id: str, mount_point: str
) -> AWSResponse:
    try:
        response = client.attach_volume(
            Device=mount_point, InstanceId=instance_id, VolumeId=volume_id
        )
        logger.debug(f"Attached volume {volume_id} to instance {instance_id}")
    except ClientError as e:
        raise FailedActivity(
            "Unable to attach volume %s to instance %s: %s"
            % (volume_id, instance_id, e.response["Error"]["Message"])
        )
    return response

def authorize_security_group_ingress(
    requested_security_group_id: str,
    ip_protocol: str,
    from_port: int,
    to_port: int,
    ingress_security_group_id: str = None,
    cidr_ip: str = None,
    configuration: Configuration = None,
    secrets: Secrets = None,
) -> AWSResponse:
    """
    Add one ingress rule to a security group
    https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Client.authorize_security_group_ingress

    - requested_security_group_id: the id for the security group to update
    - ip_protocol: ip protocol name (tcp, udp, icmp, icmpv6) or -1 to specify all
    - from_port: start of port range
    - to_port: end of port range
    - ingress_security_group_id: id of the securiy group to allow access to. You can either specify this or cidr_ip.
    - cidr_ip: the IPv6 CIDR range.
    You can either specify this or ingress_security_group_id
    """  # noqa: E501
    client = aws_client("ec2", configuration, secrets)
    request_kwargs = create_ingress_kwargs(
        requested_security_group_id,
        ip_protocol,
        from_port,
        to_port,
        ingress_security_group_id,
        cidr_ip,
    )
    try:
        response = client.authorize_security_group_ingress(**request_kwargs)
        return response
    except ClientError as e:
        raise ActivityFailed(
            "Failed to add ingress rule: {}".format(e.response["Error"]["Message"])
        )

def revoke_security_group_ingress(
    requested_security_group_id: str,
    ip_protocol: str,
    from_port: int,
    to_port: int,
    ingress_security_group_id: str = None,
    cidr_ip: str = None,
    configuration: Configuration = None,
    secrets: Secrets = None,
) -> AWSResponse:
    """
    Remove one ingress rule from a security group
    https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Client.revoke_security_group_ingress

    - requested_security_group_id: the id for the security group to update
    - ip_protocol: ip protocol name (tcp, udp, icmp, icmpv6) or -1 to specify all
    - from_port: start of port range
    - to_port: end of port range
    - ingress_security_group_id: id of the securiy group to allow access to. You can either specify this or cidr_ip.
    - cidr_ip: the IPv6 CIDR range. You can either specify this or ingress_security_group_id
    """  # noqa: E501
    client = aws_client("ec2", configuration, secrets)
    request_kwargs = create_ingress_kwargs(
        requested_security_group_id,
        ip_protocol,
        from_port,
        to_port,
        ingress_security_group_id,
        cidr_ip,
    )
    try:
        response = client.revoke_security_group_ingress(**request_kwargs)
        return response
    except ClientError as e:
        raise ActivityFailed(
            "Failed to remove ingress rule: {}".format(e.response["Error"]["Message"])
        )

def create_ingress_kwargs(
    requested_security_group_id: str,
    ip_protocol: str,
    from_port: int,
    to_port: int,
    ingress_security_group_id: str = None,
    cidr_ip: str = None,
) -> Dict[str, any]:
    request_kwargs = {
        "GroupId": requested_security_group_id,
        "IpPermissions": [
            {
                "IpProtocol": ip_protocol,
                "IpRanges": [
                    {
                        # conditionally assign the following
                        # 'CidrIp': cidr_ip
                    }
                ],
                "FromPort": from_port,
                "ToPort": to_port,
                "UserIdGroupPairs": [
                    {
                        # conditionally assign the following
                        # 'GroupId': ingress_security_group_id
                    }
                ],
            }
        ],
    }
    req = request_kwargs["IpPermissions"][0]
    if cidr_ip is not None:
        req["IpRanges"][0]["CidrIp"] = cidr_ip
    if ingress_security_group_id is not None:
        req["UserIdGroupPairs"][0]["GroupId"] = ingress_security_group_id
    return request_kwargs


# import serial

# with serial.Serial('/dev/ttyUSB0', 115200, timeout=1) as ser:
#     # s = ser.read(10)
#     line = ser.readline()
# print(line)

import time
import serial

print('Running LW20 sample.')

# Make a connection to the com port.
serialPortName = '/dev/ttyUSB0'
serialPortBaudRate = 115200
port = serial.Serial(serialPortName, serialPortBaudRate, timeout=0.1)

# Enable serial mode by sending some characters over the serial port.
port.write('www\r\n')
# Read and ignore any unintended responses
port.readline()

# Get the product information
port.write('?\r\n')
productInfo = port.readline()
print('Product information: ' + productInfo)

while True:
	# Get distance reading (First return, default filtering)
	port.write('LD\r\n')
	distanceStr = port.readline()
	# Convert the distance string response into a number
	distanceCM = float(distanceStr)

	# Do what you want with the distance information here
	print('standoff: {0:.2f} m'.format(distanceCM))

	# Wait for 50ms before the next reading is taken
	time.sleep(0.05)


import asyncio
from dataclasses import dataclass
import json
import os

import cv2
import mediapipe as mp
from aiohttp import web
from aiohttp_middlewares import cors_middleware

from aiortc import RTCPeerConnection, RTCSessionDescription

import sys

mp_drawing = mp.solutions.drawing_utils
mp_drawing_styles = mp.solutions.drawing_styles
mp_hands = mp.solutions.hands

user_path = os.getcwd()
path_required = os.path.join(user_path.split('/server')[0], "Gesture_Recognizer_Model")
#print(path_required)
sys.path.insert(0, path_required)

from detector import Detector

pcs = set()
dataChannel = None

detector = Detector()

async def consume_video(track):
    while True:
        frame = await track.recv()
        img = frame.to_ndarray(format="bgr24")

        detector.add_frame(img)
        detector.predict_on_frames()

        with mp_hands.Hands(
            min_detection_confidence=0.5,
            min_tracking_confidence=0.5) as hands:

                image = cv2.cvtColor(cv2.flip(img, 1), cv2.COLOR_BGR2RGB)

                image.flags.writeable = False
                results = hands.process(image)

                image.flags.writeable = True
                image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
                if results.multi_hand_landmarks:
                    for hand_landmarks in results.multi_hand_landmarks:
                        mp_drawing.draw_landmarks(
                            image,
                            hand_landmarks,
                            mp_hands.HAND_CONNECTIONS,
                            mp_drawing_styles.get_default_hand_landmarks_style(),
                            mp_drawing_styles.get_default_hand_connections_style())

        cv2.imshow('MediaPipe Hands', image)

        #cv2.imshow("window", img)
        cv2.waitKey(1)
        #dataChannel.send(json.dumps({"command": "click"}))

async def offer(request):
    params = await request.json()
    offer = RTCSessionDescription(sdp=params["sdp"], type=params["type"])

    pc = RTCPeerConnection()
    pcs.add(pc)

    @pc.on("datachannel")
    def on_datachannel(channel):
        global dataChannel
        dataChannel = channel

        @channel.on("message")
        def on_message(message):
            if isinstance(message, str) and message.startswith("ping"):
                channel.send("pong")

    @pc.on("connectionstatechange")
    async def on_connectionstatechange():
        if pc.connectionState == "failed":
            await pc.close()
            pcs.discard(pc)

    @pc.on("track")
    def on_track(track):
        if track.kind == "video":
            asyncio.ensure_future(consume_video(track))

        @track.on("ended")
        async def on_ended():
            print("stream ended")

    # handle offer
    await pc.setRemoteDescription(offer)

    # send answer
    answer = await pc.createAnswer()
    await pc.setLocalDescription(answer)

    return web.Response(
        content_type="application/json",
        text=json.dumps(
            {"sdp": pc.localDescription.sdp, "type": pc.localDescription.type}
        ),
    )

async def on_shutdown(app):
    # close peer connections
    coros = [pc.close() for pc in pcs]
    await asyncio.gather(*coros)
    pcs.clear()

if __name__ == "__main__":
    app = web.Application(middlewares=[cors_middleware(allow_all=True)])
    app.on_shutdown.append(on_shutdown)
    app.router.add_post("/offer", offer)
    web.run_app(
        app, access_log=None, host="0.0.0.0", port=8080, ssl_context=None
    )


#!/usr/bin/env python3

import numpy as np
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt

def fit_line(x, y):
    reg = LinearRegression()
    X = x.reshape((-1, 1))
    reg.fit(X, y)
    return reg.coef_[0], reg.intercept_

def main():
    x = np.array([1, 2, 3])
    y = np.array([1, 2.5, 3]) + 1
    slope, intercept = fit_line(x, y)
    print("Slope:", slope)
    print("Intercept:", intercept)
    plt.scatter(x, y)
    x1 = np.linspace(min(x)-1, max(x)+1, 10)
    plt.plot(x1, x1*slope + intercept, 'red')
    plt.show()

if __name__ == "__main__":
    main()