class Upgrade():
    def __init__(self, id, name, affects_speed, adds_outputs, one_per_profile = False, one_per_minion = False, speed_mult = None, outputs = None, special_case = None):
        self.__id = id
        self.__name = name
        self.__affects_speed = affects_speed
        self.__adds_outputs = adds_outputs
        self.__special_case = special_case

        self.__one_per_profile = one_per_profile
        self.__one_per_minion = one_per_minion
        self.__speed_mult = speed_mult
        self.__outputs = outputs
        self.__special_case = special_case

    def __repr__(self):
        toPrint = self.__name
        toPrint += f"\nID: {self.__id}\n"
        toPrint += f"Affects speed: {self.__affects_speed}\n"
        if self.__affects_speed:
            toPrint += f"Speed multiplier: {self.__speed_mult}\n"

        toPrint += f"Adds outputs: {self.__adds_outputs}\n"
        if self.__adds_outputs:
            toPrint += f"Outputs: {self.__outputs}\n"

        toPrint += f"One per profile: {self.__one_per_profile}\n"
        toPrint += f"One per minion: {self.__one_per_minion}\n"
        return toPrint

    def get_id(self):
        return self.__id

    def get_name(self):
        return self.__name

    def get_speed_mult(self, minion):
        if special_case == "better soulflow":
            if minion.get_name() == "voidling":
                return 1 + 0.03 * minion.get_tier()
        return self.__speed_mult

    def get_outputs(self):
        return outputs

    def calc_outputs(self, time, time_between_actions, items_per_actions):
        if special_case == "dia spread":
            return 0.1 * items_per_actions * (time/time_between_actions)

        elif special_case == "potato spread":
            #NOT CONFIRMED
            return 0.1 * items_per_actions * (time/time_between_actions)

        elif special_case == "krapmus helm":
            return -1

        elif "soulflow" in special_case:
            return time/180

    def one_per_profile(self):
        return self.__one_per_profile

    def one_per_minion(self):
        return self.__one_per_minion

    def affects_speed(self):
        return self.__affect_speed

    def adds_outputs(self):
        return self.__adds_outputs

class Upgrades():
    def __init__(self):
        self.__max_id = 0
        self.__upgrades_list = []

    def add_upgrade(self,  name, affects_speed, adds_outputs, one_per_profile = False, one_per_minion = False, speed_mult = None, outputs = None, special_case = None):
        self.__max_id += 1
        self.__upgrades_list.append(Upgrade(self.__max_id,  name, affects_speed, adds_outputs, one_per_profile, one_per_minion, speed_mult, outputs, special_case))

    def search_by_name(self, name):
        for upgrade in self.__upgrades_list:
            if upgrade.get_name() == name:
                return upgrade

    def search_by_id(self, id):
        for upgrade in self.__upgrades_list:
            if upgrade.get_id() == id:
                return upgrade

    def print_short_info(self):
        for upgrade in self.__upgrades_list:
            print("{:2d}".format(upgrade.get_id()) + " " + upgrade.get_name())

upgrades = Upgrades()

upgrades.add_upgrade("auto smelter or dwarven super compactor", False, False, one_per_minion = True)
upgrades.add_upgrade("diamond spreading", False, True, outputs = "diamond", special_case = "dia spread")
upgrades.add_upgrade("potato spreading", False, True, outputs = "potato", special_case = "potato spread")
upgrades.add_upgrade("krampus helmet", False, True, outputs = "red gift", special_case = "krampus helm")
upgrades.add_upgrade("minion expander", True, False, speed_mult = 1.05)
upgrades.add_upgrade("flycatcher", True, False, speed_mult = 1.2)
upgrades.add_upgrade("enchanted egg", False, False)
upgrades.add_upgrade("flint shovel", False, False)
upgrades.add_upgrade("lesser soulflow engine", True, True, speed_mult = 0.5, outputs = "raw soulfow", special_case = "lesser slouflow")
upgrades.add_upgrade("soulflow engine", True, True, speed_mult = 0.5, outputs = "raw soulfow", special_case = "better slouflow")

if __name__ == "__main__":
    #testing
    print(upgrades.search_by_name("flycatcher"))
    upgrades.print_short_info()


#!/usr/bin/env python
# encoding: utf-8
import os
import sys
import math
import time
import torch
import random
import argparse
import numpy as np
from sep import SEP
from data import load_tree
from functools import reduce
import torch.nn.functional as F
from transformers.optimization import get_cosine_schedule_with_warmup

class Trainer(object):
    def __init__(self, args):
        super(Trainer, self).__init__()
        # Random Seed
        random.seed(args.seed)
        np.random.seed(args.seed)
        torch.manual_seed(args.seed)
        if torch.cuda.is_available():
            torch.cuda.manual_seed(args.seed)
            torch.cuda.manual_seed_all(args.seed)
        torch.backends.cudnn.deterministic = True
        torch.backends.cudnn.benchmark = False
        self.args = args
        self.exp_name = self.set_experiment_name()

        if torch.cuda.is_available():
            self.args.device = 'cuda:{}'.format(args.gpu)
        else:
            self.args.device = 'cpu'
        self.load_data()

    def init_fold(self):
        self.patience = 0
        self.best_loss_epoch = 0
        self.best_acc_epoch = 0
        self.best_loss = 1e9
        self.best_loss_acc = -1e9
        self.best_acc = -1e9
        self.best_acc_loss = 1e9
        self.args.num_features = self.dataset[0]['node_features'].size(1)
        self.args.num_classes = len(set([t['label'] for t in self.dataset]))

    def load_data(self):
        self.dataset = load_tree(self.args.dataset, self.args.tree_depth)

    def load_tvt(self, fold_number, val_fold_number):
        data = self.args.dataset
        train_idxes = torch.as_tensor(np.loadtxt('./datasets/%s/10fold_idx/train_idx-%d.txt' % (data, fold_number), dtype=np.int32), dtype=torch.long)
        val_idxes = torch.as_tensor(np.loadtxt('./datasets/%s/10fold_idx/test_idx-%d.txt' % (data, val_fold_number), dtype=np.int32), dtype=torch.long)
        test_idxes = torch.as_tensor(np.loadtxt('./datasets/%s/10fold_idx/test_idx-%d.txt' % (data, fold_number), dtype=np.int32), dtype=torch.long)
        all_idxes = reduce(np.union1d, (train_idxes, val_idxes, test_idxes))
        assert len(all_idxes) == len(self.dataset)

        # bug: random.shuffle(tensor), this will cause replicated data
        train_idxes = np.setdiff1d(train_idxes, val_idxes)
        random.shuffle(train_idxes)
        train_set = [self.dataset[i] for i in train_idxes]
        val_set = [self.dataset[i] for i in val_idxes]
        test_set = [self.dataset[i] for i in test_idxes]
        return train_set, val_set, test_set

    def load_model(self):
        model = SEP(self.args).to(self.args.device)
        return model

    def organize_val_log(self, train_loss, val_loss, val_acc, fold_number, epoch):
        if val_loss < self.best_loss:
            torch.save(
                self.model.state_dict(),
                './checkpoints/{}/experiment-{}_fold-{}_seed-{}_best-model.pth'.format(self.log_folder_name, self.exp_name, fold_number, self.args.seed)
            )
            self.best_loss_acc = val_acc
            self.best_loss = val_loss
            self.best_loss_epoch = epoch
            self.patience = 0
        else:
            self.patience += 1

        if val_acc > self.best_acc:
            self.best_acc = val_acc
            self.best_acc_loss = val_loss
            self.best_acc_epoch = epoch

    def organize_test_log(self, test_loss, test_acc, t_start, t_end, fold_number):
        self.overall_results['durations'].append(t_end - t_start)
        self.overall_results['val_loss'].append(self.best_loss)
        self.overall_results['val_acc'].append(self.best_acc)
        self.overall_results['test_loss'].append(test_loss)
        self.overall_results['test_acc'].append(test_acc)

    def eval(self, loader):
        self.model.eval()
        correct = 0.
        loss = 0.
        for i in range(0, len(loader), self.args.batch_size):
            batch = loader[i:i+self.args.batch_size]
            with torch.no_grad():
                out = self.model(batch)
            pred = out.max(dim=1)[1]
            y = torch.LongTensor([d['label'] for d in batch]).to(self.args.device)
            correct += pred.eq(y).sum().item()
            loss += F.nll_loss(out, y, reduction='sum').item()
        return correct / len(loader), loss / (i+1)

    def train(self):
        self.overall_results = {
            'val_loss': [],
            'val_acc': [],
            'test_loss': [],
            'test_acc': [],
            'durations': []
        }

        train_fold_iter = range(1, 11)
        val_fold_iter = list(range(1, 11))

        s_start = time.time()
        for fold_number in train_fold_iter:
            val_fold_number = val_fold_iter[fold_number-2]
            train_loader, val_loader, test_loader = self.load_tvt(fold_number, val_fold_number)

            self.init_fold()
            # Load Model & Optimizer
            self.model = self.load_model()
            self.optimizer = torch.optim.Adam(self.model.parameters(), lr=self.args.lr, weight_decay=self.args.l2rate)

            iter_per_epoch = 50 if args.dataset in i50_dataset \
                                else math.ceil(len(train_loader) / self.args.batch_size)
            if self.args.lr_schedule:
                self.scheduler = get_cosine_schedule_with_warmup(self.optimizer, self.args.patience * iter_per_epoch, self.args.num_epochs * iter_per_epoch)

            t_start = time.time()
            # K-Fold Training, epoch default 500
            for epoch in range(self.args.num_epochs):
                self.model.train()
                total_loss = 0
                if args.dataset in i50_dataset:
                    e_iter = range(50)
                else:
                    e_iter = range(0, len(train_loader), self.args.batch_size)
                for _ in e_iter:
                    if args.dataset in i50_dataset:
                        indexes = list(range(len(train_loader)))
                        random.shuffle(indexes)
                        batch = [train_loader[i] for i in indexes[:self.args.batch_size]]
                    else:
                        batch = train_loader[_:_+self.args.batch_size]
                    self.optimizer.zero_grad()
                    out = self.model(batch)
                    y = torch.LongTensor([d['label'] for d in batch]).to(self.args.device)
                    loss = F.nll_loss(out, y)
                    loss.backward()
                    torch.nn.utils.clip_grad_norm_(self.model.parameters(), self.args.grad_norm)
                    total_loss += loss.item() * len(batch)
                    self.optimizer.step()

                    if self.args.lr_schedule:
                        self.scheduler.step()

                total_loss = total_loss / len(train_loader)

                # Validation
                val_acc, val_loss = self.eval(val_loader)
                self.organize_val_log(total_loss, val_loss, val_acc, fold_number, epoch)
                if self.patience > self.args.patience:
                    break

            t_end = time.time()
            checkpoint = torch.load('./checkpoints/{}/experiment-{}_fold-{}_seed-{}_best-model.pth'.format(self.log_folder_name, self.exp_name, fold_number, self.args.seed))
            self.model.load_state_dict(checkpoint)
            test_acc, test_loss = self.eval(test_loader)
            self.organize_test_log(test_loss, test_acc, t_start, t_end, fold_number)

        s_end = time.time()
        val_acc_mean = np.array(self.overall_results['val_acc']).mean()
        val_acc_std = np.array(self.overall_results['val_acc']).std()
        test_acc_mean = np.array(self.overall_results['test_acc']).mean()
        test_acc_std = np.array(self.overall_results['test_acc']).std()
        print("%.4f\t%.4f\t%.4f\t%.4f\t%.2f" % (test_acc_mean,
                                                test_acc_std,
                                                val_acc_mean,
                                                val_acc_std,
                                                (s_end-s_start)/60))
        sys.stdout.flush()

    def set_experiment_name(self):
        ts = time.strftime('%Y-%m-%d-%H:%M:%S', time.gmtime())
        self.log_folder_name = os.path.join(*[self.args.dataset, 'SEP'])
        if not(os.path.isdir('./checkpoints/{}'.format(self.log_folder_name))):
            os.makedirs(os.path.join('./checkpoints/{}'.format(self.log_folder_name)))
        exp_name = str()
        exp_name += "GNN={}_".format(self.args.conv)
        exp_name += "TD={}_".format(self.args.tree_depth)
        exp_name += "GP={}_".format(self.args.global_pooling)
        exp_name += "BS={}_".format(self.args.batch_size)
        exp_name += "HD={}_".format(self.args.hidden_dim)
        exp_name += "LR={}_".format(self.args.lr)
        exp_name += "WD={}_".format(self.args.l2rate)
        exp_name += "GN={}_".format(self.args.grad_norm)
        exp_name += "DO={}_".format(self.args.final_dropout)
        exp_name += "LS={}_".format(self.args.lr_schedule)
        exp_name += "TS={}".format(ts)
        return exp_name

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='SEP arguments')
    parser.add_argument('-d', '--dataset', type=str, default="IMDB-BINARY",
                        help='name of dataset')
    parser.add_argument('-c', '--conv', default='GCN', type=str,
                        choices=['GCN', 'GIN', 'GAT', 'Cheb', 'SAGE', 'GAT2', 'Transformer' ],
                        help='message-passing function type')
    parser.add_argument('--num-convs', default=3, type=int)
    parser.add_argument('--num-head', default=1, type=int)
    parser.add_argument('-k', '--tree_depth', type=int, default=3,
                        help='the depth of coding tree (default: 3)')
    parser.add_argument('-b', '--batch_size', type=int, default=32,
                        help='input batch size for training (default: 32)')
    parser.add_argument('-e', '--num_epochs', type=int, default=500,
                        help='number of epochs to train (default: 500)')
    parser.add_argument('-lr', '--lr', type=float, default=0.0005,
                        help='learning rate (default: 0.0005)')
    parser.add_argument('-s', '--seed', type=int, default=0,
                        help='random seed for splitting the dataset into 10 (default: 0)')
    parser.add_argument('-hd', '--hidden_dim', type=int, default=64,
                        help='number of hidden units (default: 64)')
    parser.add_argument('-fd', '--final_dropout', type=float, default=0.5,
                        help='final layer dropout (default: 0.5)')
    parser.add_argument('-l2', '--l2rate', type=float, default=0.0001,
                        help='L2 penalty lambda')
    parser.add_argument('--gpu', type=int, default=0,
                        help='which gpu to use if any (default: 0)')
    parser.add_argument("--grad-norm", type=float, default=1.0)
    parser.add_argument('--patience', type=int, default=50, help='patience for earlystopping')
    parser.add_argument("--lr-schedule", action='store_true')
    parser.add_argument("--link-input", action='store_true')
    parser.add_argument('-gp', '--global-pooling', type=str, default="sum", choices=["sum", "average"],
                        help='Pooling for over nodes: sum or average')
    args = parser.parse_args()

    linkIn_dataset  = ['IMDB-BINARY', 'IMDB-MULTI', 'COLLAB', 'DD']
    i50_dataset = ['IMDB-BINARY', 'IMDB-MULTI', 'MUTAG', 'PROTEINS', 'PTC', 'DD']
    if args.dataset in linkIn_dataset:
        args.link_input = True

    line = '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s' % (
            args.dataset,
            args.conv,
            args.tree_depth,
            args.global_pooling,
            args.hidden_dim,
            args.batch_size,
            args.final_dropout,
            args.num_head,
            args.lr_schedule)
    print(line, flush=True)
    trainer = Trainer(args)
    trainer.train()


# -*- coding: utf-8 -*-
from django.db import transaction
from django.db.models import Count, Avg, Q
from django.shortcuts import get_object_or_404
from rest_framework import viewsets, status, permissions
from rest_framework.response import Response

from biz import redis_client
from biz.constants import COURSE_PAYMENT_STATUS_UNPAID
from biz.models import Course, BoxerIdentification, BoxingClub, CourseOrder, OrderComment
from biz.utils import Round
from boxing_app.permissions import IsBoxerPermission
from boxing_app.serializers import CourseAllowNullDataSerializer, CourseFullDataSerializer

class BoxerMyCourseViewSet(viewsets.ModelViewSet):
    serializer_class = CourseAllowNullDataSerializer
    permission_classes = (permissions.IsAuthenticated, IsBoxerPermission)

    def get_queryset(self):
        return Course.objects.filter(boxer__user=self.request.user)\
            .annotate(order_count=Count('course_orders',
                                        filter=Q(course_orders__status__gt=COURSE_PAYMENT_STATUS_UNPAID)),
                      score=Round(Avg('course_orders__comment__score')))\
            .select_related('club', 'boxer')

    @transaction.atomic
    def update(self, request, *args, **kwargs):
        boxer = BoxerIdentification.objects.get(user=self.request.user)
        validity = request.data.get('validity')
        club_id = request.data.get('club')
        club = get_object_or_404(BoxingClub, id=club_id)
        for course_data in request.data.get('course_list'):
            is_open = course_data.get('is_open')
            course = Course.objects.get(id=course_data.get('course_id'))
            course_data.pop('course_id')
            course_data['validity'] = validity
            course_data['club'] = club_id
            if is_open:
                serializer = CourseFullDataSerializer(instance=course, data=course_data)
            else:
                serializer = CourseAllowNullDataSerializer(instance=course, data=course_data)
            serializer.is_valid(raise_exception=True)
            serializer.save(boxer=boxer)
        boxer.is_accept_order = False
        boxer.save()
        redis_client.record_object_location(boxer, club.longitude, club.latitude)
        return Response(status=status.HTTP_204_NO_CONTENT)

    def list(self, request, *args, **kwargs):
        response = super().list(request, *args, **kwargs)
        boxer = BoxerIdentification.objects.get(user=self.request.user)
        if boxer.is_locked:
            return Response({'message': '你暂时不能接单。'}, status=status.HTTP_400_BAD_REQUEST)
        self.get_boxer_base_info(dict=response.data, boxer=boxer)
        course = self.get_queryset().filter(is_open=True).select_related('club').last()
        if course:
            self.get_course_base_info(dict=response.data, course=course)
        return response

    @staticmethod
    def get_course_base_info(dict, course):
        if course:
            dict['validity'] = course.validity
            dict['boxer_id'] = course.boxer_id
            dict['club_id'] = course.club.id
            dict['club_name'] = course.club.name
            dict['club_city'] = course.club.city
            dict['club_address'] = course.club.address
            dict['club_longitude'] = course.club.longitude
            dict['club_latitude'] = course.club.latitude
        return dict

    @staticmethod
    def get_boxer_base_info(dict, boxer):
        if boxer:
            dict['order_count'] = CourseOrder.objects.filter(boxer=boxer, status__gt=COURSE_PAYMENT_STATUS_UNPAID).count()
            dict['allowed_course'] = boxer.allowed_course
            comment_count_and_avg_score = OrderComment.objects.filter(order__boxer=boxer) \
                .aggregate(comments_count=Count('id'), avg_score=Round(Avg('score')))
            dict.update(comment_count_and_avg_score)
        return dict

class GetBoxerCourseByAnyOneViewSet(viewsets.ReadOnlyModelViewSet):
    serializer_class = CourseAllowNullDataSerializer
    permission_classes = (permissions.AllowAny,)

    def get_queryset(self):
        return Course.objects.filter(boxer__id=self.kwargs['boxer_id'], is_open=True)\
            .annotate(order_count=Count('course_orders',
                                        filter=Q(course_orders__status__gt=COURSE_PAYMENT_STATUS_UNPAID)),
                      score=Round(Avg('course_orders__comment__score')))\
            .select_related('club', 'boxer')

    def opened_courses_list(self, request, *args, **kwargs):
        response = super().list(request, *args, **kwargs)
        boxer = BoxerIdentification.objects.get(id=kwargs['boxer_id'])
        course = self.get_queryset().select_related('club').last()
        if course:
            BoxerMyCourseViewSet.get_course_base_info(dict=response.data, course=course)
        BoxerMyCourseViewSet.get_boxer_base_info(dict=response.data, boxer=boxer)
        return response


import requests
import json

API_ACCESS_KEY='YOUR_API_ACCESS_KEY'

registrationIds=['DEVICE_REGISTRATION_ID']

url = 'https://android.googleapis.com/gcm/send'

msg={'message':'here is a message. message',
	'title':'This is a title. title',
	'subtitle':'This is a subtitle. subtitle',
	'tickerText':'Ticker text here...Ticker text here...Ticker text here',
	'vibrate'	: 1,
	'sound'		: 1,
	'largeIcon'	: 'large_icon',
	'smallIcon'	: 'small_icon'
}
fields = {
	'registration_ids': registrationIds,
	'data': msg
}

# Adding empty header as parameters are being sent in payload
headers = {'Authorization':'key='+API_ACCESS_KEY,
	'Content-Type': 'application/json'}
r = requests.post(url, data=json.dumps(fields), headers=headers)
print(r.content)


import subprocess
import platform
import os
import shutil
import tempfile
from typing import Optional

def _dd_mebibyte_postfix() -> str:
    if platform.system() == "Darwin":
        return "m"

    return "M"

def file_resize_to_mib(path: str, mib: int) -> None:
    subprocess.check_call(["dd", "if=/dev/zero", f"of={path}",
                           f"bs=1{_dd_mebibyte_postfix()}", f"count={mib}"])

def _linux_image_partition(
    path: str, br_type: str, fs_type: str, align_mib: int, part_len_mib: int
) -> None:
    label = "gpt" if br_type == "GPT" else "msdos"
    subprocess.check_call(["parted", "-s", path, "mklabel", label])

    part_type = "primary" if br_type == "MBR" else "test-partition"

    fs_type = fs_type.lower()
    if fs_type == "fat12":
        fs_type = "fat16"  # parted doesn't support fat12 labels

    subprocess.check_call(["parted", "-s", path,
                           "mkpart", part_type,
                           fs_type, f"{align_mib}M",
                           f"{align_mib + part_len_mib}M"])

def _darwin_image_partition_gpt(
    path: str, _: str, align_mib: int, part_len_mib: int
) -> None:
    part_begin = (align_mib * 1024 * 1024) // 512
    part_end = part_begin + ((part_len_mib * 1024 * 1024) // 512)

    gdisk_fmt = "n\n"  # New partition
    gdisk_fmt += "1\n"  # At index 1
    gdisk_fmt += f"{part_begin}\n"  # Starts here
    gdisk_fmt += f"{part_end}\n"  # Ends here
    gdisk_fmt += "\n"  # With default GUID (some Apple thing)
    gdisk_fmt += "w\n"  # Write the new changes
    gdisk_fmt += "y\n"  # Yes, overwrite everything

    gdp = subprocess.Popen(["gdisk", path], stdin=subprocess.PIPE)

    assert gdp.stdin
    gdp.stdin.write(gdisk_fmt.encode("ascii"))
    gdp.stdin.close()

    gdp.wait(5)
    if gdp.returncode != 0:
        raise RuntimeError("gdisk exited with error")

# Darwin doesn't have 'parted', instead it ships with
# a weird version of 'fdisk'
def _darwin_image_partition_mbr(
    path: str, fs_type: str, align_mib: int, part_len_mib: int
) -> None:
    fs_type_to_id = {
        "FAT12": 0x01,
        "FAT16": 0x04,
        "FAT32": 0x0C
    }

    part_begin = (align_mib * 1024 * 1024) // 512
    part_len_mib = (part_len_mib * 1024 * 1024) // 512
    fs_id = "{:02X}".format(fs_type_to_id[fs_type])

    fdisk_fmt = f"{part_begin},{part_len_mib},{fs_id}\n"

    fdp = subprocess.Popen(["fdisk", "-yr", path], stdin=subprocess.PIPE)

    assert fdp.stdin
    fdp.stdin.write(fdisk_fmt.encode("ascii"))
    fdp.stdin.close()

    fdp.wait(5)
    if fdp.returncode != 0:
        raise RuntimeError("fdisk exited with error")

def _darwin_image_partition(
    path: str, br_type: str, fs_type: str, align_mib: int, part_len_mib: int
) -> None:
    if br_type == "MBR":
        _darwin_image_partition_mbr(path, fs_type, align_mib, part_len_mib)
    else:
        _darwin_image_partition_gpt(path, fs_type, align_mib, part_len_mib)

SYSTEM_TO_IMAGE_PARTITION = {
    "Linux": _linux_image_partition,
    "Darwin": _darwin_image_partition,
}

def image_partition(
    path: str, br_type: str, fs_type: str, align_mib: int, part_len_mib: int
) -> None:
    part_fn = SYSTEM_TO_IMAGE_PARTITION[platform.system()]
    part_fn(path, br_type, fs_type, align_mib, part_len_mib)

def fat_recursive_copy(raw_fs_path: str, file_path: str) -> None:
    subprocess.check_call([
        "mcopy", "-Q", "-i", raw_fs_path, "-s", file_path, "::"
    ])

def fat_fill(raw_fs_path: str, root_dir_path: str) -> None:
    for f in os.listdir(root_dir_path):
        full_path = os.path.abspath(os.path.join(root_dir_path, f))
        fat_recursive_copy(raw_fs_path, full_path)

def make_fat(raw_fs_path: str, _: int, force_fat32: bool) -> None:
    cr_args = ["mformat", "-i", raw_fs_path]
    if force_fat32:
        cr_args.append("-F")

    subprocess.check_call(cr_args)

def make_iso(
    image_path: str, root_path: str, uefi_root_path: Optional[str] = None,
    iso_br_path: Optional[str] = None
) -> None:
    # Make the disk itself
    xorriso_args = ["xorriso", "-as", "mkisofs"]

    if iso_br_path is not None:
        br_file = "boot_record"
        br_path = os.path.join(root_path, br_file)
        shutil.copy(iso_br_path, br_path)

        xorriso_args.extend([
            "-b", br_file, "-no-emul-boot", "-boot-load-size", "4",
            "-boot-info-table"
        ])

    if uefi_root_path is not None:
        # Make the EFI ESP partition
        fat_image = os.path.join(root_path, "efi_esp")
        file_resize_to_mib(fat_image, 1)
        make_fat(fat_image, 1, False)
        fat_fill(fat_image, uefi_root_path)

        xorriso_args.extend([
            "--efi-boot", "efi_esp", "-efi-boot-part", "--efi-boot-image"
        ])

    xorriso_args.extend([
        "--protective-msdos-label", root_path, "-o", image_path
    ])
    subprocess.check_call(xorriso_args)

def image_embed(image_path: str, mib_offset: int, fs_image_path: str) -> None:
    subprocess.check_call([
        "dd", f"if={fs_image_path}", f"seek={mib_offset}",
        f"bs=1{_dd_mebibyte_postfix()}", f"of={image_path}",
        "conv=notrunc"
    ])

def make_fs(
    image_path: str, fs_type: str, image_mib_offset: int,
    size: Optional[int], root_path: str,
    uefi_root_path: Optional[str] = None,
    iso_br_path: Optional[str] = None
) -> None:
    if fs_type == "ISO9660":
        return make_iso(image_path, root_path, uefi_root_path, iso_br_path)

    with tempfile.NamedTemporaryFile() as tf:
        assert size
        file_resize_to_mib(tf.name, size)

        if fs_type.startswith("FAT"):
            make_fat(tf.name, size, fs_type == "FAT32")
            fat_fill(tf.name, root_path)
            if uefi_root_path:
                fat_fill(tf.name, uefi_root_path)
        else:
            raise RuntimeError(f"Unknown filesystem type {fs_type}")

        image_embed(image_path, image_mib_offset, tf.name)


import pandas as pd
from pyspark.shell import spark

train_data_no_name = pd.read_csv("./datasets/train_FD001.txt", sep="\s+", header=None)
columns = ['engineNumber', 'cycleNumber', 'opSetting1',
           'opSetting2', 'opSetting3', 'sensor1', 'sensor2',
           'sensor3', 'sensor4', 'sensor5', 'sensor6',
           'sensor7', 'sensor8', 'sensor9', 'sensor10',
           'sensor11', 'sensor12', 'sensor13', 'sensor14',
           'sensor15', 'sensor16',
           'sensor17', 'sensor18', 'sensor19', 'sensor20',
           'sensor21']

df = spark.createDataFrame(train_data_no_name, columns)
print(df.corr('engineNumber', 'sensor1'))


import sys
import io

from context import game
import test_helpers

class TestOptions():
    def test_rules(self):
        out, err = test_helpers.capture_io(game.rules, test_helpers.dummy)
        assert ("This is a complex world but I am a simple guide." in out) == True
        assert err == ""

    def test_quit(self):
        out, err = test_helpers.capture_io(game.quit)
        assert out == "You may yet live to see another day."
        assert err == ""

    def test_play(self):
        sys.stdin = io.StringIO("quit\n")
        out, err = test_helpers.capture_io(game.play)
        assert ("You are standing in a near pitch-black alley which" in out) == True
        assert err == ""

    def test_idk(self):
        out, err = test_helpers.capture_io(game.idk, test_helpers.dummy)
        assert out == "I don't know what that means..."
        assert err == ""

    def test_noway(self):
        out, err = test_helpers.capture_io(game.noway, test_helpers.dummy)
        assert out == "There is nothing in that direction."
        assert err == ""


def sum(num1, num2):
    resultado=num1+num2
    return resultado

print ("hello world")
numero1=5
numero2=7
if numero1>numero2:
    print ("el numero 1 es mayor que el numero 2")
else:
    print ("el numero 2 es mayor que el numero 1")

print (sum(4,5))


#!/usr/bin/env python
"""
Integration test for the 'sdh_tactile_adapter' node.

"""

import rospy
import unittest
import rostest
import std_msgs.msg
import schunk_sdh.msg
import tactile_msgs.msg

PKG = 'slip_detection'

class TestTactileAdapter(unittest.TestCase):
    def setUp(self):
        """
        Sets up the test fixture before exercising it.

        """
        # params
        self.result = None
        self.wait_for_result = None

        # publishers
        self.event_out = rospy.Publisher(
            '~event_out', std_msgs.msg.String, latch=True
        )
        self.component_input = rospy.Publisher(
            '~component_input', schunk_sdh.msg.TactileSensor
        )

        # subscribers
        self.component_output = rospy.Subscriber(
            '~component_output', tactile_msgs.msg.TactileData, self.result_callback
        )

    def tearDown(self):
        """
        Deconstructs the test fixture after testing it.

        """
        self.event_out.unregister()
        self.component_input.unregister()
        self.component_output.unregister()

    def test_sdh_tactile_interface(self):
        """
        Verifies that the node correctly converts the tactile information
        from a SDH sensor to a hardware independent tactile message.

        """
        # arrays of the expected tactile message
        sensor_1 = tactile_msgs.msg.TactileArray()
        sensor_1.tactile_array = [1, 2, 3, 4, 5, 6]

        sensor_2 = tactile_msgs.msg.TactileArray()
        sensor_2.tactile_array = [7, 7, 7, 7, 7, 7]

        # complete the tactile message
        desired_result = tactile_msgs.msg.TactileData()
        desired_result.name = ['sensor_1', 'sensor_2']
        desired_result.tactile_array = [sensor_1, sensor_2]
        desired_result.size_x = [3, 2]
        desired_result.size_y = [2, 3]

        # matrices of the tactile sensors
        tactile_matrix_0 = schunk_sdh.msg.TactileMatrix()
        tactile_matrix_0.matrix_id = 0
        tactile_matrix_0.cells_x = 3
        tactile_matrix_0.cells_y = 2
        tactile_matrix_0.tactile_array = [1, 2, 3, 4, 5, 6]

        tactile_matrix_1 = schunk_sdh.msg.TactileMatrix()
        tactile_matrix_1.matrix_id = 1
        tactile_matrix_1.cells_x = 2
        tactile_matrix_1.cells_y = 3
        tactile_matrix_1.tactile_array = [7, 7, 7, 7, 7, 7]

        # complete the tactile sensors
        tactile_sensors = schunk_sdh.msg.TactileSensor()
        tactile_sensors.tactile_matrix.append(tactile_matrix_0)
        tactile_sensors.tactile_matrix.append(tactile_matrix_1)

        while not self.wait_for_result:
            self.component_input.publish(tactile_sensors)
            self.event_out.publish('e_start')

        self.assertSequenceEqual(
            self.result.tactile_array, desired_result.tactile_array
        )

    def result_callback(self, msg):
        self.result = msg
        self.wait_for_result = True

if __name__ == '__main__':
    rospy.init_node('test_sdh_tactile_adapter')
    rostest.rosrun(PKG, 'test_sdh_tactile_adapter', TestTactileAdapter)


from collections import defaultdict
from .repository import Repository
from .shell import Command
import os.path
import textwrap

class ConfigLexer:

    def lex(self, data):
        data = textwrap.dedent(data.strip('\n'))
        output, section, block = [], '', ''
        for line in data.splitlines(True):
            if line.startswith('['):
                block = self.drain_block(section, block, output)
                section = line.strip()[1:-1]
                continue
            else:
                block += line
        else:
            block = self.drain_block(section, block, output)
        return output

    __call__ = lex

    def drain_block(self, section, block, output):
        if block:
            block = textwrap.dedent(block)
            key, values = '', []
            for line in block.splitlines():
                if not line.strip():
                    continue

                if key and line[0] in (' ', '\t'):
                    # it must be a value
                    values.append(line.strip())
                    pass
                if '=' in line:
                    if key:
                        output.append((section, key, values))
                        values = []
                    key, _, val = line.partition('=')
                    key = key.strip()
                    val = val.strip()
                    if val:
                        values.append(val)
            if key:
                output.append((section, key, values))
                values = []
        return ''

class ConfigParser:

    def parse_repository(self, key, values, repository):
        if key == 'work-tree':
            repository['work_tree'] = values[-1]
        elif key == 'git-dir':
            repository['git_dir'] = values[-1]
        elif key == 'bare':
            repository['bare'] = values[-1] == 'true'
        else:
            raise ValueError('unknown option %s' % key)

    def parse(self, data):
        repositories = defaultdict(lambda: {
            'work_tree': None,
            'git_dir': None,
            'bare': None
        })
        for section, key, values in data:
            if section.startswith('repository '):
                name = section[12:-1]
                repository = repositories[name]
                self.parse_repository(key, values, repository)

            else:
                raise ValueError('unknown section %s' % section)

        repositories = {Repository(name, **opts)
                        for name, opts in repositories.items()}
        return {
            'repositories': repositories
        }

    __call__ = parse

class ConfigReader:

    def __init__(self):
        self.lexer = ConfigLexer()
        self.parser = ConfigParser()

    def read(self, data):
        data = self.lexer(data)
        data = self.parser(data)
        return data

    def read_from_filename(self, filename):
        with open(filename) as file:
            data = file.read()
            return self.read(data)
        return data

    __call__ = read

class ConfigWriter:

    def write(self, conf):

        def clean(value):
            if value is True:
                return 'true'
            if value is False:
                return 'false'
            if value is None:
                return 'null'
            return value

        buf = ''
        for repository in conf['repositories']:
            buf += '[repository "%s"]\n' % repository.name
            if repository.work_tree is not None:
                buf += '\twork-tree = %s\n' % repository.work_tree
            if repository.git_dir is not None:
                buf += '\tgit-dir = %s\n' % repository.git_dir
            if repository.bare is not None:
                buf += '\tbare = %s\n' % clean(repository.bare)
        return buf
    __call__ = write

    def write_into_filename(self, filename, conf):
        with open(filename, 'w') as file:
            data = self.write(conf)
            file.write(data)

class Settings:

    def __init__(self, config_file=None):
        self._reader = ConfigReader().read_from_filename
        self._writer = ConfigWriter().write_into_filename
        self._config = {'repositories': set()}
        if os.path.isfile(config_file):
            self._config = self._reader(config_file)
        self.config_file = config_file

    def save(self):
        self._writer(self.config_file, self._config)

    def __enter__(self):
        return self

    def __exit__(self, type, value, traceback):
        self.save()

    @property
    def cwd(self):
        return os.path.dirname(self.config_file)

    @property
    def repositories(self):
        return self._config['repositories']

    def Command(self, *cmd, **kwargs):
        cwd = os.path.join(self.cwd, kwargs.pop('cwd', '.'))
        return Command(*cmd, cwd=cwd, **kwargs)


import logging
import numpy as np
from sklearn.metrics import fbeta_score, precision_score, recall_score
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
from starter.ml.data import process_data

# Optional: implement hyperparameter tuning.
def train_model(X_train, y_train):
    """
    Trains a machine learning model and returns it.

    Inputs
    ------
    X_train : np.array
        Training data.
    y_train : np.array
        Labels.
    Returns
    -------
    model
        Trained machine learning model.
    """
    rfc = RandomForestClassifier(random_state=42)
    param_grid = {
        'n_estimators': [200, 500],
        'max_features': ['auto'],
        'max_depth': [4, 20, 100],
        'criterion': ['gini']
    }
    cv_rfc = GridSearchCV(estimator=rfc, param_grid=param_grid, cv=5)
    cv_rfc.fit(X_train, y_train)
    return cv_rfc.best_estimator_

def compute_model_metrics(y, preds):
    """
    Validates the trained machine learning model using precision, recall, and F1.

    Inputs
    ------
    y : np.array
        Known labels, binarized.
    preds : np.array
        Predicted labels, binarized.
    Returns
    -------
    precision : float
    recall : float
    fbeta : float
    """
    fbeta = fbeta_score(y, preds, beta=1, zero_division=1)
    precision = precision_score(y, preds, zero_division=1)
    recall = recall_score(y, preds, zero_division=1)
    return precision, recall, fbeta

def inference(model, X):
    """ Run model inferences and return the predictions.

    Inputs
    ------
    model : RandomForestClassifier
        Trained machine learning model.
    X : np.array
        Data used for prediction.
    Returns
    -------
    preds : np.array
        Predictions from the model.
    """
    preds = model.predict(X)
    return preds

def validate_model_per_slice(trained_model, df_test, cat_feats,
                            encoder, lb, output_path):
    """ Run model inferences and return the predictions.

    Inputs
    ------
    trained_model : RandomForestClassifier
        Trained machine learning model.
    df_test : pd.DataFrame
        Test Data frame for validation.
    cat_feats : list[str]
        List containing the names of the categorical features.
    encoder : sklearn.preprocessing._encoders.OneHotEncoder
        Trained sklearn OneHotEncoder.
    lb : sklearn.preprocessing._label.LabelBinarizer
        Trained sklearn LabelBinarizer.
    output_path : str
        Path of text file for writing the output of validation results.
    Returns
    -------

    """
    logging.basicConfig(level=logging.INFO, format="%(asctime)-15s %(message)s")
    logger = logging.getLogger()
    with open(output_path,'w') as output_file:
        for cat in cat_feats:
            for cat_type in df_test[cat].unique():
                df_cat_type = df_test[df_test[cat]==cat_type]

                X_test, y_test, _, _ = process_data(
                    df_cat_type, cat_feats, label="salary", training=False, encoder=encoder, lb=lb
                )
                y_pred = trained_model.predict(X_test)
                test_precision, test_recall, test_fbeta = compute_model_metrics(y_test, y_pred)
                slice_metrics = f"{cat}_{cat_type}; Precision: {test_precision}, Recall: {test_recall}, fbeta: {test_fbeta}"
                logger.info(slice_metrics)
                output_file.write(slice_metrics + '\n')


from . import FuncTest

class TestRoot(FuncTest):
    def test_index(self):
        res = self.testapp.get('/', status=200)
        res.mustcontain(
            '
Pyramid App
'
        )
        self.assertEqual(res.click('Learn more').status_int, 200)

    def test_about(self):
        res = self.testapp.get('/about.html', status=200)
        res.mustcontain('
About
')


import numpy as np
from scipy.optimize import curve_fit, minimize
import matplotlib.pyplot as plt

### CONSTANTS

# colours to use for different wavelength beams
BEAM_COLORS = [(0, 500e-9, 'blue', 'royalblue', 'slateblue', 'blueviolet', 'midnightblue'),
                (500e-9, 550e-9, 'darkgreen', 'olivedrab', 'yellowgreen', 'limegreen', 'darkgreen'),
                (550e-9, 600e-9, 'goldenrod', 'gold', 'orange', 'darkkhaki', 'olive'),
                (600e-9, np.inf, 'firebrick', 'red', 'orangered', 'lightsalmon', 'maroon')]

# standard SI prefixes for distance
SI_UNITS = [(1e-15, 'fm'), (1e-12, 'pm'), (1e-9, 'nm'), (1e-6, 'um'), (1e-3, 'mm'), (1, 'm'), (1e3, 'km')]

### FUNCTIONS

def determine_prefix(lengths):
    '''
    Given a length (or list of lengths),
    return a tuple with the appropriate unit multiplier
    and a string of the unit symbol.
    '''
    min_length = np.array(lengths, ndmin=1).min()
    i = 0
    while min_length > SI_UNITS[i][0]:
        i += 1
    return SI_UNITS[max(i-1,0)]

def apply_buffer(value, buffer, left=False):
    '''
    Apply buffer to given value. If right side of domain,
    multiply by (1+buffer) for positive values and (1-buffer)
    for negative values (and vice versa for left side).
    '''
    return value*(1+buffer) if ((value > 0) != left) else value*(1-buffer)

def default_ext(array, default=0, min=False):
    '''
    Compute maximum of an array. Empty arrays
    give the specified default value.
    '''
    if len(array) > 0:
        return np.amin(array) if min else np.amax(array)
    else:
        return default

def nearest_index(array, value):
    return np.argmin(np.abs(array-value))

def empty_matrix(d):
    '''
    Given a list of distances, return 2x2 identity matrices
    repeated over a dimension with size equal to the list.
    '''
    return np.tile(np.eye(2)[np.newaxis,:,:], (len(d), 1, 1) )

def space(d, n, start=None, end=None, start_ind=None, end_ind=None):
    '''
    Given a N-length list of distances and numbers specifying the
    start and end of propagation, return a Nx2x2 matrix for
    propagation along the specified length.
    '''
    if start_ind is None:
        start_ind = nearest_index(d, start)
    elif start is None:
        start = d[start_ind]

    if end_ind is None:
        end_ind = nearest_index(d, end)
    elif end is None:
        end = d[end_ind]

    matrix = empty_matrix(d)
    matrix[start_ind:end_ind,0,1] = d[start_ind:end_ind]-start
    matrix[end_ind:,0,1] = end-start

    matrix[:0,1] /= n

    return matrix

def curved_interface(d, n1, n2, r, pos=None, pos_ind=None):
    if pos_ind is None:
        pos_ind = nearest_index(d, pos)

    matrix = empty_matrix(d)
    matrix[pos_ind:,1,0] = (n1 - n2) / (r*n2)
    matrix[pos_ind:,1,1] = n1 / n2

    return matrix

def apply_transfer(q, matrix):
    '''
    Given a complex beam parameter q and a Nx2x2 ray transfer matrix,
    calculate the complex beam parameter at each of the N positions.
    '''
    return (matrix[:,0,0]*q + matrix[:,0,1])/(matrix[:,1,0]*q + matrix[:,1,1])

def get_radius(q, wavelength):
    '''
    Given a list of complex beam parameters and a wavelength,
    calculate the beam radius from each q.
    '''
    waist_size = np.sqrt(wavelength * np.imag(q) / np.pi)
    return waist_size*np.sqrt(1 + (np.real(q) / np.imag(q))**2)

def get_phase(q):
    '''
    Given a list of complex beam parameters,
    calculate the Gouy phase from each q.
    '''
    return np.degrees(np.arctan(np.real(q)/np.imag(q)))

def plot(*beams, **kwargs):
    '''
    Plot the beam radius and Guoy phase over some distance
    (determined by either the measurement datapoints, waist position,
    Rayleigh range or lens positions).
    '''
    BUFFER = kwargs.get('BUFFER', 0.1)
    N = kwargs.get('N', 2000)
    include_data = kwargs.get('include_data', True)

    # pre-process beams
    min_size = np.inf
    max_size = 0
    beam_domains = [None]*len(beams)
    beam_sizes = [None]*len(beams)
    beam_phases = [None]*len(beams)
    plot_data = [False]*len(beams)
    for i, beam in enumerate(beams):
        beam = beams[i]

        if hasattr(beam, 'position_array') and include_data:
            d_min = np.min(beam.position_array)
            d_max = np.max(beam.position_array)
            buffer_distance = BUFFER*(d_max - d_min)
            beam_domains[i] = np.linspace(d_min-buffer_distance, d_max+buffer_distance, N)

            plot_data[i] = True
        else:
            if beam.reverse:
                last_lens = default_ext([x.pos for x in beam.lenses], beam.source, min=True)
                last_q = beam.propagate_beam_q(last_lens-BUFFER).item()
                domains = [last_lens-BUFFER-2*np.real(last_q),
                            beam.source - np.imag(last_q),
                            last_lens]
                domain_start = apply_buffer(min(domains), BUFFER, left=True)
                domain_end = beam.source
            else:
                last_lens = default_ext([x.pos for x in beam.lenses], beam.source)
                last_q = beam.propagate_beam_q(last_lens+BUFFER).item()
                domains = [last_lens+BUFFER-2*np.real(last_q),
                            beam.source + np.imag(last_q),
                            last_lens]

                domain_start = beam.source
                domain_end = apply_buffer(max(domains), BUFFER)
            beam_domains[i] = np.linspace(domain_start, domain_end, N)

        beam_sizes[i], beam_phases[i] = beam.propagate_beam(beam_domains[i])

        cur_min = np.min(beam_sizes[i])
        if cur_min < min_size:
            min_size = cur_min

        cur_max = np.max(beam_sizes[i])
        if cur_max > max_size:
            max_size = cur_max

    waist_unit = determine_prefix(min_size)
    show_legend = False

    # plot beams
    plt.figure(figsize=(7, 5))
    plt.subplot(211)
    for i in range(len(beams)):
        beam = beams[i]
        kwargs = {}
        if beam.label is not None:
            kwargs['label'] = beam.label
            show_legend = True
        plt.plot(beam_domains[i], beam_sizes[i]/waist_unit[0], '-', color=beam.profile[3+i], **kwargs)
        if plot_data[i]:
            plt.plot(beam.position_array, beam.size_array/waist_unit[0], '.', markersize=10, color=beam.profile[2])

        for j in range(len(beam.lenses)):
            plt.axvline(x=beam.lenses[j].pos, linestyle='--', color=beam.profile[2], alpha=0.5)

    plt.grid(which='both')
    plt.gca().autoscale(enable=True, axis='x', tight=True)
    plt.ylabel('Beam size [{}]'.format(waist_unit[1]))
    plt.ylim([0, (1+BUFFER)*max_size/waist_unit[0]])
    if show_legend:
        plt.legend(loc='best')
    plt.subplot(212)
    for i in range(len(beams)):
        plt.plot(beam_domains[i], beam_phases[i], '-', color=beam.profile[3+i])
    plt.ylabel('Gouy phase [$^\circ$]')
    plt.xlabel('Position [m]')
    plt.grid(which='both')
    plt.gca().autoscale(enable=True, axis='x', tight=True)
    plt.ylim([-90, 90])
    plt.yticks(np.arange(-90, 90+30, 30))
    plt.tight_layout()
    plt.show()

def optimize(lenses, beam, target, position, tol=0.0001):
    '''
    Uses the given list of lenses to match the
    beam and the target (the latter of which may be
    another beam or a target waist size) at the given
    position.
    '''
    lenses = np.array(lenses, ndmin=1)
    def obj(positions, beam, target, position):
        for i in range(len(lenses)):
            lenses[i].pos = positions[i]

        q = beam.propagate_beam_q(position)

        is_beam = not isinstance(target, (int, float, complex))

        if is_beam and len(lenses) > 1:
            target = target.propagate_beam_q(position)
            return np.abs(q-target)
        else:
            if is_beam:
                target = target.propagate_beam(position, return_phase=False)
            return (beam.get_radius(q, position) - target)**2

    base_bound = (beam.source, position)
    if beam.reverse:
        base_bound = base_bound[::-1]

    positions = minimize(obj, [x.pos for x in lenses], bounds=[base_bound]*len(lenses),
                            args=(beam, target, position), tol=(beam.get_radius()*tol)**2).x

    for i in range(len(lenses)):
        lenses[i].pos = positions[i]

    is_beam = not isinstance(target, (int, float, complex))
    q = beam.propagate_beam_q(position)
    if is_beam:
        q2 = target.propagate_beam_q(position)
        return ((q * np.conj(q2) / (np.conj(q2) - q)) * (2*beam.wavelength / (get_radius(q2, beam.wavelength) / get_radius(q, beam.wavelength) / np.pi)) * -1j)**4
    else:
        return np.abs(q-target)

### CLASSES

class Beam(object):
    '''
    A Beam object is defined by a complex beam parameter given at a particular position,
    as well as a list of lenses acting on the beam.
    '''
    def __init__(self, source, source_q, lenses=[], reverse=False, wavelength=None, label=None):
        '''
        Instantiate a beam with a given source position,
        complex beam parameter at source, wavelength, and
        list of Lens objects.
        '''
        self.source, self.source_q, self.lenses, self.reverse, self.wavelength, self.label = source, source_q, lenses, reverse, wavelength, label

    @property
    def system(self):
        '''
        Getter for system context.
        '''
        if not hasattr(self, '__system'):
            self.__system = DEFAULT_SYSTEM
        return self.__system

    @system.setter
    def system(self, system):
        '''
        Setter for system context.
        '''
        self.__system = system

    @property
    def wavelength(self):
        '''
        Getter for wavelength.
        '''
        return self.__wavelength

    @wavelength.setter
    def wavelength(self, value):
        '''
        Setter for wavelength; updates color information
        for plotting.
        '''
        self.__wavelength = value if value is not None else self.system.wavelength
        for profile in BEAM_COLORS:
            if profile[0] < self.wavelength < profile[1]:
                self.profile = profile
                return

    @property
    def lenses(self):
        '''
        Getter for lens list.
        '''
        return self.__lenses

    @lenses.setter
    def lenses(self, value):
        '''
        Setter for lens list; ensures list is sorted.
        '''
        self.__lenses = sorted(value, key=lambda x: x.pos)

    def set_data(self, position_array, size_array):
        '''
        Associate a set of measurements (list of measurement positions
        and beam size at those positions) with the beam.
        '''
        self.position_array, self.size_array = position_array, size_array

    def plot(self, BUFFER=0.1, N=2000, include_data=True):
        plot(self, BUFFER=BUFFER, N=N, include_data=include_data)

    def build_transfer(self, d):
        '''
        Given a N-length list of positions, return a
        Nx2x2 ray transfer matrix from the lenses
        associated with this beam.
        '''
        wv = self.wavelength
        sub = self.system.ambient_substrate
        n0 = sub.n(wv)

        d = np.array(d, ndmin=1)
        for i in range(0, len(d)-1):
            if d[i] > d[i+1]:
                raise ValueError('List of positions should be sorted')
                ################### TODO: add reverse logic
        i = 0
        matrix = empty_matrix(d)
        current_position = self.source
        while i < len(self.lenses) and self.lenses[i].start() < d[-1]:
            matrix = np.matmul(space(d, n0, current_position, self.lenses[i].start()), matrix)
            matrix = np.matmul(self.lenses[i].matrix(d, wv, sub), matrix)
            current_position = self.lenses[i].end()
            i += 1
        matrix = np.matmul(space(d, n0, current_position, d[-1]), matrix)
        return matrix

    def path_wavelength(self, d):
        d = np.array(d, ndmin=1)
        n = np.ones(len(d)) * self.system.ambient_substrate.n(self.wavelength)
        for l in self.lenses:
            if hasattr(l, 'substrate'):
                start = nearest_index(d, l.start())
                end = nearest_index(d, l.end())
                n[start:end] = l.substrate.n(self.wavelength)
        return self.wavelength / n

    def get_radius(self, q=None, d=None):
        '''
        Given a list of complex beam parameters,
        return the beam radii using the appropriate
        wavelength.
        '''
        if q is None:
            q = self.source_q
        if d is None:
            wavelength = self.wavelength
        else:
            wavelength = self.path_wavelength(d)
        return get_radius(q, wavelength)

    def propagate_beam_q(self, d):
        '''
        Given a list of distances, return the
        complex beam parameter at each position
        by propagating through the system of lenses.
        '''
        return apply_transfer(self.source_q, self.build_transfer(d))

    def propagate_beam(self, d, return_phase=True):
        '''
        Given a list of distances, return the
        beam radii (and Guoy phase) at each position
        by propagating through the system of lenses.
        '''
        q_values = self.propagate_beam_q(d)
        beam_sizes = self.get_radius(q_values, d)
        if return_phase:
            phases = get_phase(q_values)
            return beam_sizes, phases
        else:
            return beam_sizes

    def addLens(self, lens):
        '''
        Add the specified lens to this path.
        '''
        self.lenses = self.lenses + [lens]

    def removeLens(self, lens):
        '''
        Remove the specified lens from this path.
        '''
        self.lenses.remove(lens)

def fit_beam(position_array, size_array, source, wavelength, lenses=[], label=None):
    '''
    Given a list of positions, a list of beam radii, a source position,
    wavelength and a list of lenses (present during measurement),
    return a beam object defined by the source position and required
    source complex beam parameter to reproduce the measured values.
    '''
    i = np.argsort(position_array)
    position_array = np.array(position_array)[i]
    size_array = np.array(size_array)[i]

    pos_max = position_array.max()
    if position_array.min() < source < pos_max:
        raise ValueError('Source of beam cannot be in the middle of measurements')

    def kinked_line(d, a1, b1, a2, b2):
        if a1 != a2:
            d0 = (b2 - b1)/(a1 - a2)
        else:
            d0 = 0

        size = np.zeros(d.shape)
        size[d<=d0] = a1*(d[d<=d0]-b1)
        size[d>d0] = a2*(d[d>d0]-b2)
        return size

    prefit_params, _ = curve_fit(kinked_line, position_array, size_array)
    a1, b1, a2, b2 = prefit_params

    if np.sign(a1) == np.sign(a2):
        def line(d, a, b):
            return a*(d-b)
        prefit_params, _ = curve_fit(line, position_array, size_array)
        a, b = prefit_params
        waist_pos = b
        waist = wavelength / np.pi / a
    else:
        waist_pos = (b2 - b1)/(a1 - a2)
        waist = np.min(size_array)

    def beam_size(d, source_q_real, source_q_imag):
        new_beam = Beam(source, source_q_real + source_q_imag * 1j, lenses,
                       (pos_max < source), wavelength)
        return new_beam.propagate_beam(position_array, return_phase=False)

    initial_guess = (source - waist_pos, waist)

    fit_params, _ = curve_fit(beam_size, position_array, size_array,
                              bounds=([-np.inf, 0], [np.inf, np.inf]),
                              p0=initial_guess)

    new_beam = Beam(source, fit_params[0] + fit_params[1] * 1j,
                   lenses, (pos_max < source), wavelength, label)
    new_beam.set_data(position_array, size_array)
    return new_beam

class Lens(object):
    '''
    A lens object, defined by a position and focal length.
    '''
    def __init__(self, f, pos=0, beams=None):
        self.f, self.pos = f, pos
        self.add_beams(beams)

    def add_beams(self, beams):
        if beams is not None:
            beams = np.array(beams, ndmin=1)
            for beam in beams:
                beam.addLens(self)

    def matrix(self, d, wavelength, ambient_substrate):
        pos_ind = nearest_index(d, self.pos)

        matrix = empty_matrix(d)
        matrix[pos_ind:,1,0] = -1./self.f

        return matrix

    def start(self):
        return self.pos

    def end(self):
        return self.pos

class ThickLens(Lens):
    def __init__(self, r, pos=0, beams=None, substrate=None):
        self.r, self.pos, self.substrate = r, pos, substrate
        self.add_beams(beams)

    def start(self):
        return self.pos - self.thickness/2

    def end(self):
        return self.pos + self.thickness/2

    def thickness_calc(self):
        if self.r1 > 0 and self.r2 > 0:
            thickness = 0.00635

            for r in [self.r1, self.r2]:
                if r != np.inf:
                    thickness += r - np.sqrt(r**2 - (self.diameter/2)**2)
        else:
            thickness = 0.0035

        return thickness

    @property
    def thickness(self):
        if not hasattr(self, '__thickness'):
            self.__thickness = self.thickness_calc()
        return self.__thickness

    @thickness.setter
    def thickness(self, value):
        self.__thickness = value

    @property
    def diameter(self):
        if not hasattr(self, '__diameter'):
            self.__diameter = 0.0254
        return self.__diameter

    @diameter.setter
    def diameter(self, value):
        self.__diameter = value

    @property
    def system(self):
        if not hasattr(self, '__system'):
            self.__system = DEFAULT_SYSTEM
        return self.__system

    @system.setter
    def system(self, value):
        self.__system = value

    @property
    def substrate(self):
        if not hasattr(self, '__substrate'):
            self.__substrate = self.system.optic_substrate
        return self.__substrate

    @substrate.setter
    def substrate(self, value):
        self.__substrate = value

    def matrix(self, d, wavelength=None, ambient_substrate=None):
        if wavelength is None:
            wavelength = self.system.wavelength
        if ambient_substrate is None:
            ambient_substrate = self.system.ambient_substrate

        n_lens = self.substrate.n(wavelength)
        nAmbient = ambient_substrate.n(wavelength)

        start = self.start()
        end = self.end()

        start_ind = nearest_index(d, start)
        end_ind = nearest_index(d, end)

        matrix = np.matmul(
            np.matmul(curved_interface(d, n_lens, nAmbient, self.r2, pos_ind=end_ind),
                      space(d, n_lens, start_ind=start_ind, end_ind=end_ind)),
            curved_interface(d, nAmbient, n_lens, self.r1, pos_ind=start_ind))

        return matrix

class PlanoConvex(ThickLens):
    '''
    A plano-convex(cave) lens, defined by a position,
    a radius of curvature and a substrate material.
    '''
    @property
    def r1(self):
        if not hasattr(self, '__r1'):
            self.__r1 = self.r
        return self.__r1

    @r1.setter
    def r1(self, value):
        self.__r1 = value

    @property
    def r2(self):
        if not hasattr(self, '__r1'):
            self.__r2 = np.inf
        return self.__r2

    @r2.setter
    def r2(self, value):
        self.__r2 = value

class BiConvex(ThickLens):
    '''
    A bi-convex(cave) lens, defined by a position,
    a radius (or radii) of curvature and a substrate
    material.
    '''
    @property
    def r1(self):
        if not hasattr(self, '__r1'):
            self.__r1 = self.r
        return self.__r1

    @r1.setter
    def r1(self, value):
        self.__r1 = value

    @property
    def r2(self):
        if not hasattr(self, '__r1'):
            self.__r2 = -self.r
        return self.__r2

    @r2.setter
    def r2(self, value):
        self.__r2 = value

class Substrate(object):
    '''
    A substrate material, defined by a dispersion
    formula.
    '''
    def __init__(self, n, microns=True):
        '''
        Initialize substrate with refractive index.
        '''
        self.n = lambda l: n(l*1e6 if microns else l)

BK7 = Substrate(lambda l:
                np.sqrt(1 +
                        1.03961212*l**2/(l**2 - 0.00600069867) +
                        0.231792344*l**2/(l**2 - 0.0200179144) +
                        1.01046945*l**2/(l**2 - 103.560653)
                ))

FUSED_SILICA = Substrate(lambda l:
                np.sqrt(1 +
                        0.6961663*l**2/(l**2 - 0.0684043**2) +
                        0.4079426*l**2/(l**2 - 0.1162414**2) +
                        0.8974794*l**2/(l**2 - 9.896161**2)
                ))

VACUUM = Substrate(lambda l: 1)
AIR = Substrate(lambda l:
                1 + 0.05792105/(238.0185 - l**-2) +
                0.00167917/(57.362 - l**-2))

class System(object):
    def __init__(self, wavelength=1064e-9, optic_substrate=FUSED_SILICA, ambient_substrate=AIR):
        self.wavelength, self.optic_substrate, self.ambient_substrate = wavelength, optic_substrate, ambient_substrate

    def beam(self, *args, **kwargs):
        new_beam = Beam(*args, **kwargs)
        new_beam.system = self
        return new_beam

DEFAULT_SYSTEM = System()


from dash import dcc, html
import dash_bootstrap_components as dbc

external_stylesheets=['https://use.fontawesome.com/releases/v5.8.1/css/all.css']
href_download_btn = "data\\raw\\HIST_PAINEL_COVIDBR_02jun2023.zip" # Atualizar diretório relativo

class LogoInitials:
    def __init__(self):
        self.element = html.A(
            html.Img(
                src="assets\imagens\logo_initials.png",
                height="75px"
            ),
            href="https://eduardo-pereira.webflow.io/",
            title="Visitar Portfólio",
            target="_blank",
            style={"textDecoration": "none"}
        )

class LogoApp:
    def __init__(self):
        self.element = html.A(
            html.Img(
                src="assets\imagens\logo_app.png",
                height="50px"
            ),
            href="/",
            style={"textDecoration": "none", "marginLeft": "20px", "marginRight": "20px"}
        )

class OpenVisaoGeral:
    def __init__(self):
        self.element = dbc.NavItem(
            dbc.NavLink("Visão Geral", id="open-visaoGeral", style={"cursor": "pointer"})
        )

class OpenObjetivos:
    def __init__(self):
        self.element = dbc.NavItem(
            dbc.NavLink("Objetivos", id="open-objetivos", style={"cursor": "pointer"})
        )

class OpenDados:
    def __init__(self):
        self.element = dbc.NavItem(
            dbc.NavLink("Dados", id="open-dados", style={"cursor": "pointer"})
        )

class OpenFrameworks:
    def __init__(self):
        self.element = dbc.NavItem(
            dbc.NavLink("Frameworks", id="open-frameworks", style={"cursor": "pointer"})
        )

class SocialBar:
    def __init__(self):
        self.element = html.Div(
            [
                html.A(
                    html.Img(
                        src="assets\imagens\gmail_icon.svg",
                        className="mr-2 inverted-icon",
                    ),
                    href="mailto:eduardojr.pereira@gmail.com",
                    target="_blank",
                    title="Enviar email"
                ),
                html.A(
                    html.Img(
                        src="assets\imagens\linkedin_icon.svg",
                        className="mr-2 inverted-icon",
                    ),
                    href="https://www.linkedin.com/in/eduardo-jr-pereira/",
                    target="_blank",
                    title="Ver perfil no Linkedin"
                ),
                html.A(
                    html.Img(
                        src="assets\imagens\github_icon.svg",
                        className="mr-2 inverted-icon",
                    ),
                    href="https://github.com/eduardojr-pereira",
                    target="_blank",
                    title="Visitar repositório no Github"
                ),
                html.A(
                    html.Img(
                        src="assets\imagens\discord_icon.svg",
                        className="mr-2 inverted-icon",
                    ),
                    href="https://discord.com/channels/1095050260964966483/1111074732503203900",
                    target="_blank",
                    title="Chamar no Discord"
                )
            ],
            className="d-flex justify-content-around"
        )

class DownloadCvButton:
    def __init__(self):
        self.element = dbc.Button(
            "Download - CV",
            href="https://drive.google.com/file/d/1KsDqlciv2BpCuvGBKzs6cPz5N5n4rjyr/view?usp=sharing",
            download="CV_EduardoPereira",
            external_link=True,
            title="Curriculum Vitae - Eduardo Pereira",
            outline=True,
            className="btn btn-outline-light button-animation",
            style={"width": "175px"}
        )

class DropdownPortfolio:
    def __init__(self):
        self.element = dbc.DropdownMenu(
            children=[
                dbc.DropdownMenuItem(
                    [
                        dbc.Row(
                            [
                                dbc.Col(html.I(className="fas fa-camera", style={"width": "10px"}), width="auto"),
                                dbc.Col("Entry 1", width=True),
                            ],
                            align="center",
                        )
                    ],
                    href="projeto1",
                    target="_blank"
                ),
                dbc.DropdownMenuItem(
                    [
                        dbc.Row(
                            [
                                dbc.Col(html.I(className="far fa-file-alt", style={"width": "10px"}), width="auto"),
                                dbc.Col("Entry 2", width=True),
                            ],
                            align="center",
                        )
                    ],
                    href="projeto2",
                    target="_blank"
                ),
                dbc.DropdownMenuItem(
                    [
                        dbc.Row(
                            [
                                dbc.Col(html.I(className="fas fa-chart-bar", style={"width": "10px"}), width="auto"),
                                dbc.Col("Entry 3", width=True),
                            ],
                            align="center",
                        )
                    ],
                    href="projeto3",
                    target="_blank"
                ),
                dbc.DropdownMenuItem(
                    [
                        dbc.Row(
                            [
                                dbc.Col(html.I(className="fas fa-code", style={"width": "10px"}), width="auto"),
                                dbc.Col("Entry 4", width=True),
                            ],
                            align="center",
                        )
                    ],
                    href="projeto4",
                    target="_blank"
                ),
                dbc.DropdownMenuItem(
                    [
                        dbc.Row(
                            [
                                dbc.Col(html.I(className="fas fa-star", style={"width": "10px"}), width="auto"),
                                dbc.Col("Entry 5", width=True),
                            ],
                            align="center",
                        )
                    ],
                    href="projeto5",
                    target="_blank"
                ),
                dbc.DropdownMenuItem(
                    [
                        dbc.Row(
                            [
                                dbc.Col(html.I(className="fas fa-book", style={"width": "10px"}), width="auto"),
                                dbc.Col("Blog", width=True),
                            ],
                            align="center",
                        )
                    ],
                    href="/blog",
                    target="_blank"
                ),
                dbc.DropdownMenuItem(divider=True),
                dbc.DropdownMenuItem(html.P("Perfil Profissional:", className="text-center text-light"), disabled=True),
                dbc.DropdownMenuItem(SocialBar().element),
                dbc.DropdownMenuItem(
                    html.Div(
                        [
                            DownloadCvButton().element
                        ],
                        className="d-flex justify-content-center align-items-center mt-2 mb-2 w-100"
                    )
                )
            ],
            nav=True,
            in_navbar=True,
            label=[
                html.I(className="fas fa-code", style={"margin-right": "10px"}),
                "Portfólio"
            ]
        )

class NavbarComponent:
    @staticmethod
    def create_navbar():
        navbar = dbc.Navbar(
            dbc.Container(
                [
                    LogoApp().element,
                    dbc.NavbarToggler(id="navbar-toggler", n_clicks=0, style={"marginRight":"20px"}),
                    dbc.Collapse(
                        [
                            dbc.Nav(
                                [
                                    OpenVisaoGeral().element,
                                    OpenObjetivos().element,
                                    OpenDados().element,
                                    OpenFrameworks().element,
                                    DropdownPortfolio().element
                                 ],
                                className="me-auto",
                                navbar=True,
                            )
                        ],
                        id="navbar-collapse",
                        navbar=True,
                    )
                ]
            ),
            color="dark",
            dark=True
        )
        return navbar

class OffCanvas:
    @staticmethod
    def create_offcanvas_visao_geral():
        offcanvas_visao_geral = dbc.Offcanvas(
            id="offcanvas-visaoGeral",
            className= "offcanvas-animation",
            children=[
                html.H3("Visão Geral", className="text-center text-white"),
                html.Hr(),
                html.P(
                    "É de conhecimento geral que a pandemia do coronavírus tem impactado significativamente o Brasil e o mundo. Assim, acompanhar a "
                    "evolução dos casos, das taxas de transmissão e dos esforços de controle é de extrema importância."
                ),
                html.Br(),
                html.P(
                    "Além disso, a disseminação de informações confiáveis é essencial para combater a desinformação e contribuir para uma "
                    "compreensão clara da situação atual da pandemia no Brasil."
                ),
                html.Br(),
                dcc.Markdown('''
                    Nesse sentido, o aplicativo **coronaDash** visa suprir essa necessidade, fornecendo uma plataforma confiável e acessível
                    para a visualização e análise dos dados relacionados ao COVID-19.
                '''
                ),
                html.Br(),
                html.P(
                    "Através de ferramentas interativas como gráficos, mapas e análises de dados, o aplicativo permite aos usuários acompanhar de perto "
                    "e compreender a situação da pandemia em nosso país. A plataforma também oferece a possibilidade de filtrar e selecionar informações "
                    "específicas, proporcionando uma visão clara e detalhada da evolução da pandemia do coronavírus no Brasil."
                )
            ]
        )
        return offcanvas_visao_geral

    @staticmethod
    def create_offcanvas_objetivos():
        objetivos =[
            "Utilizar ferramentas de Ciências de Dados para fornecer dados atualizados e confiáveis sobre o COVID-19 no Brasil;",
            "Permitir a visualização da evolução da pandemia em diferentes regiões do país;",
            "Oferecer ferramentas interativas para análise e visualização dos dados, auxiliando na identificação de tendências e padrões;",
            "Facilitar a compreensão dos dados através de gráficos e tabelas interativas;",
            "Possibilitar a comparação entre diferentes estados e municípios em relação ao número de casos e óbitos."
        ]

        offcanvas_objetivos = dbc.Offcanvas(
            id="offcanvas-objetivos",
            className= "offcanvas-animation",
            children=[
                html.H3("Objetivos", className="text-center text-white"),
                html.Hr(),
                html.H5("Objetivo principal:"),
                html.P(
                    "Este projeto tem como objetivo principal fornecer informações atualizadas e relevantes sobre a evolução da pandemia no Brasil, "
                    "de maneira confiável e acessível, para que todos possam se manter informados e tomar decisões bem embasadas diante dessa crise de saúde."
                ),
                html.Br(),
                html.H5("Objetivos específicos:"),
                html.Ol([html.Li(objetivo) for objetivo in objetivos])
            ]
        )
        return offcanvas_objetivos

    @staticmethod
    def create_offcanvas_dados():
        offcanvas_dados = dbc.Offcanvas(
            id="offcanvas-dados",
            className= "offcanvas-animation",
            children=[
                html.H3("Conjunto de Dados", className="position-relative text-center text-white"),
                html.Div(
                    [
                        dbc.Badge(id="last-update-texto", color="light")
                    ],
                    className="text-center w-100"
                ),
                html.Hr(),
                html.P(
                    "O conjunto de dados utilizado nesse projeto é disponibilizado diariamente "
                    "pelo Ministério da Saúde através do Portal Brasileiro de Dados Abertos "
                    "e as informações contidas no dataset incluem dados sobre casos e óbitos "
                    "por COVID-19 no Brasil, agregados por estado, município e data."
                ),
                html.Br(),
                html.P(
                    "O dataset fornece informações valiosas para acompanhar a evolução do "
                    "COVID-19 no Brasil, permitindo análises e visualizações para entender "
                    "a propagação da doença."
                ),
                html.Br(),
                html.P(
                    "Esse conjunto de dados apresenta um total de 6.406.528 registros "
                    "e 17 colunas, além disso a memória utilizada pelo DataFrame é "
                    "de aproximadamente 879,8MB"
                ),
                html.Br(),
                html.Div(
                    [
                        dbc.Button(
                            "Portal de Dados Abertos",
                            href="https://dados.gov.br/home",
                            title="Fonte dos dados para o Covid-19",
                            target="_blank",
                            outline=True,
                            className="btn btn-outline-light button-animation"
                        ),
                        dbc.Button(
                            "Download",
                            href=href_download_btn,
                            download="covid_dataset.zip",
                            external_link=True,
                            title="Baixar os dados brutos",
                            outline=True,
                            className="btn btn-outline-light button-animation"
                        )
                    ],
                    className="d-flex justify-content-between"
                )
            ]
        )
        return offcanvas_dados

    @staticmethod
    def create_offcanvas_frameworks():
        frameworks = [
            {"item": "Numpy", "descricao": "biblioteca Python para realizar cálculos numéricos eficientes."},
            {"item": "Pandas", "descricao": "biblioteca Python para análise e manipulação de dados."},
            {"item": "Dash", "descricao": "framework Python para a criação de aplicativos web interativos."},
            {"item": "Dash Bootstrap Components", "descricao": "conjunto de componentes Bootstrap para uso no Dash."},
            {"item": "Plotly", "descricao": "biblioteca Python para a criação de gráficos interativos."},
            {"item": "HTML e CSS", "descricao": "Linguagens de marcação e estilo para construir a interface do aplicativo Dash."},
            {"item": "JSON", "descricao": "biblioteca Python para trabalhar com dados no formato JSON."},
            {"item": "Jupyter Notebooks", "descricao": "ambiente para escrever e executar código Python de forma exploratória."},
            {"item": "Visual Studio Code", "descricao": "Ambiente de desenvolvimento integrado (IDE) para escrever, depurar e executar o código Python."}
        ]

        offcanvas_frameworks = dbc.Offcanvas(
            id="offcanvas-frameworks",
            className= "offcanvas-animation",
            children=[
                html.H3("Recursos e Frameworks utilizados", className="text-center text-white"),
                html.Hr(),
                html.Ul([html.Li([html.B(item["item"]+": ", className="text-white"), html.Span(item["descricao"])]) for item in frameworks]),
                html.Br(),
                html.P(
                    "Optou-se pela utilização das ferramentas supracitadas, especialmente por serem open-source e de fácil replicação.")
            ]
        )
        return offcanvas_frameworks


import logging

import boto3
from botocore.exceptions import ClientError
from retrying import retry
from time_utils import seconds

from tests.common.networking.security_groups import (
    delete_security_group,
    describe_security_groups_for_network_interface,
)

@retry(stop_max_attempt_number=3, wait_fixed=seconds(5))
def describe_fsx_filesystem(region: str, file_system_id: str):
    logging.info(f"Describing FSx File System {file_system_id}")
    try:
        return _fsx(region).describe_file_systems(FileSystemIds=[file_system_id])["FileSystems"][0]
    except Exception as e:
        if isinstance(e, ClientError) and "FileSystemNotFound" in str(e):
            return None
        else:
            logging.error(f"Cannot describe FSx File System {file_system_id}: {e}")
            raise e

@retry(stop_max_attempt_number=10, wait_fixed=seconds(30))
def delete_fsx_filesystem(region: str, file_system_id: str, delete_dependent_resources: bool = True):
    logging.info(f"Deleting FSx File System {file_system_id}")
    try:
        security_group_ids = set()
        if delete_dependent_resources:
            security_group_ids |= describe_fsx_filesystem_security_groups(region, file_system_id)
        _fsx(region).delete_file_system(FileSystemId=file_system_id)
        if delete_dependent_resources:
            logging.info(
                "The following Security Groups will be deleted as part of "
                f"the deletion for the FSx File System {file_system_id}: {security_group_ids}"
            )
            wait_for_fsx_filesystem_deletion(region, file_system_id)
            for security_group_id in security_group_ids:
                delete_security_group(region, security_group_id)
    except Exception as e:
        if isinstance(e, ClientError) and "FileSystemNotFound" in str(e):
            logging.warning(f"Cannot delete FSx File System {file_system_id} because it does not exist")
        else:
            logging.error(f"Cannot delete FSx File System {file_system_id}: {e}")
            raise e

@retry(stop_max_attempt_number=3, wait_fixed=seconds(5))
def describe_fsx_filesystem_security_groups(region: str, file_system_id: str):
    logging.info(f"Describing Security Groups for FSx File System {file_system_id}")
    fs_description = _fsx(region).describe_file_systems(FileSystemIds=[file_system_id])
    network_interface_ids = fs_description["FileSystems"][0]["NetworkInterfaceIds"]
    security_group_ids = set()
    for network_interface_id in network_interface_ids:
        for security_group_id in describe_security_groups_for_network_interface(region, network_interface_id):
            security_group_ids.add(security_group_id)
    return security_group_ids

@retry(stop_max_attempt_number=10, wait_fixed=seconds(60))
def wait_for_fsx_filesystem_deletion(region: str, file_system_id: str):
    logging.info(f"Waiting for deletion of FSx File System {file_system_id}")
    fs_description = describe_fsx_filesystem(region, file_system_id)
    if fs_description is not None:
        state = fs_description.get("Lifecycle")
        raise Exception(f"FSx File System {file_system_id} in state {state} not deleted, yet. Sleeping 60 seconds ...")

def _fsx(region):
    return boto3.client("fsx", region)


from telegram import InlineKeyboardMarkup, Update
from telegram.ext import ContextTypes

from handlers.response import send_response

async def send_choice(
        update: Update,
        context: ContextTypes.DEFAULT_TYPE,
        text: str,
        keyboard: InlineKeyboardMarkup
) -> None:
    await send_response(update, context, text, keyboard)

async def edit_choice(
        query,
        text: str,
        keyboard: InlineKeyboardMarkup
) -> None:
    message = query.message

    if message.text == text and message.reply_markup == keyboard:
        return

    if not text:
        text = query.message.text
    await query.edit_message_text(text=text, reply_markup=keyboard)

async def get_user_choice(query, prefix: str) -> str | None:
    if not _check_query(query):
        return None
    user_choice = query.data.replace(prefix, "")
    return user_choice

def _check_query(query) -> bool:
    return query.data and query.data.strip()

async def get_query(update: Update):
    query = update.callback_query
    await query.answer()
    return query


def calc_acc1(out, label):

    import numpy as np

    run_acc = []

    for i in range(np.size(out,1)):

        top = ( abs(out[:,i,:] - label[:,i,:])/label[:,i,:] ).sum()
        bottom = np.size(out,0)
        run_acc.append(top/bottom)

    run_acc = np.array(run_acc)

    acc = run_acc.sum()/(np.size(out,1))

    return acc

def calc_acc2(out, label):

    import numpy as np

    _, predicted = torch.max(out, 1)
    total += label.size(1)
    correct += (predicted == label).sum()

    acc = correct/total

    return acc


# Author:                       Marcus Nogueira
# Date of latest revision:      12/04/1986
# Purpose:                      A Python script that executes a few bash commands successfully.

# Imports
import os
import subprocess
import time

# Declaration of variables
BLUE = "\033[34m"  # Blue text
RESET = "\033[0m"  # Reset to default color

# Declaration of functions
def snake_bash():
    """Function using bash commands """

    os.system("clear")
    os.system('figlet "Punching Snakes" -f "3d" | lolcat')
    print("\n\n")
    time.sleep(1)

    print(f'{BLUE}LOGGED IN USER: {RESET}')
    os.system('whoami')
    print("")
    time.sleep(1)
    ip_output = subprocess.getoutput(
        "ip a show eno1 | grep -oP 'inet \K\d{1,3}(\.\d{1,3}){3}'")
    print(f'{BLUE}CURRENT IP ADDRESS:\n{RESET}{ip_output}')
    print("")
    time.sleep(1)

    print(f'{BLUE}THIS PC\'S HARDWARE:{RESET}')
    os.system('sudo lshw -short')

# Main
if __name__ == "__main__":
    snake_bash()

# End


#!/usr/bin/env python3

from tkinter.filedialog import askopenfilename
from tkinter import messagebox
from datetime import datetime
from decouple import config
import os
import pandas as pd
import tkinter as tk
import mapper_lib as mp

if __name__ == "__main__":

    current_timestamp = datetime.now().strftime("%H%M%S%d%m%y")
    ccm = mp.Mapper()
    root = tk.Tk()
    root.withdraw()
    msg_box = tk.messagebox.askquestion('Execution Options', 'Open existing file?')

    # routine if existing file is opened
    if msg_box == 'yes':
        filename = askopenfilename(initialdir=os.getcwd()+'/final/')
        data = pd.read_csv(filename)
        root.destroy()
    else:  # routine if data have to be gathered from APIs
        root.destroy()
        ccm.spotify_query()
        ccm.songkick_data_scraping(start_year=2020)
        data = ccm.artist_list_from_songkick

        try:
            os.mkdir(os.getcwd()+'/final')
        except FileExistsError:
            pass

        data.to_csv(os.getcwd()+"/final/list_final_"+current_timestamp+".csv")

    ccm.plot_filter(data,min_occ=50, region_filter=['Northern Europe', 'Western Europe', 'Southern Europe'],year=2020)


import logger_class

class Application:
    applicationDictionary = {}
    __errorClass = 'app_error'
    __error = None

    def createApplication(self, name, path, vwindow):
        if self.isApplicationValid(name, path, vwindow):
            self.__createApplicationDictionary(name, path, vwindow)
        else:
            print("Application Creation Error")

    def __isNameValid(self, name):
        if type(name) is not str:
            self.__error = '[AP#C1]APP_NAME_TYPE_ERROR'
            lg = logger_class.Logger().logError(self.__errorClass, self.__error)
            if not lg: print("Error has not been logged")
            del lg
            return False
        if len(name) > 16:
            self.__error = '[AP#1]APP_LENGTH_ERROR'
            lg = logger_class.Logger().logError(self.__errorClass, self.__error)
            if not lg: print("Error has not been logged")
            del lg
            return False

        return True

    def __isPathValid(self, path):
        if type(path) is not str:
            self.__error = '[AP#C2]PATH_TYPE_ERROR'
            lg = logger_class.Logger().logError(self.__errorClass, self.__error)
            if not lg: print("Error has not been logged")
            del lg
            return False
        if len(path) > 128:
            self.__error = '[AP#2]PATH_LENGTH_ERROR'
            lg = logger_class.Logger().logError(self.__errorClass, self.__error)
            if not lg: print("Error has not been logged")
            del lg
            return False

        return True

    def __isVWindowValid(self, vwindow):
        if type(vwindow) is not int:
            self.__error = '[AP#C3]WINDOW_TYPE_ERROR'
            lg = logger_class.Logger().logError(self.__errorClass, self.__error)
            if not lg: print("Error has not been logged")
            del lg
            return False
        if vwindow > 10:
            self.__error = '[AP#3]WINDOW_VALUE_ERROR'
            lg = logger_class.Logger().logError(self.__errorClass, self.__error)
            if not lg: print("Error has not been logged")
            del lg
            return False

        return True

    def isApplicationValid(self, name, path, vwindow):
        if self.__isNameValid(name) and self.__isPathValid(path) and self.__isVWindowValid(vwindow):
            return True
        else:
            return False

    def __createApplicationDictionary(self, name, path, vwindow):
        self.applicationDictionary = {
            "name": name,
            "path": path,
            "vwindow": vwindow
        }

# app = Application()
# app.createApplication('name', 'path', 3)
# print(app.applicationDictionary)
# del app


# 이 풀이는 시간초과. 리스트에서 dictionary로 변경해주자!
# import sys
# input = sys.stdin.readline
#
# N, M = map(int, input().split())
#
# answer = []
# for i in range(N):
#     answer.append([i, input()])  # 순서, 이름
#
# for _ in range(M):
#     question = input().rstrip()
#     if question.isdigit():  # 숫자면
#         # print(int(question)-1)
#         question = int(question) - 1
#         print(answer[question][1])
#     else:
#         for i in range(N):
#             if question == answer[i][1]:
#                 print(i+1)

import sys
input = sys.stdin.readline

N, M = map(int, input().split())
dict_name = {}
dict_number = {}

for i in range(N):
    name = input().rstrip()
    dict_name[i] = name
    dict_number[name] = i

for _ in range(M):
    question = input().rstrip()
    if question.isdigit():  # 숫자인 경우
        print(dict_name[int(question)-1])
    else:
        print(dict_number[question]+1)


from audioop import reverse

from numpy import False_

def col_a(N):
    m = [0] * 100
    for c in N:
        m[c] += 1
    return m.index(max(m))

def col_d(N):
    d = {}
    for x in N:
        a = d.get(x,0)
        d[x] = a + 1
    y = list(d.items())
    y.sort(key = lambda v : v[1], reverse=True)
    return y[0][0]
N = []
l = int(input('Enter the length of array: '))

def fn(N):
    return len(N['car_name'])

for i in range(l):
    x = int(input('Enter the numbers: '))
    if x > 0 and x < 100:
        N.append(x)
    else:
        print('wrong numbers')

c = col_d(N)
print(c)


import numpy
def numberOfPaths(m, n):
    dp = numpy.empty((m + 1, n + 1))
    dp.fill(0)
    r = m+1
    c = n+1
    def cal(m, n):
        try:
            if m == 1 or n == 1:
                return 1
            elif r > m and c > n and dp[m][n] > 0:
                return dp[m][n]
            elif r > n and c > n and dp[n][m] > 0:
                return dp[n][m]
            else:
                dp[m][n] = cal(m - 1, n) + cal(m, n - 1)
        except Exception as e:
            dp[m][n] = cal(m - 1, n) + cal(m, n - 1)
        return dp[m][n]

    return cal(m, n)
print(numberOfPaths(23,12))