from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.exceptions import ValidationError
from .serializers import FeedbackSerializer, FakeProfileSerializer, UserInfoSerializer, get_user_coin_data, \
    get_user_base_info_data, JieProfileSerializer, JuPeiSerializer
from .permissions import IsCustomUser, IsSuperUser, IsStaffUser
from utils.validators import RaiseMessage
from stores.models import CouponType, CouponTypeValidate
from stores.status import *
from common.renderers import MongoJsonEncoder
from common.permissions import WhiteListOnly
from common.mongo import mongodb
import json
# TODO(ChenQiushi): 印尼，待定
# from general.settings import IMPLICIT_USER
from general.settings import STATIC_URL
from general.events import UserEvent
from django.template.response import TemplateResponse
# from configs.serializers import get_auth_config
from general.settings import JIE_DOMAIN, API_ID_INFO, API_PHONE_INFO
from datetime import datetime
from .user_info import UserInfoMongo
from .serializers import get_auth_config
import requests
from .models import FeedBack, JuPei
from rest_framework.decorators import detail_route, list_route
from rest_framework.viewsets import ReadOnlyModelViewSet
import jieba
import re
from vendors.baidu_ocr import baidu_word_ocr
from common.logs import add_log_count
import traceback

class FeedbackView(APIView):

    permission_classes = (IsCustomUser,)

    def post(self, request):
        serializer = FeedbackSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        token_data = request.token_data
        number = token_data['number']
        device_id = token_data.get('device_id')
        serializer.save(number=number, device_id=device_id)
        return Response({'status': 1})

class ProfileView(APIView):

    permission_classes = (IsCustomUser,)

    def get(self, request):
        user_id = request.user_id
        return Response(get_user_base_info_data(user_id))

    def post(self, request):
        user_id = request.user_id
        user_info = UserInfoMongo(user_id)
        try:  #身份认证相关 from_proj = 'jie'
            serializer = JieProfileSerializer(data=request.data)
            serializer.is_valid(raise_exception=True)
            data = serializer.validated_data
            user_info.update_profile(data, 'jie')
        except:  # user.from_proj = 'dai'， 兼容头像，昵称等场景
            data = request.data.copy()
            user_info.update_profile(data)
        return self.get(request)

# 单一产品 fake 信息
class FakeProfileView(APIView):
    permission_classes = (IsCustomUser,)

    def get(self, request):
        user_id = request.user_id
        user_info = UserInfoMongo(user_id)
        return Response(user_info.fake_profile)

    def post(self, request):
        user_id = request.user_id
        serializer = FakeProfileSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        data = serializer.validated_data
        user_info = UserInfoMongo(user_id)
        user_info.update_fake_profile(data)
        return self.get(request)

# 信用等级页面
class CreditLevelView(APIView):

    permission_classes = (IsCustomUser,)

    def get(self, request):
        user_id = request.user_id
        user_info = UserInfoMongo(user_id)
        auth = user_info.auth
        auth_priority, authx = get_auth_config()
        if authx:
            for a in authx:
                a['auth'] = auth.get(a['type'], 0)
        ret = {
            'user': get_user_base_info_data(user_id),
            'auth_priority': auth_priority,
            'authx': authx
        }
        auth_identification = ret['user'].get('auth', {}).get('identification')
        if auth_identification == 1:
            ret['user']['auth']['identification'] = 10
        return Response(ret)

# 签到
class SignInView(APIView):
    permission_classes = (IsCustomUser,)

    def post(self, request):
        user_id = request.user_id
        user_info = UserInfoMongo(user_id)
        if not user_info.has_signed:
            user_info.sign_in()
            ret = get_user_coin_data(user_id)
            return Response(ret)
        RaiseMessage().has_signed()

# 分享好友
class ShareFriendView(APIView):
    permission_classes = (IsCustomUser,)

    def post(self, request):
        user_id = request.user_id
        user_info = UserInfoMongo(user_id)
        user_info.update_share_friends()
        return Response({})

def user_redbags_view(request):
    context = {'static': STATIC_URL}
    return TemplateResponse(request, 'redbags/index.html', context)

# 我的红包
class UserConponsView(APIView):
    permission_classes = (IsCustomUser,)

    def get(self, request):
        # 用户的券
        user_id = request.user_id
        user_info = UserInfoMongo(user_id)
        ret = {}

        if user_info.is_birthday:
            ret['is_birthday'] = {
                "name": "生日特权大礼包",
                "icon": "https://platplat.oss-cn-shanghai.aliyuncs.com/coupons/icon/birthday_gift.png",
                'event_action': {
                    'link': JIE_DOMAIN + '/misc/stores/coins#/List/?data={"is_birthday":true}&name=生日特权'
                }
            }

        if user_info.is_new_register:
            ret['is_new_register'] = {
                "name": "新人专享大礼包",
                "icon": "https://platplat.oss-cn-shanghai.aliyuncs.com/coupons/icon/new_register.png",
                'event_action': {
                    'link': JIE_DOMAIN + '/misc/stores/coins#/List/?data={"is_new_register":true}&name=新人专享'
                }
            }

        ret['coins_url'] = JIE_DOMAIN + '/misc/stores/coins'

        coupons = user_info.coupons
        validate_coupons = []
        for user_coupon in coupons:
            coupon = user_coupon['coupon']
            validate = CouponTypeValidate(coupon)
            add_id = user_coupon['add_id']
            data_ret = {}

            # 失效时间
            check_coupon_time = validate.check_coupon_time(user_info, user_coupon['user_created'])
            if check_coupon_time['expire'] or user_coupon['use_status'] == USED:
                user_info.delete_coupon(add_id)  # 删除过期券、使用成功券
                continue

            time_effective = check_coupon_time['time_effective'] or '~'
            time_expire = check_coupon_time['time_expire'] or '~'

            bottom_tip = []
            if check_coupon_time['time_effective']:
                bottom_tip.append('开始时间：%s' % time_effective.strftime('%Y-%m-%d %H:%M:%S'))
            if check_coupon_time['time_expire']:
                bottom_tip.append('截止时间：%s' % time_expire.strftime('%Y-%m-%d %H:%M:%S'))
            elif coupon['is_birthday']:
                bottom_tip = bottom_tip.append('生日特权')
            elif coupon['is_new_register']:
                bottom_tip = bottom_tip.append('新人专享')
            else:
                bottom_tip = bottom_tip.append('信用权益')

            # 底部 tip
            data_ret['bottom_tip'] = bottom_tip

            # button
            check_can_use = validate.check_can_use(user_info, user_coupon['user_created'], user_coupon['use_status'])
            data_ret['effective'] = check_can_use['enable']
            data_ret['button_text'] = check_can_use['tip']

            # 面值f
            if coupon['is_credit_coin']:  # 奖励信用币
                show_num = coupon['credit_coin_amount']
                show_unit = '个'
            else:
                show_num = coupon['phone_amount']/100.0
                show_unit = '元'
            data_ret['show_num'] = show_num
            data_ret['show_unit'] = show_unit
            # 红包 UI
            coupon_ret = {
                'name': coupon['name'],
                'icon': coupon['icon']
            }
            data_ret['coupon'] = coupon_ret
            data_ret['add_id'] = user_coupon['add_id']

            validate_coupons.append(data_ret)

        ret['coupons'] = json.loads(MongoJsonEncoder().encode(validate_coupons))
        return Response(ret)

# 删除统计渠道用户接口，改从 es 获取

class IdInfoView(APIView):
    # permission_classes = (IsCustomUser,)

    def post(self, request):
        serializer = UserInfoSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        data = serializer.validated_data

        ret = {}
        # 内网获取身份证信息
        # url_id = MARKET_HOST + '/mobile/idinfo'
        id_info = {}
        try:
            url_id = API_ID_INFO.format(data['identification'])
            r_id = requests.get(url_id, timeout=5)
            id_info = r_id.json()
        except:
            pass

        if id_info:
            ret.update(id_info)

        # 内网获取手机运营商
        # url_number = MARKET_HOST + '/mobile/info/' + data['number']
        url_number = API_PHONE_INFO.format(data['number'])
        number_info = {}
        try:
            r_number = requests.get(url_number, timeout=5)
            number_info = r_number.json()
        except:
            pass

        if number_info:
            ret.update({'phone_type': number_info.get('phone_type')})

        ret['apply_time'] = datetime.now().strftime('%Y/%m/%d %H:%M:%S')
        return Response(ret)

class JuPeiViewSet(ReadOnlyModelViewSet):
    permission_classes = (WhiteListOnly,)
    queryset = JuPei.objects
    serializer_class = FeedbackSerializer

    def _check_ocr_words(self, tags):
        """
        取出mongodb中排序靠前的1000个，计算tags中占比
        :param tags:
        :return:
        """
        return len(tags)

    @list_route(methods=['post'], permission_classes=(IsCustomUser,), url_name='apply')
    def apply(self, request):
        serializer = JuPeiSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        data = serializer.validated_data
        image_url = data['image_url']
        product_id = data['product_id']
        token = request.token_data
        ju, created = JuPei.objects.update_or_create(user_id=token['user_id'], defaults={'number': token['number']})

        try:
            success, words = baidu_word_ocr(image_url)
        except:
            add_log_count('baidu_word_ocr')
            traceback.print_exc()
            success, words = None, None

        if success:
            if words:  # ocr接口调用成功且有文字，通过；ocr接口调用失败也通过
                tags = list(jieba.cut(re.sub(r'[^\u4e00-\u9fa5]', '', words)))
                if tags and self._check_ocr_words(tags):
                    bulk = mongodb.jupei_words.initialize_ordered_bulk_op()
                    for tag in tags:
                        bulk.find({'_id': tag}).upsert().update({'$inc': {'word_count': 1}})
                    bulk.execute()
                else:
                    return Response({'amount_add': 0, 'review': '未通过审核'})
            else:
                return Response({'amount_add': 0, 'review': '未通过审核'})

        amount_add, msg = ju.update_pei(product_id)
        return Response({'amount_add': amount_add, 'review': msg})

    @list_route(methods=['get'], permission_classes=(IsStaffUser,), url_name='words')
    def wordocr(self, request):
        words = mongodb.jupei_words.find(sort=[('word_count', -1)])
        return Response(list(words)[:1000])

    def retrieve(self, request, *args, **kwargs):
        user_id = int(kwargs['pk'])
        instance, created = JuPei.objects.get_or_create(user_id=user_id)
        users = mongodb.users.find_one({'_id': user_id}) or {}
        ret = {
            'amount': instance.amount,
            'send_count': instance.send_count,
            'withdraw': 0,  # 提现金额目前只能为0
            'jupei_applied': users.get('jupei_applied', [])
        }
        return Response(ret)


import os
from os.path import join, exists
import argparse
import torch
import torch.nn as nn
from torch.utils.data import DataLoader, ConcatDataset, random_split
import random
import json

from dataset import Dictionary, VQAFeatureDataset, VisualGenomeFeatureDataset
from dataset import tfidf_from_questions
from dataset_cp_v2 import VQA_cp_Dataset, Image_Feature_Loader
from model.regat import build_regat
from config.parser import parse_with_config
from train import train
import utils
from utils import trim_collate

def parse_args():
    parser = argparse.ArgumentParser()
    '''
    For training logistics
    '''
    parser.add_argument('--epochs', type=int, default=20)
    parser.add_argument('--base_lr', type=float, default=1e-3)
    parser.add_argument('--lr_decay_start', type=int, default=15)
    parser.add_argument('--lr_decay_rate', type=float, default=0.25)
    parser.add_argument('--lr_decay_step', type=int, default=2)
    parser.add_argument('--lr_decay_based_on_val', action='store_true',
                        help='Learning rate decay when val score descreases')
    parser.add_argument('--grad_accu_steps', type=int, default=1)
    parser.add_argument('--grad_clip', type=float, default=0.25)
    parser.add_argument('--weight_decay', type=float, default=0)
    parser.add_argument('--batch_size', type=int, default=64)
    parser.add_argument('--output', type=str, default='saved_models/')
    parser.add_argument('--save_optim', action='store_true',
                        help='save optimizer')
    parser.add_argument('--log_interval', type=int, default=-1,
                        help='Print log for certain steps')
    parser.add_argument('--seed', type=int, default=-1, help='random seed')

    '''
    loading trained models
    '''
    parser.add_argument('--checkpoint', type=str, default="")

    '''
    For dataset
    '''
    parser.add_argument('--dataset', type=str, default='vqa',
                        choices=["vqa", "vqa_cp"])
    parser.add_argument('--data_folder', type=str, default='./data')
    parser.add_argument('--use_both', action='store_true',
                        help='use both train/val datasets to train?')
    parser.add_argument('--use_vg', action='store_true',
                        help='use visual genome dataset to train?')
    parser.add_argument('--adaptive', action='store_true',
                        help='adaptive or fixed number of regions')
    '''
    Model
    '''
    parser.add_argument('--relation_type', type=str, default='implicit',
                        choices=["spatial", "semantic", "implicit"])
    parser.add_argument('--fusion', type=str, default='mutan',
                        choices=["ban", "butd", "mutan"])
    parser.add_argument('--tfidf', action='store_true',
                        help='tfidf word embedding?')
    parser.add_argument('--op', type=str, default='c',
                        help="op used in tfidf word embedding")
    parser.add_argument('--num_hid', type=int, default=1024)
    '''
    Fusion Hyperparamters
    '''
    parser.add_argument('--ban_gamma', type=int, default=1, help='glimpse')
    parser.add_argument('--mutan_gamma', type=int, default=2, help='glimpse')
    '''
    Hyper-params for relations
    '''
    # hyper-parameters for implicit relation
    parser.add_argument('--imp_pos_emb_dim', type=int, default=64,
                        help='geometric embedding feature dim')

    # hyper-parameters for explicit relation
    parser.add_argument('--spa_label_num', type=int, default=11,
                        help='number of edge labels in spatial relation graph')
    parser.add_argument('--sem_label_num', type=int, default=15,
                        help='number of edge labels in \
                              semantic relation graph')

    # shared hyper-parameters
    parser.add_argument('--dir_num', type=int, default=2,
                        help='number of directions in relation graph')
    parser.add_argument('--relation_dim', type=int, default=1024,
                        help='relation feature dim')
    parser.add_argument('--nongt_dim', type=int, default=20,
                        help='number of objects consider relations per image')
    parser.add_argument('--num_heads', type=int, default=16,
                        help='number of attention heads \
                              for multi-head attention')
    parser.add_argument('--num_steps', type=int, default=1,
                        help='number of graph propagation steps')
    parser.add_argument('--residual_connection', action='store_true',
                        help='Enable residual connection in relation encoder')
    parser.add_argument('--label_bias', action='store_true',
                        help='Enable bias term for relation labels \
                              in relation encoder')

    # can use config files
    parser.add_argument('--config', help='JSON config files')

    args = parse_with_config(parser)
    return args

if __name__ == '__main__':
    args = parse_args()
    if not torch.cuda.is_available():
        raise ValueError("CUDA is not available," +
                         "this code currently only support GPU.")
    n_device = torch.cuda.device_count()
    print("Found %d GPU cards for training" % (n_device))
    device = torch.device("cuda")
    batch_size = args.batch_size*n_device

    torch.backends.cudnn.benchmark = True

    if args.seed != -1:
        print("Predefined randam seed %d" % args.seed)
    else:
        # fix seed
        args.seed = random.randint(1, 10000)
        print("Choose random seed %d" % args.seed)
    torch.manual_seed(args.seed)
    torch.cuda.manual_seed_all(args.seed)

    if "ban" == args.fusion:
        fusion_methods = args.fusion+"_"+str(args.ban_gamma)
    else:
        fusion_methods = args.fusion

    dictionary = Dictionary.load_from_file(
                    join(args.data_folder, 'glove/dictionary.pkl'))
    if args.dataset == "vqa_cp":
        coco_train_features = Image_Feature_Loader(
                            'train', args.relation_type,
                            adaptive=args.adaptive, dataroot=args.data_folder)
        coco_val_features = Image_Feature_Loader(
                            'val', args.relation_type,
                            adaptive=args.adaptive, dataroot=args.data_folder)
        val_dset = VQA_cp_Dataset(
                    'test', dictionary, coco_train_features, coco_val_features,
                    adaptive=args.adaptive, pos_emb_dim=args.imp_pos_emb_dim,
                    dataroot=args.data_folder)
        train_dset = VQA_cp_Dataset(
                    'train', dictionary, coco_train_features,
                    coco_val_features, adaptive=args.adaptive,
                    pos_emb_dim=args.imp_pos_emb_dim,
                    dataroot=args.data_folder)
    else:
        val_dset = VQAFeatureDataset(
                'val', dictionary, args.relation_type, adaptive=args.adaptive,
                pos_emb_dim=args.imp_pos_emb_dim, dataroot=args.data_folder)
        train_dset = VQAFeatureDataset(
                'train', dictionary, args.relation_type,
                adaptive=args.adaptive, pos_emb_dim=args.imp_pos_emb_dim,
                dataroot=args.data_folder)

    model = build_regat(val_dset, args).to(device)

    tfidf = None
    weights = None
    if args.tfidf:
        tfidf, weights = tfidf_from_questions(['train', 'val', 'test2015'],
                                              dictionary)
    model.w_emb.init_embedding(join(args.data_folder,
                                    'glove/glove6b_init_300d.npy'),
                               tfidf, weights)

    model = nn.DataParallel(model).to(device)

    if args.checkpoint != "":
        print("Loading weights from %s" % (args.checkpoint))
        if not os.path.exists(args.checkpoint):
            raise ValueError("No such checkpoint exists!")
        checkpoint = torch.load(args.checkpoint)
        state_dict = checkpoint.get('model_state', checkpoint)
        matched_state_dict = {}
        unexpected_keys = set()
        missing_keys = set()
        for name, param in model.named_parameters():
            missing_keys.add(name)
        for key, data in state_dict.items():
            if key in missing_keys:
                matched_state_dict[key] = data
                missing_keys.remove(key)
            else:
                unexpected_keys.add(key)
        print("Unexpected_keys:", list(unexpected_keys))
        print("Missing_keys:", list(missing_keys))
        model.load_state_dict(matched_state_dict, strict=False)

    # use train & val splits to optimize, only available for vqa, not vqa_cp
    if args.use_both and args.dataset == "vqa":
        length = len(val_dset)
        trainval_concat_dset = ConcatDataset([train_dset, val_dset])
        if args.use_vg or args.use_visdial:
            trainval_concat_dsets_split = random_split(
                                trainval_concat_dset,
                                [int(0.2*length),
                                 len(trainval_concat_dset)-int(0.2*length)])
        else:
            trainval_concat_dsets_split = random_split(
                                trainval_concat_dset,
                                [int(0.1*length),
                                 len(trainval_concat_dset)-int(0.1*length)])
        concat_list = [trainval_concat_dsets_split[1]]

        # use a portion of Visual Genome dataset
        if args.use_vg:
            vg_train_dset = VisualGenomeFeatureDataset(
                        'train', train_dset.features, train_dset.normalized_bb,
                        train_dset.bb, train_dset.spatial_adj_matrix,
                        train_dset.semantic_adj_matrix, dictionary,
                        adaptive=train_dset.adaptive,
                        pos_boxes=train_dset.pos_boxes,
                        dataroot=args.data_folder)
            vg_val_dset = VisualGenomeFeatureDataset(
                            'val', val_dset.features, val_dset.normalized_bb,
                            val_dset.bb, val_dset.spatial_adj_matrix,
                            val_dset.semantic_adj_matrix, dictionary,
                            adaptive=val_dset.adaptive,
                            pos_boxes=val_dset.pos_boxes,
                            dataroot=args.data_folder)
            concat_list.append(vg_train_dset)
            concat_list.append(vg_val_dset)
        final_train_dset = ConcatDataset(concat_list)
        final_eval_dset = trainval_concat_dsets_split[0]
        train_loader = DataLoader(final_train_dset, batch_size, shuffle=True,
                                  num_workers=4, collate_fn=trim_collate)
        eval_loader = DataLoader(final_eval_dset, batch_size,
                                 shuffle=False, num_workers=4,
                                 collate_fn=trim_collate)

    else:
        train_loader = DataLoader(train_dset, batch_size, shuffle=True,
                                  num_workers=4, collate_fn=trim_collate)
        eval_loader = DataLoader(val_dset, batch_size, shuffle=False,
                                 num_workers=4, collate_fn=trim_collate)

    output_meta_folder = join(args.output, "regat_%s" % args.relation_type)
    utils.create_dir(output_meta_folder)
    args.output = output_meta_folder+"/%s_%s_%s_%d" % (
                fusion_methods, args.relation_type,
                args.dataset, args.seed)
    if exists(args.output) and os.listdir(args.output):
        raise ValueError("Output directory ({}) already exists and is not "
                         "empty.".format(args.output))
    utils.create_dir(args.output)
    with open(join(args.output, 'hps.json'), 'w') as writer:
        json.dump(vars(args), writer, indent=4)
    logger = utils.Logger(join(args.output, 'log.txt'))

    train(model, train_loader, eval_loader, args, device)


from simulation_studies.simdata import *
import torch
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.neighbors import NearestNeighbors
import numpy as np

def load_data(sim_tag = 'l'):
    if sim_tag == 'l':
        sim_dict = sim_data_low_dim(1000, 100, noise_scale = 0)
        return sim_dict

    if sim_tag == 'h':
        sim_dict = sim_data_high_dim(1000, 100, noise_scale = 0)
        return sim_dict

    if sim_tag == 'c':
        #Import real-world data
        df_all = pd.read_csv('data_all', index_col=0)
        df_unc = pd.read_csv('data_unc', index_col=0)
        df_conf = pd.read_csv('data_conf', index_col=0)

        #Full data
        x_all = df_all.values[:, 2:]
        t_all = df_all['treatment'].values.reshape(-1,1)
        y_all = df_all['outcome'].values.reshape(-1,1)

        #Unconfouded data
        x_unc = df_unc.values[:, 2:]
        t_unc = df_unc['treatment'].values.reshape(-1,1)
        y_unc = df_unc['outcome'].values.reshape(-1,1)

        #Confounded data
        x_conf = df_conf.values[:, 2:]
        t_conf = df_conf['treatment'].values.reshape(-1,1)
        y_conf = df_conf['outcome'].values.reshape(-1,1)

        #Test data
        x_test = x_all
        return {'x_unc': x_unc, 't_unc': t_unc, 'y_unc': y_unc, 'u_unc': u_unc, 'x_conf': x_conf, 't_conf': t_conf, 'y_conf': y_conf, 'u_conf': u_conf, 'x_test': x_test}

#SVC to predict prob of a sample coming from conf data or unc data
def d_score(x_conf, x_unc):
    s_conf = torch.ones(x_conf.size())
    s_unc = torch.zeros(x_unc.size())
    x_cat = torch.cat((x_conf, x_unc))
    s_cat = torch.cat((s_conf, s_unc)).flatten()
    #clf = LogisticRegression().fit(x_cat, s_cat)
    clf = SVC(gamma='auto', probability=True)
    clf.fit(x_cat, s_cat)
    d_score_conf = clf.predict_proba(x_conf)
    d_score_unc = clf.predict_proba(x_unc)

    return [torch.Tensor(d_score_conf[:, 1]), torch.Tensor(d_score_unc[:, 1])]

#Get points in covariate space for MDPM
def points(x_conf, x_unc, d_conf, d_unc):
    i = torch.argmax(torch.abs(d_conf-0.5))
    j = torch.argmax(torch.abs(d_unc-0.5))
    k = torch.argmax(torch.abs(d_unc-d_conf[i]))
    m = torch.argmax(torch.abs(d_conf-d_unc[j]))

    return [i,j,k,m]

#Balancing with middle point distance minimization (MPD)
def MPD(rep_conf, rep_unc, points):
    i, j, k, m = points
    z_i = rep_conf[i]
    z_j = rep_unc[j]
    z_k = rep_unc[k]
    z_m = rep_conf[m]

    return sum(torch.pow((z_i+z_m)/2 - (z_j+z_k)/2, 2))

def data_aug(x, x_uc, alpha):
    n_conf = x.shape[0]
    n_cov = x.shape[1]
    lam = torch.distributions.beta.Beta(torch.tensor(alpha), torch.tensor(alpha)).sample(torch.Size([n_conf])).reshape(-1,1)
    ind = np.random.choice(x_uc.shape[0], n_conf, replace=True)
    x_rand = x_uc[ind]#np.random.choice(x_uc, size=[n_conf, n_cov], replace=True)
    x_inter = lam * x_rand + (1-lam) * x
    z_inter = lam * 0 + (1-lam) * 1
    return [x_inter, z_inter]

def data_aug_within_domain(x, x_uc, alpha):
    n_conf = x.shape[0]
    lam = torch.distributions.beta.Beta(torch.tensor([alpha]), torch.tensor([alpha])).sample(torch.Size([n_conf]))
    x_rand = np.random.choice(x_uc.flatten(), size=[n_conf, 2], replace=True)
    x_inter = lam * x_rand[:, 0].reshape(-1,1) + (1-lam) * x_rand[:, 1].reshape(-1,1)
    z_inter = torch.zeros_like(x_inter)
    x_cat = torch.cat((x_inter, x))
    z_cat = torch.cat((z_inter, torch.ones_like(x)))
    return [x_cat, z_cat]

def data_aug_cross(x, x_uc, alpha):
    n_conf = x.shape[0]
    n_unc = x_uc.shape[0]

    lam = torch.distributions.beta.Beta(torch.tensor([alpha]), torch.tensor([alpha])).sample(torch.Size([n_conf * n_unc]))
    #x_rand = np.random.choice(x_uc.flatten(), size=[n_conf, 1], replace=True)
    x_inter = torch.ones(size=[n_unc * n_conf, 1])
    z_inter = torch.ones(size=[n_unc * n_conf, 1])
    j=0
    for i in range(0, n_unc * n_conf, n_conf):
        x_inter[i:i+n_conf] = lam[i:i+n_conf] * x_uc[j] + (1-lam[i:i+n_conf]) * x
        z_inter[i:i+n_conf] = lam[i:i+n_conf] * 0 + (1-lam[i:i+n_conf]) * 1
        j += 1
    return [x_inter, z_inter]

def data_aug_modi(x, x_uc, alpha):
    n_conf = x.shape[0]
    lam = torch.distributions.beta.Beta(torch.tensor([alpha]), torch.tensor([alpha])).sample(torch.Size([n_conf]))
    lambd = torch.max(lam, 1-lam)
    x_rand = np.random.choice(x_uc.flatten(), size=[n_conf, 1], replace=True)
    x_inter = (1-lambd) * x_rand + lambd * x
    z_inter = (1-lambd) * 0 + lambd * 1
    return [x_inter, z_inter]

def cross_sample_aug(x, x_uc, y, y_uc, t, t_uc, alpha):
    n_conf = x.shape[0]
    lam = torch.distributions.beta.Beta(torch.tensor([alpha]), torch.tensor([alpha])).sample(torch.Size([n_conf]))

    x_1 = x[t.flatten() == 1, :]
    x_0 = x[t.flatten() == 0, :]

    y_1 = y[t.flatten() == 1, :]
    y_0 = y[t.flatten() == 0, :]

    x_uc_1 = x_uc[t_uc.flatten() == 1, :]
    x_uc_0 = x_uc[t_uc.flatten() == 0, :]

    y_uc_1 = y_uc[t_uc.flatten() == 1, :]
    y_uc_0 = y_uc[t_uc.flatten() == 0, :]

    ind_rand_1 = np.random.choice(range(x_uc_1.shape[0]), size=[x_1.shape[0], 1], replace=True)
    ind_rand_0 = np.random.choice(range(x_uc_0.shape[0]), size=[x_0.shape[0], 1], replace=True)

    x_rand_1 = x_uc_1[ind_rand_1.flatten(), :]
    x_rand_0 = x_uc_0[ind_rand_0.flatten(), :]

    y_rand_1 = y_uc_1[ind_rand_1.flatten(), :]
    y_rand_0 = y_uc_0[ind_rand_0.flatten(), :]

    x_inter = lam * torch.cat((x_rand_1, x_rand_0)) + (1-lam) * torch.cat((x_1, x_0))
    z_inter = lam * 0 + (1-lam) * 1
    y_inter = lam * torch.cat((y_rand_1, y_rand_0)) + (1-lam) * torch.cat((y_1, y_0))
    t_inter = torch.cat((torch.ones_like(y_1), torch.zeros_like(y_0)))
    return [x_inter, z_inter, y_inter, t_inter]

def pseudo_pehe(x, t, y, cate_hat):
    x_t = x[(t == 1).flatten(), :]
    x_c = x[(t == 0).flatten(), :]

    nbrs_treatment = NearestNeighbors(n_neighbors=1, algorithm='ball_tree').fit(x_t)
    nbrs_control = NearestNeighbors(n_neighbors=1, algorithm='ball_tree').fit(x_c)

    dist_t, ind_t = nbrs_treatment.kneighbors(x)
    dist_c, ind_c = nbrs_control.kneighbors(x)

    y_t, y_c = y[ind_t.flatten()].reshape(-1,1), y[ind_c.flatten()].reshape(-1,1)
    pseudo_cate = y_t - y_c

    return ((pseudo_cate - cate_hat)**2).mean()

def pseudo_cate(x, t, y, x_a, t_a, y_a):
    x_t = x_a[(t_a == 1).flatten(), :]
    x_c = x_a[(t_a == 0).flatten(), :]

    nbrs_treatment = NearestNeighbors(n_neighbors=1, algorithm='auto').fit(x_t)
    nbrs_control = NearestNeighbors(n_neighbors=1, algorithm='auto').fit(x_c)

    dist_t, ind_t = nbrs_treatment.kneighbors(x)
    dist_c, ind_c = nbrs_control.kneighbors(x)

    y_t, y_c = np.zeros_like(y), np.zeros_like(y)
    for i in range(x.shape[0]):
       if t[i] == 1:
           y_t[i] = y[i]
           y_c[i] = y_a[(t_a == 0).flatten()][ind_c[i]]
       else:
           y_c[i] = y[i]
           y_t[i] = y_a[(t_a == 1).flatten()][ind_t[i]]

    pseudo_cate = y_t - y_c

    return pseudo_cate

class EarlyStopping():
    """
    Early stopping to stop the training when the loss does not improve after
    certain epochs.
    """
    def __init__(self, patience=15, min_delta=0.001):
        """
        :param patience: how many epochs to wait before stopping when loss is
               not improving
        :param min_delta: minimum difference between new loss and old loss for
               new loss to be considered as an improvement
        """
        self.patience = patience
        self.min_delta = min_delta
        self.counter = 0
        self.best_loss = None
        self.early_stop = False
    def __call__(self, val_loss):
        if self.best_loss == None:
            self.best_loss = val_loss
        elif self.best_loss - val_loss > self.min_delta:
            self.best_loss = val_loss
            self.counter = 0 #Reset counter
        elif self.best_loss - val_loss < self.min_delta:
            self.counter += 1
            #print(f"INFO: Early stopping counter {self.counter} of {self.patience}")
            if self.counter >= self.patience:
                print('INFO: Early stopping')
                self.early_stop = True


# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

from marionette_driver import errors, Wait
from marionette_harness import MarionetteTestCase

class TestWindowless(MarionetteTestCase):
    def setUp(self):
        super(TestWindowless, self).setUp()

        self.marionette.delete_session()
        self.marionette.start_session({"moz:windowless": True})

    def tearDown(self):
        # Reset the browser and active WebDriver session
        self.marionette.restart(in_app=True)
        self.marionette.delete_session()

        super(TestWindowless, self).tearDown()

    def test_last_chrome_window_can_be_closed(self):
        with self.marionette.using_context("chrome"):
            handles = self.marionette.chrome_window_handles
            self.assertGreater(len(handles), 0)
            self.marionette.switch_to_window(handles[0])
            self.marionette.close_chrome_window()
            self.assertEqual(len(self.marionette.chrome_window_handles), 0)

    def test_last_content_window_can_be_closed(self):
        handles = self.marionette.window_handles
        self.assertGreater(len(handles), 0)
        self.marionette.switch_to_window(handles[0])
        self.marionette.close()
        self.assertEqual(len(self.marionette.window_handles), 0)

    def test_no_window_handles_after_silent_restart(self):
        # Check that windows are present, but not after a silent restart
        handles = self.marionette.window_handles
        self.assertGreater(len(handles), 0)

        self.marionette.restart(silent=True)
        with self.assertRaises(errors.TimeoutException):
            wait = Wait(
                self.marionette,
                ignored_exceptions=errors.NoSuchWindowException,
                timeout=5,
            )
            wait.until(lambda _: self.marionette.window_handles)

        # After a normal restart a browser window will be opened again
        self.marionette.restart(in_app=True)
        handles = self.marionette.window_handles
        self.assertGreater(len(handles), 0)
        self.marionette.switch_to_window(handles[0])


import xml.etree.ElementTree as ET
import os
import subprocess
from storage_controllers.common import exceptions

def _check_initialised(func):
    def check_id(self, *args, **kwargs):
        if hasattr(self, 'id'):
            return func(self, *args, **kwargs)
        else:
            raise exceptions.ControllerError('Not initialised')
    return check_id

def run(cmd, args):
    commands = ['omconfig', 'omreport']
    basepath = "/opt/dell/srvadmin/bin"
    binaries = {x: os.path.join(basepath, x) for x in commands}
    for f in binaries.values():
        if not os.access(f, os.X_OK):
            raise OSError(os.errno.ENOEXEC)
    cmd = [binaries[cmd]]
    cmd.extend(args.split(' '))
    cmd.extend(['-fmt', 'xml'])
    output = subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0]
    if "Error! User has insufficient privileges to run command." in output:
        raise exceptions.ControllerError("Not enough privileges to perform "
                                         "this operation. Are you root?")
    return ET.fromstring(output.strip())

def get_controllers():
    """
    Returns a list of perc controllers instances for this server

    :param controller_id: The id of the requested controller.
    """
    res = run('omreport', 'storage controller')
    if res.find('Controllers') is None:
        raise exceptions.ControllerError("Unable to retrieve "
                                         "controller information")
    controllers = res.find('Controllers')
    ids = [controller.find('ControllerNum').text for controller in controllers]
    return [Controller(x) for x in ids]

def get_logical_drive(name):
    """
    Returns a logical drive instance given the name.

    :param name: The logical drive name. Es: c2u35.
    :returns: A LogicalDrive instance for that name.
    """
    controller_id, logical_drive_id = name.strip('c').split('u')
    return LogicalDrive(controller_id, logical_drive_id)

def get_physical_drive(controller_id, physical_drive_id):
    """
    Returns a physical drive instance given the coordinates.

    :param controller_id: The controller where this physical drive is attached to.
    :param physical_drive_id: The id of the physical drive.
    :returns: A PhysicalDrive instance.
    """
    return PhysicalDrive(controller_id, physical_drive_id)

def _check_exit_code(result, error):
    '''
    Check the exit code from the xml output of an omconfig command

    :param result: The xml output
    :param error: The error to return in case something went wrong
    '''
    if (not len(result.findall('CustomStat')) or
            result.find('CustomStat').text != '0'):
        raise exceptions.ControllerError(error)

def _parse_logical_drive(xml_input, logical_drive):
    """
    Parse the xml returned by the omreport command and assign attributes to
    a logical drive object.

    :param xml_input: The xml to parse.
    :param logical_drive: The logical drive object to act on.
    """
    logical_drive.id = xml_input.find('LogicalDriveNum').text
    logical_drive.device_path = xml_input.find('DeviceName').text

    status_mapping = {
        '2': "Online",
        '4': "Failed"
    }
    logical_drive.status = status_mapping[xml_input.find('ObjStatus').text]

    raid_mapping = {
        '2': "RAID-0",
        '4': "RAID-1"
    }
    logical_drive.type = raid_mapping[xml_input.find('Layout').text]

    return logical_drive

def _parse_physical_drive(xml_input, physical_drive):
    """
    Parse the xml returned by the omreport command and assign attributes to
    a physical drive object.

    :param xml_input: The xml to parse.
    :param physical_drive: The physical drive object to act on.
    """
    physical_drive.id = '{0}:0:{1}'.format(xml_input.find('Channel').text,
                        xml_input.find('TargetID').text)
    physical_drive.firmware = xml_input.find('Revision').text
    # For some reason the perc controller reports size in decimal, not binary
    physical_drive.size = int(xml_input.find('Length').text) / 1000000000000
    physical_drive.model = xml_input.find('ProductID').text
    physical_drive.serial = xml_input.find('DeviceSerialNumber').text

    state_mapping = {
        '1': "Ready",
        '2': "Failed",
        '4': "Online"
    }
    physical_drive.state = state_mapping[xml_input.find('ObjState').text]

    status_mapping = {
        '2': "Ok",  # Ok
        '3': "Non-Critical",  # Non-Critical
        '4': "Failed"
    }
    physical_drive.status = status_mapping[xml_input.find('ObjStatus').text]

    return physical_drive

class Controller():
    def __init__(self, controller_id):
        """
        Runs a single big command to fetch all the information for this controller.
        It's up to each method to digest its output.

        :param controller_id: The controller id
        """
        self.controller_id = controller_id
        res = run('omreport', 'storage controller controller={0}'.format(
                  self.controller_id))
        if res.find('Controllers') is None:
            raise exceptions.ControllerError("Unable to retrieve controller "
                                       "information for controller {0}".format(
                                       self.controller_id))
        self.controller_info = res.find('Controllers')[0]

    def get_info(self):
        '''
        Returns dict with: pci id, model, firmware, status
        '''
        return {
            'firmware': self.controller_info.find('FirmwareVer').text,
            'id': self.controller_id,
            'model': self.controller_info.find('Name').text,
            'pci_id': self.controller_info.find('PciID').text,
            'slot': self.controller_info.find('PCISlot').text
        }

    def get_logical_drives(self):
        '''
        Scan the controller and return a list of LogicalDrive instances.
        '''
        res = run('omreport', 'storage vdisk controller={0}'.format(self.controller_id))
        if res.find('VirtualDisks') is None:
            raise exceptions.ControllerError("Unable to retrieve logical drives "
                                       "information for controller {0}".format(
                                       self.controller_id))
        logical_drives = []
        for entry in res.find('VirtualDisks'):
            logical_drive = _parse_logical_drive(entry, LogicalDrive())
            logical_drive.controller_id = self.controller_id
            logical_drive.name = 'c{0}u{1}'.format(self.controller_id,
                                                   logical_drive.id)
            logical_drives.append(logical_drive)
        return logical_drives

    def get_physical_drives(self):
        '''
        Scan the controller and return a list of PhysicalDrive instances.
        '''
        res = run('omreport', 'storage pdisk controller={0}'.format(
                  self.controller_id))
        if res.find('ArrayDisks') is None:
            raise exceptions.ControllerError("Unable to retrieve physical drives "
                                       "information for controller {0}".format(
                                       self.controller_id))
        physical_drives = []
        for entry in res.find('ArrayDisks'):
            physical_drive = _parse_physical_drive(entry, PhysicalDrive())
            physical_drive.controller_id = self.controller_id
            physical_drives.append(physical_drive)
        return physical_drives

    def create_logical_drive(self, physical_drive):
        """
        Create a new logical drive.
        """
        # Get the list of vdisk ids currently configured on the controller.
        # This is horrible, but it's the only way I can get the vdisk id
        # after its creation. The omconfig command only returns the exit code,
        # nothing else, and there's no way to get the vdisk starting from the
        # pdisk. This is so prone to bugs.
        before_ids = [x.id for x in iter(self.get_logical_drives())]
        # Create the vdisk
        # TODO: Get the options line from the config, with specific options
        #       for each controller. Useful for multiple Perc controllers
        #       dealing with storage drives and OS drives.
        res = run('omconfig', 'storage controller controller={0} '
                  'action=createvdisk pdisk={1} raid=r0 size=max '
                  'stripesize=64kb diskcachepolicy=disabled readpolicy=ara '
                  'writepolicy=wb'.format(self.controller_id, physical_drive))
        _check_exit_code(res, "Failed to create a logical drive on controller "
                         "{0} with physical drives {1}".format(
                         self.controller_id, physical_drive))
        # Now let's get the list again to find the new id.
        after_ids = [x.id for x in iter(self.get_logical_drives())]
        new_vdisk_ids = set(after_ids).difference(set(before_ids))
        if len(new_vdisk_ids) != 1:
            raise base.ControllerError('Problem after creating a vdisk for '
                                       'physical drives {0}: cannot compute '
                                       'the new vdisk id'.format(physical_drive))
        else:
            new_vdisk_id = new_vdisk_ids.pop()
        return LogicalDrive(self.controller_id, new_vdisk_id).get_info()

    def clear_foreign_config(self):
        """
        Wipe out the foreign config.

        :return: A boolean with the result.
        """
        res = run('omconfig', 'storage controller controller={0} '
                  'action=clearforeignconfig'.format(self.controller_id))
        _check_exit_code(res, "Failed to clear the foreign config on"
                              "controller {0}".format(self.controller_id))
        return True

class LogicalDrive():
    def __init__(self, controller_id=None, vdisk_id=None):
        """
        None decides if the instance should be manually or automatically
        populated.

        :param controller_id: The controller id
        :param vdisk_id: The vdisk id
        """
        if (controller_id is not None and vdisk_id is not None):
            res = run('omreport', 'storage vdisk controller={0} vdisk={1}'.format(
                      controller_id, vdisk_id))
            if res.find('VirtualDisks') is None:
                raise exceptions.ControllerError("Unable to retrieve information for "
                                           "logical drive {0} on controller "
                                           "{1}".format(vdisk_id,
                                           controller_id))
            entry = res.find('VirtualDisks')[0]
            self = _parse_logical_drive(entry, self)
            self.controller_id = controller_id
            self.id = vdisk_id
            self.name = 'c{0}u{1}'.format(self.controller_id, self.id)

    @_check_initialised
    def get_info(self):
        '''
        Returns a dict with: type, device_name, status
        '''
        return {
            'controller_id': self.controller_id,
            'device_path': self.device_path,
            'id': self.id,
            'name': self.name,
            'physical_drives': [a.id for a in self.get_physical_drives()],
            'status': self.status,
            'type': self.type
        }

    @_check_initialised
    def get_physical_drives(self):
        '''
        Return a list of PhysicalDrive instances that form the logcal drive.
        '''
        # Find out what physical drive is being used by a logical drive
        res = run('omreport', 'storage pdisk controller={0} '
                  'vdisk={1}'.format(self.controller_id, self.id))
        if res.find('ArrayDisks') is None:
            raise exceptions.ControllerError("Unable to find which "
                                             "physical drive is being "
                                             "used by logical drive {0} "
                                             "on controller {1}".format(
                                             self.id, self.controller_id))
        physical_drives = []
        for entry in res.find('ArrayDisks'):
            physical_drive = _parse_physical_drive(entry, PhysicalDrive())
            physical_drives.append(physical_drive)
        return physical_drives

    @_check_initialised
    def delete(self):
        '''
        Delete the logical drive.

        :return: The information for the logical drive that just got deleted.
        '''
        info = self.get_info()
        res = run("omconfig", "storage vdisk controller={0} vdisk={1} "
                  "action=deletevdisk".format(self.controller_id,
                  self.id))
        _check_exit_code(res, "Failed to delete logical drive {0} on "
                              "controller {0}".format(self.controller_id,
                              self.id))
        info['status'] = 'Successfully removed'
        return info

class PhysicalDrive():
    def __init__(self, controller_id=None, pdisk_id=None):
        """
        Decide if the instance should be manually or automatically populated

        :param controller_id: The controller id
        :param pdisk_id: The pdisk id (usually something like 1:0:23)
        """
        if (controller_id is not None and pdisk_id is not None):
            res = run('omreport', 'storage pdisk controller={0} pdisk={1}'.format(
                      controller_id, pdisk_id))
            if res.find('ArrayDisks') is None:
                raise exceptions.ControllerError("Unable to retrieve information for "
                                           "physical drive {0} on controller "
                                           "{1}".format(pdisk_id, controller_id))
            entry = res.find('ArrayDisks')[0]
            self = _parse_physical_drive(entry, self)
            self.controller_id = controller_id
            self.id = pdisk_id

    @_check_initialised
    def get_info(self):
        '''
        Returns dict with: status, size, manufacturer, model, serial
        '''
        return {
            'controller_id': self.controller_id,
            'firmware': self.firmware,
            'id': self.id,
            'model': self.model,
            'serial': self.serial,
            'size': self.size,
            'state': self.state,
            'status': self.status
        }

    @_check_initialised
    def blink_led(self):
        '''
        Switch on the drive bay light, and returns success bool
        '''
        res = run('omconfig', 'storage pdisk action=blink controller={0} '
                  'pdisk={1}'.format(self.controller_id, self.id))
        _check_exit_code(res, "Unable to switch on the indicator LED for "
                              "physical drive {0} on controller {1}".format(
                              self.id, self.controller_id))
        return True

    @_check_initialised
    def unblink_led(self):
        '''
        Switch off the drive bay light, and returns success bool
        '''
        res = run('omconfig', 'storage pdisk action=unblink controller={0} '
                  'pdisk={1}'.format(self.controller_id, self.id))
        _check_exit_code(res, "Unable to switch off the indicator LED for "
                              "physical drive {0} on controller {1}".format(
                              self.id, self.controller_id))
        return True


__author__ = 'George Stepiko'

import pytest
from helpers import *
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec

browsers_to_test = (
    'chrome',
    'ie',
    'firefox',
    'firefox_nght',
    'jeegurda'   # just to check incorrect browser option
)

def test_example(my_driver):
    driver = my_driver()
    driver.get("http://www.google.com/")
    driver.find_element_by_name("q").send_keys("webdriver")
    driver.find_element_by_name("btnK").click()
    WebDriverWait(driver, 10).until(ec.title_is("webdriver - Google Search"))

@pytest.mark.parametrize('brsr', browsers_to_test,
                         ids=browsers_to_test)
def test_login(my_driver, brsr):                               # no checks as while during task 3
    driver = my_driver(brsr)
    driver.get('http://localhost/litecart/admin')
    login(wd=driver)


# -*- coding: utf-8 -*-
r"""Plot visit output

This exports:

  -

This depends on:

  -
Examples of usage:

  - default usage:

        python -m

descriptions
"""
import numpy as np
import sys, os, argparse
# import pathlib
import numpy as np
import shilofue.ParsePrm as ParsePrm
import shilofue.PlotVisit as PlotVisit

# directory to the aspect Lab
ASPECT_LAB_DIR = os.environ['ASPECT_LAB_DIR']
RESULT_DIR = os.path.join(ASPECT_LAB_DIR, 'results')
# directory to shilofue
shilofue_DIR = os.path.join(ASPECT_LAB_DIR, 'shilofue')

sys.path.append(os.path.join(ASPECT_LAB_DIR, 'utilities', "python_scripts"))
import Utilities

def Usage():
    print("\
Visualization with visit\n\
\n\
Examples of usage: \n\
\n\
  - translate script: \n\
\n\
        python -m shilofue.TwoDSubduction0.PlotVisit visit_options -i $TwoDSubduction_DIR/latent_heat_issue/cookbook_latent-heat -sr temperature.py\n\
            -sr: the relative path under the visit_script folder\n\
\n\
  - run script: \n\
        python -m shilofue.TwoDSubduction0.PlotVisit run -i $TwoDSubduction_DIR/non_linear34/eba_low_tol_newton_shift_CFL0.8/visit_scripts/slab.py\n\
\n\
  - run vtk scripts: \n\
        python -m shilofue.TwoDSubduction0.PlotVisit vtk_options -i /home/lochy/ASPECT_PROJECT/TwoDSubduction/non_linear34/eba_low_tol_newton_shift_CFL0.8_lh -p TwoDSubduction_MOW -s 25\n\
            -p operations, available operations are: \n\
                TwoDSubduction_MOW: pull out tentative MOW from temperature: \n\
                TwoDSubduction_SlabAnalysis: analyze slab morphology: \n\
        ")

class VISIT_OPTIONS(PlotVisit.VISIT_OPTIONS):
    """
    parse .prm file to a option file that bash can easily read
    """
    def Interpret(self, **kwargs):
        """
        Interpret the inputs, to be reloaded in children
        kwargs: options
            last_step(list): plot the last few steps
        """
        # call function from parent
        PlotVisit.VISIT_OPTIONS.Interpret(self, **kwargs)

        # default settings
        self.options['IF_PLOT_SHALLOW'] = kwargs.get('if_plot_shallow', "False") # plot the shallow part of the slab.
        self.options['IF_EXPORT_SLAB_MORPH'] = 'False'
        self.options['IF_PLOT_SLAB'] = 'True'
        self.options['GLOBAL_UPPER_MANTLE_VIEW_BOX'] = 0.0
        self.options['ROTATION_ANGLE'] = 0.0
        # try using the value for the background
        try:
            self.options['ETA_MIN'] =\
                Utilities.string2list(self.idict['Material model']['Visco Plastic TwoD']['Minimum viscosity'], float)[0]
        except ValueError:
            eta_min_inputs =\
                ParsePrm.COMPOSITION(self.idict['Material model']['Visco Plastic TwoD']['Minimum viscosity'])
            self.options['ETA_MIN'] = eta_min_inputs.data['background'][0] # use phases
        try:
            self.options['ETA_MAX'] =\
                Utilities.string2list(self.idict['Material model']['Visco Plastic TwoD']['Maximum viscosity'], float)[0]
        except ValueError:
            eta_max_inputs =\
                ParsePrm.COMPOSITION(self.idict['Material model']['Visco Plastic TwoD']['Maximum viscosity'])
            self.options['ETA_MAX'] = eta_max_inputs.data['background'][0] # use phases
        # self.options['IF_DEFORM_MECHANISM'] = value.get('deform_mechanism', 0)
        self.options['IF_DEFORM_MECHANISM'] = 1
        # rotation of the domain
        if self.options['GEOMETRY'] == 'chunk':
            try:
                index = ParsePrm.FindWBFeatures(self.wb_dict, 'Subducting plate')
            except KeyError:
                # either there is no wb file found, or the feature 'Subducting plate' is not defined
                rotation_angle = 52.0
            else:
                # rotate to center on the slab
                feature_sp = self.wb_dict['features'][index]
                rotation_angle = 90.0 - feature_sp["coordinates"][2][0] - 2.0
            self.options['ROTATION_ANGLE'] = rotation_angle
        elif self.options['GEOMETRY'] == 'box':
            try:
                index = ParsePrm.FindWBFeatures(self.wb_dict, 'Subducting plate')
            except KeyError:
                # either there is no wb file found, or the feature 'Subducting plate' is not defined
                trench_x = 4e6
            else:
                # reset the view point
                feature_sp = self.wb_dict['features'][index]
                trench_x = feature_sp["coordinates"][2][0]
            window_width = 1.8e6
            self.options['GLOBAL_UPPER_MANTLE_VIEW_BOX'] =\
            "(%.4e, %.4e, 1.9e6, 2.9e6)" % (trench_x - window_width/2.0, trench_x + window_width/2.0)
        else:
            raise ValueError("Geometry should be \"chunk\" or \"box\"")
        # Slab configuration
        index = ParsePrm.FindWBFeatures(self.wb_dict, 'Subducting plate')
        feature_sp = self.wb_dict['features'][index]
        self.options["INITIAL_SHEAR_ZONE_THICKNESS"] = feature_sp["composition models"][0]["max depth"]

        # peierls rheology
        try:
            include_peierls_rheology = self.idict['Material model']['Visco Plastic TwoD']['Include Peierls creep']
            if include_peierls_rheology == 'true':
                self.options['INCLUDE_PEIERLS_RHEOLOGY'] = True
            else:
                self.options['INCLUDE_PEIERLS_RHEOLOGY'] = False
        except KeyError:
            self.options['INCLUDE_PEIERLS_RHEOLOGY'] = False

    def vtk_options(self, **kwargs):
        '''
        options of vtk scripts
        '''
        # call function from parent
        PlotVisit.VISIT_OPTIONS.vtk_options(self, **kwargs)
        # reference trench point
        self.options['THETA_REF_TRENCH'] = 0.0  # initial value
        if self.options['GEOMETRY'] == 'chunk':
            try:
                index = ParsePrm.FindWBFeatures(self.wb_dict, 'Subducting plate')
            except KeyError:
                # either there is no wb file found, or the feature 'Subducting plate' is not defined
                theta_ref_trench = 0.63
            else:
                # rotate to center on the slab
                feature_sp = self.wb_dict['features'][index]
                theta_ref_trench = feature_sp["coordinates"][2][0] / 180.0 * np.pi
        elif self.options['GEOMETRY'] == 'box':
            try:
                index = ParsePrm.FindWBFeatures(self.wb_dict, 'Subducting plate')
            except KeyError:
                # either there is no wb file found, or the feature 'Subducting plate' is not defined
                # for the box geometry, this is the x distance of the trench
                theta_ref_trench = 4000000.0
            else:
                # rotate to center on the slab
                feature_sp = self.wb_dict['features'][index]
                theta_ref_trench = feature_sp["coordinates"][2][0]
        else:
            raise ValueError("Value of geometry must be either \"chunk\" or \"box\"")
        self.options['THETA_REF_TRENCH'] = theta_ref_trench

    def get_snaps_for_slab_morphology(self, **kwargs):
        '''
        get the snaps for processing slab morphology
        kwargs (dict):
            time_interval (float)
        '''
        ptime_start = kwargs.get('time_start', None)
        ptime_interval = kwargs.get('time_interval', None)
        ptime_end = kwargs.get('time_end', None)
        assert(ptime_interval is None or type(ptime_interval) == float)
        # steps for processing slab morphology
        snaps, times, _ = PlotVisit.GetSnapsSteps(self._case_dir, 'graphical')
        psnaps = []
        ptimes = []
        last_time = -1e8  # initiate as a small value, so first step is included
        # loop within all the available steps, find steps satisfying the time interval requirement.
        for i in range(len(times)):
            time = times[i]
            snap = snaps[i]
            if ptime_start is not None and time < ptime_start:
                # check on the start
                continue
            if ptime_end is not None and time > ptime_end:
                # check on the end
                break
            if type(ptime_interval) == float:
                if (time - last_time) < ptime_interval:
                    continue  # continue if interval is not reached
            pvtu_file_path = os.path.join(self.options["DATA_OUTPUT_DIR"], "solution", "solution-%05d.pvtu" % snap)
            if os.path.isfile(pvtu_file_path):
                # append if the file is found
                last_time = time
                psnaps.append(snap)
                ptimes.append(time)
        return psnaps

class PREPARE_RESULT_OPTIONS(PlotVisit.PREPARE_RESULT_OPTIONS):
    """
    parse .prm file to a option file that bash can easily read
    """
    def Interpret(self, **kwargs):
        """
        Interpret the inputs, to be reloaded in children
        kwargs: options
        """
        # call function from parent
        PlotVisit.PREPARE_RESULT_OPTIONS.Interpret(self, **kwargs)

def main():
    '''
    main function of this module
    Inputs:
        sys.arg[1](str):
            commend
        sys.arg[2, :](str):
            options
    '''
    _commend = sys.argv[1]
    # parse options
    parser = argparse.ArgumentParser(description='Parse parameters')
    parser.add_argument('-i', '--inputs', type=str,
                        default='',
                        help='Some inputs')
    parser.add_argument('-sr', '--script', type=str,
                        default='temperature.py',
                        help='script')
    parser.add_argument('-j', '--json_file', type=str,
                        default='./config_case.json',
                        help='Filename for json file')
    parser.add_argument('-p', '--operation', type=str,
                        default='',
                        help='operation to take')
    parser.add_argument('-s', '--step', type=int,
                        default='0',
                        help='step')
    parser.add_argument('-ls', '--last_step', type=bool,
                        default=False,
                        help='Only plot last step (bool value)')
    _options = []
    try:
        _options = sys.argv[2: ]
    except IndexError:
        pass
    arg = parser.parse_args(_options)

    # commands
    if _commend in ['-h', '--help']:
        # example:
        Usage()

    elif _commend == 'visit_options':
        # output bash options to a file that could be
        # read by bash script
        # initiate class object
        case_dir = arg.inputs
        Visit_Options = VISIT_OPTIONS(case_dir)
        # call function
        Visit_Options.Interpret()
        # ofile = os.path.join('visit_scripts', 'slab_sph.py')
        ofile = os.path.join('visit_scripts', os.path.basename(arg.script))
        visit_script = os.path.join(ASPECT_LAB_DIR, 'visit_scripts', arg.script)
        visit_base_script = os.path.join(ASPECT_LAB_DIR, 'visit_scripts', 'base.py')  # base.py : base file
        Visit_Options.read_contents(visit_base_script, visit_script)  # this part combines two scripts
        Visit_Options.substitute()  # substitute keys in these combined file with values determined by Interpret() function
        ofile_path = Visit_Options.save(ofile, relative=True)  # save the altered script
        pass

    elif _commend == 'vtk_options':
        vtk_option_path, _, _ = PlotVisit.PrepareVTKOptions(VISIT_OPTIONS, arg.inputs, arg.operation, step=arg.step)
        PlotVisit.RunVTKScripts(arg.operation, vtk_option_path)

    elif _commend == 'run':
        PlotVisit.RunScripts(arg.inputs)

    else:
        # no such option, give an error message
        raise ValueError('No commend called %s, please run -h for help messages' % _commend)

# run script
if __name__ == '__main__':
    main()


import dataclasses
import json
import logging
import os
from enum import Enum
from random import choice
from time import sleep

import typer
from rich.console import Console
from rich.logging import RichHandler
from rich.table import Table

from chronus import version
from chronus.application.benchmark_service import BenchmarkService
from chronus.application.init_model_service import InitModelService
from chronus.application.load_model_service import LoadModelService
from chronus.application.run_model_service import RunModelService
from chronus.domain.configuration import Configuration
from chronus.domain.interfaces.optimizer_interface import OptimizerInterface
from chronus.domain.interfaces.repository_interface import RepositoryInterface
from chronus.domain.interfaces.settings_interface import Permission
from chronus.SystemIntegration.application_runners.hpcg import HpcgService
from chronus.SystemIntegration.cpu_info_services.cpu_info_service import LsCpuInfoService
from chronus.SystemIntegration.optimizers.bruteforce_optmizer import BruteForceOptimizer
from chronus.SystemIntegration.optimizers.linear_regression import LinearRegressionOptimizer
from chronus.SystemIntegration.optimizers.random_tree_forrest import RandomTreeOptimizer
from chronus.SystemIntegration.repositories.sqlite_repository import SqliteRepository
from chronus.SystemIntegration.settings_interface.etc_storage import EtcLocalStorage
from chronus.SystemIntegration.system_service_interfaces.ipmi_system_service import (
    IpmiSystemService,
)

name = "chronus"

class Color(str, Enum):
    white = "white"
    red = "red"
    cyan = "cyan"
    magenta = "magenta"
    yellow = "yellow"
    green = "green"

class FileWithTimeStampHandlerAndLevel(logging.FileHandler):
    def emit(self, record: logging.LogRecord) -> None:
        from datetime import datetime

        record.msg = f"[{datetime.now().strftime('%H:%M:%S')}] {record.levelname: <7} {record.msg}"
        super().emit(record)

console = Console()
FORMAT = "%(message)s"
logging.basicConfig(
    level="INFO",
    format=FORMAT,
    datefmt="[%X]",
    handlers=[RichHandler(), FileWithTimeStampHandlerAndLevel("chronus.log")],
)

app = typer.Typer(
    name=name,
    help="A energy scheduling model, build for HPC.",
    add_completion=True,
)

def version_callback(print_version: bool) -> None:
    """Print the version of the package."""
    version_string = (
        "\x1B[38;2;63;81;177mc\x1B[39m\x1B[38;2;90;85;174mh\x1B[39m\x1B[38;2;123;95;172mr\x1B[39m\x1B["
        "38;2;133;101;173mo\x1B[39m\x1B[38;2;143;106;174mn\x1B[39m\x1B[38;2;156;106;169mu\x1B[39m\x1B["
        "38;2;168;106;164ms\x1B[39m \x1B[38;2;186;107;153mv\x1B[39m\x1B[38;2;204;107;142me\x1B[39m\x1B["
        "38;2;223;119;128mr\x1B[39m\x1B[38;2;241;130;113ms\x1B[39m\x1B[38;2;242;147;109mi\x1B[39m\x1B["
        "38;2;243;164;105mo\x1B[39m\x1B[38;2;245;183;113mn\x1B[39m\x1B[38;2;247;201;120m:\x1B[39m"
    )

    if print_version:
        print(version_string + "\x1B[38;2;247;201;120m" + version + "\x1B[39m")
        raise typer.Exit()

class Config:
    frequency_max: int = 3_600_000
    frequency_min: int = 1_000_000
    frequency_step: int = 100_000
    frequency_default: int = 2_400_000
    cores_max: int = 128
    cores_min: int = 1
    cores_step: int = 1
    cores_default: int = 1
    fan_speed_max: int = 10_000
    fan_speed_min: int = 1_000
    fan_speed_step: int = 1_000
    fan_speed_default: int = 1_000

class StandardConfig:
    """Standard configuration for the suite."""

    def __init__(self):
        self._color = choice(list(Color))

    def __iter__(self):
        return range(2).__iter__()

    def color(self) -> str:
        """Get the color of the suite."""
        return self._color

FORMAT = "%(message)s"
logging.basicConfig(level="INFO", format=FORMAT, datefmt="[%X]", handlers=[RichHandler()])
logger = logging.getLogger("main")

@app.callback()
def main(
    print_version: bool = typer.Option(
        None,
        "-v",
        "--version",
        callback=version_callback,
        is_eager=True,
        help="Prints the version of the chronus package.",
    ),
    debug: bool = typer.Option(
        False,
        "--debug",
        help="Print debug information to logs.",
    ),
) -> None:
    if debug:
        logger.setLevel(logging.DEBUG)

class Model(str, Enum):
    brute_force = BruteForceOptimizer.name()
    linear_regression = LinearRegressionOptimizer.name()
    random_tree = RandomTreeOptimizer.name()

def _choose_optimizer(model: str) -> OptimizerInterface:
    switcher = {
        BruteForceOptimizer.name(): BruteForceOptimizer(),
        LinearRegressionOptimizer.name(): LinearRegressionOptimizer(),
        RandomTreeOptimizer.name(): RandomTreeOptimizer(),
    }
    return switcher.get(model, BruteForceOptimizer())

@app.command(name="init-model")
def init_model(
    model: Model = Model.linear_regression,
    db_path: str = typer.Option(
        "data.db",
        "--db",
        "--database",
        help="The path to the database.",
    ),
    system_id: int = typer.Option(
        -1,
        "--system",
        help="The id of the system to use.",
    ),
):
    repo = SqliteRepository(db_path)
    if system_id == -1:
        console.print("[yellow]You need to choose a system to train a model.[/yellow]")
        console.print("[green]Here are the available systems:[/green]")
        present_systems(repo)

        raise typer.Exit()

    logger.info("Initializing model of type '%s'", model.name)
    making_model = InitModelService(
        system_id=system_id,
        repository=repo,
        optimizer=_choose_optimizer(model),
    )

    with console.status("training model", spinner="dots12"):
        new_model_id = making_model.run()

    logger.info("Model trained with id %s", new_model_id)

def present_systems(repo):
    systems = repo.get_all_system_info()
    table = Table(title="Available Systems", style="green")
    table.add_column("ID", justify="center", style="cyan")
    table.add_column("DataClass", justify="center", style="magenta")
    for i, system in enumerate(systems):
        table.add_row(str(i), str(system))
    console.print(table)

def present_models(repo: RepositoryInterface):
    models = repo.get_all_models()
    table = Table(title="Available Models", style="green")
    table.add_column("ID", justify="center", style="cyan")
    table.add_column("Type", justify="center", style="magenta")
    table.add_column("Created", justify="center", style="magenta")
    table.add_column("System", justify="center", style="magenta")
    for model in models:
        table.add_row(
            str(model.id), model.type, model.created_at.strftime("%d/%m/%Y"), str(model.system_info)
        )
    console.print(table)

@app.command(name="load-model")
def load_model(
    model_id: int = typer.Option(
        -1,
        "--model",
        help="The id of the model to use.",
    ),
    db_path: str = typer.Option(
        "data.db",
        "--db",
        "--database",
        help="The path to the database.",
    ),
):
    repo = SqliteRepository(db_path)
    if model_id == -1:
        console.print("[yellow]You need to choose a model to load.[/yellow]")
        console.print("[green]Here are the available models:[/green]")
        present_models(repo)

        console.print("[yellow]Specify the model id with --model <id>[/yellow]")

        raise typer.Exit()

    model = repo.get_model(model_id)

    _load_model = LoadModelService(
        model_id=model_id,
        repository=repo,
        optimizer=_choose_optimizer(model.type),
        local_storage=EtcLocalStorage(Permission.WRITE),
    )
    _load_model.run()

@dataclasses.dataclass
class ConfigDto:
    cores: int
    frequency: int
    threads_per_core: int

@app.command(name="slurm-config")
def get_config(cpu: str = typer.Argument(..., help="The cpu model to get the config for")):
    local_storage = EtcLocalStorage(Permission.READ)
    optimizer_type = local_storage.get_settings().loaded_model.type
    run_model = RunModelService(
        optimizer=_choose_optimizer(optimizer_type), local_storage=local_storage
    )
    conf = run_model.run()
    disabled = False
    if disabled:
        outgoing = ConfigDto(
            cores=-1,
            frequency=-1,
            threads_per_core=-1,
        )
    else:
        outgoing = ConfigDto(
            cores=conf.cores,
            frequency=int(conf.frequency),
            threads_per_core=conf.threads_per_core,
        )
    console.print(json.dumps(dataclasses.asdict(outgoing)))

# add partician compute

@app.command(name="run")
def run(
    hpcg_path: str,
    cores: int = typer.Argument(..., help="The number of cores to run on."),
    frequency: int = typer.Argument(..., help="The frequency to run on."),
    threads_per_core: int = typer.Argument(..., help="The number of threads to run on."),
):
    hpcg = HpcgService(hpcg_path)
    import asyncio

    hpcg.run(cores, frequency, threads_per_core)
    while hpcg.is_running():
        sleep(1)

    print(hpcg.gflops)

@app.command(name="benchmark")
def benchmark(
    hpcg_path: str,
    configurations_path: str = typer.Option(
        None,
        "--configurations",
        "-c",
        help="The path to the file containing the configurations.",
    ),
    db_path: str = typer.Option(
        "data.db",
        "-db",
        "--database",
        help="The path to the database.",
    ),
):
    full_path = os.path.abspath(hpcg_path)
    benchmark_service = BenchmarkService(
        cpu_info_service=LsCpuInfoService(),
        application_runner=HpcgService(full_path),
        benchmark_repository=SqliteRepository(db_path),
        system_service=IpmiSystemService(),
    )

    if configurations_path:
        configurations = []
        with open(configurations_path) as f:
            configurations = json.loads(f.read())
        configurations = [Configuration(**c) for c in configurations]

        benchmark_service.set_configurations(configurations)

    benchmark_service.run()

@app.command(name="fix-db")
def fix_db(
    db_path: str = typer.Option(
        "data.db",
        "-db",
        "--database",
        help="The path to the database.",
    ),
):
    repo = SqliteRepository(db_path)

    with console.status("fixing db", spinner="dots12") as status:
        status.update("fixing system samples")
        repo.fix_system_samples()
        status.update("fixing gflops per watt")
        repo.fix_gflops_per_watt()

@app.command(name="best-runs")
def best_runs(
    db_path: str = typer.Option(
        "data.db",
        "-db",
        "--database",
        help="The path to the database.",
    )
):
    repo = SqliteRepository(db_path)
    runs = repo.get_best_runs()
    table = Table(title="Best Runs", style="green")
    table.add_column("ID", justify="center", style="cyan")
    table.add_column("cores", justify="center", style="magenta")
    table.add_column("frequency", justify="center", style="magenta")
    table.add_column("threads_per_core", justify="center", style="magenta")
    table.add_column("efficiency", justify="center", style="magenta")
    table.add_column("efficiency_%", justify="right", style="green")
    table.add_column("time_used", justify="center", style="magenta")
    table.add_column("time_%", justify="right", style="red")

    previous_time = (runs[0].end_time - runs[0].start_time).total_seconds()
    previous_efficiency = runs[0].efficiency
    for _run in runs:
        time_used = (_run.end_time - _run.start_time).total_seconds()
        time_pct = (time_used / previous_time) * 100
        previous_time = time_used

        efficiency_pct = (_run.efficiency / previous_efficiency) * 100

        table.add_row(
            str(_run.run_id),
            str(_run.cores),
            str(_run.frequency),
            str(_run.threads_per_core),
            f"{_run.efficiency:.2f}",
            f"{efficiency_pct:.2f}",
            f"{time_used:.2f}",
            f"{time_pct:.2f}",
        )

    console.print(table)

# delete output dir if exception
# error if exists
# if job failed, continue

if __name__ == "__main__":
    app()


import os
from openpyxl import workbook
from openpyxl.styles import PatternFill, Border, Side

# 处理文件路径
base_dir = os.path.dirname(os.path.abspath(__file__))
target_excel_path = os.path.join(base_dir, "users.xlsx")

# 创建excel且默认会创建一个sheet（名称为Sheet）
wb = workbook.Workbook()

sheet = wb.worksheets[0] # 或 sheet = wb["Sheet"]

# 找到单元格，并修改单元格的内容
cell1 = sheet.cell(1, 1)
cell1.fill = PatternFill("solid", fgColor="99ccff")
cell1.value = "用户姓名"

cell2 = sheet.cell(1, 2)
cell2.fill = PatternFill("solid", fgColor="99ccff")
cell2.border = Border(
    left=Side(style="dashed", color="FFB6C1"),
    right=Side(style="dashed", color="9932CC"),
)
cell2.value = "密码"

cell3 = sheet.cell(1, 3)
cell3.fill = PatternFill("solid", fgColor="99ccff")
cell3.value = "注册时间"

wb.save(target_excel_path)


FILE = "days/13/input.txt"

X = 0
Y = 1

with open(FILE, "r") as f:
    sections = f.read().strip().split("\n\n")
    coords = []
    fold_instructions = []
    for line in sections[0].split("\n"):
        # Coords
        pair = line.strip().split(",")
        coords.append((int(pair[0]), int(pair[1])))

    for line in sections[1].split("\n"):
        # Fold instructions
        parts = line.split("=")
        fold_instructions.append(("x" if "x" in parts[0] else "y", int(parts[1])))

def fold(coords, folds):
    coords = set(coords)
    new_coords = set()
    for axis, line in folds:
        for x, y in coords:
            if axis == "x" and x > line:
                # Mirror over vertical line
                new_coords.add((2*line - x, y))
            elif axis == "y" and y > line:
                # Mirror over horizontal line
                new_coords.add((x, 2*line - y))
            else:
                # No transformation for this point
                new_coords.add((x, y))

        coords = new_coords
        new_coords = set()
    return coords

def part1(coords, fold_instructions):
    return len(fold(coords, fold_instructions[0:1]))

def part2(coords, fold_instructions):
    import matplotlib.pyplot as plt

    # Invert the Y-coords or else the image will be
    # up-side down due to the puzzle's coordinate system
    points = fold(coords, fold_instructions)
    x = [x for x, _ in points]
    y = [-y for _, y in points]

    plt.scatter(x, y)
    plt.show()

print("Part I", part1(coords, fold_instructions))

# Part 2 is best viewed as a plot
part2(coords, fold_instructions)


# 현재 대기목록에는 1개 이상 100개 이하의 문서가 있습니다.
# 인쇄 작업의 중요도는 1~9로 표현하며 숫자가 클수록 중요하다는 뜻입니다.
# location은 0 이상 (현재 대기목록에 있는 작업 수 - 1) 이하의 값을 가지며 대기목록의 가장 앞에 있으면 0, 두 번째에 있으면 1로 표현합니다.

# 현재 대기목록에 있는 문서의 중요도가 순서대로 담긴 배열 priorities와 내가 인쇄를 요청한 문서가 현재 대기목록의 어떤 위치에 있는지를 알려주는 location이 매개변수로 주어질 때,
# 내가 인쇄를 요청한 문서가 몇 번째로 인쇄되는지 return 하도록 solution 함수를 작성해주세요.

def solution(priorities, location):
    index = [i for i in range(0, len(priorities))]  # priorities 배열 인덱스를 담아두는 리스트

    i=0
    while 1:
        if priorities[i] < max(priorities[i+1:]):
            priorities.append(priorities.pop(i))
            index.append(index.pop(i))
        else:
            i+=1
        if priorities == sorted(priorities, reverse=True):
            break

    return index.index(location)+1

# 다른 사람 코드
def solution(priorities, location):
  answer = 0
  from collections import deque

  d = deque([(v,i) for i,v in enumerate(priorities)])   # enumerate : 인덱스 번호와 컬렉션의 원소를 tuple형태로 반환

  while len(d):
      item = d.popleft()
      if d and max(d)[0] > item[0]:
          d.append(item)
      else:
          answer += 1
          if item[1] == location:
              break
  return answer


import tensorflow as tf
import layers3 as L
import numpy as np
import model3 as M
import os
import random
import glob
import time
import cv2

# tf.debugging.set_log_device_placement(True)
class cnnModel(M.Model):
	def initialize(self):
		self.c1 = M.ConvLayer2D(5, 32, stride=4, activation=M.PARAM_RELU)
		self.c2 = M.ConvLayer2D(5, 32, stride=4, activation=M.PARAM_RELU)
		self.c3 = M.ConvLayer2D(5, 64, stride=4, activation=M.PARAM_RELU)
		self.fc = M.Dense(10)

	def forward(self, x):
		x = self.c1(x)
		x = self.c2(x)
		x = self.c3(x)
		x = M.flatten(x)
		x = self.fc(x)
		return x

def get_grads(x , model):
	x, label = x
	with tf.GradientTape() as tape:
		out = model(x)
		loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=out, labels=label))

	grads = tape.gradient(loss, model.trainable_variables)
	return grads, loss

# try to define a generator
class data_reader():
	def __init__(self, bsize):
		self.bsize= bsize
		self.data = []
		for i in glob.glob('./data/*.*'):
			img = cv2.imread(i)
			img = np.float32(img)
			lb = np.random.randint(10)
			lb = np.eye(10)[lb].astype(np.float32)
			self.data.append([img, lb])

	def get_next(self):
		data = random.sample(self.data, self.bsize)
		dt, lb = list(zip(*data))
		dt = np.array(dt)
		lb = np.array(lb)
		return dt, lb

reader = data_reader(512)
with tf.device('/cpu:0'):
	model = cnnModel()

	optimizer = tf.keras.optimizers.Adam(0.001)

	pt = M.ParallelTraining(model, optimizer, [0,1,2,3])

	for i in range(100):
		t1 = time.time()
		batch = reader.get_next()
		batch_distribute = pt.split_data(batch)
		grads, loss = pt.compute_grad_loss(batch_distribute, get_grads)
		pt.apply_grad(grads)
		t2 = time.time()
		print('LS', loss.numpy())
		print('TIME', t2-t1)


"""Tests for La Marzocco binary sensors."""
from unittest.mock import MagicMock

import pytest
from syrupy import SnapshotAssertion

from homeassistant.const import STATE_UNAVAILABLE
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er

from . import async_init_integration

from tests.common import MockConfigEntry

BINARY_SENSORS = (
    "brewing_active",
    "water_tank_empty",
)

async def test_binary_sensors(
    hass: HomeAssistant,
    mock_lamarzocco: MagicMock,
    mock_config_entry: MockConfigEntry,
    entity_registry: er.EntityRegistry,
    snapshot: SnapshotAssertion,
) -> None:
    """Test the La Marzocco binary sensors."""

    await async_init_integration(hass, mock_config_entry)

    serial_number = mock_lamarzocco.serial_number

    for binary_sensor in BINARY_SENSORS:
        state = hass.states.get(f"binary_sensor.{serial_number}_{binary_sensor}")
        assert state
        assert state == snapshot(name=f"{serial_number}_{binary_sensor}-binary_sensor")

        entry = entity_registry.async_get(state.entity_id)
        assert entry
        assert entry.device_id
        assert entry == snapshot(name=f"{serial_number}_{binary_sensor}-entry")

@pytest.mark.usefixtures("remove_local_connection")
async def test_brew_active_does_not_exists(
    hass: HomeAssistant,
    mock_lamarzocco: MagicMock,
    mock_config_entry: MockConfigEntry,
) -> None:
    """Test the La Marzocco currently_making_coffee doesn't exist if host not set."""

    await async_init_integration(hass, mock_config_entry)
    state = hass.states.get(f"sensor.{mock_lamarzocco.serial_number}_brewing_active")
    assert state is None

async def test_brew_active_unavailable(
    hass: HomeAssistant,
    mock_lamarzocco: MagicMock,
    mock_config_entry: MockConfigEntry,
) -> None:
    """Test the La Marzocco currently_making_coffee becomes unavailable."""

    mock_lamarzocco.websocket_connected = False
    await async_init_integration(hass, mock_config_entry)
    state = hass.states.get(
        f"binary_sensor.{mock_lamarzocco.serial_number}_brewing_active"
    )
    assert state
    assert state.state == STATE_UNAVAILABLE


# coding: utf-8
import datetime

def new_list(l=[], element=None):
    nl = [e for e in l]
    nl.append(element)
    return nl

def str_list_strip(l):
    vals = []
    for x in l:
        x = x.strip()
        if x:
            vals.append(x)
    return vals

def str_list_strip_replace(l, replaces=[]):
    l = str_list_strip(l)
    for r in replaces:
        l = [x.replace(r, '') for x in l]
    return l

def add_one_month(t):
    """Return a `datetime.date` or `datetime.datetime` (as given) that is
    one month earlier.

    Note that the resultant day of the month might change if the following
    month has fewer days:

        >>> add_one_month(datetime.date(2010, 1, 31))
        datetime.date(2010, 2, 28)
    """
    one_day = datetime.timedelta(days=1)
    one_month_later = t + one_day
    while one_month_later.month == t.month:  # advance to start of next month
        one_month_later += one_day
    target_month = one_month_later.month
    while one_month_later.day < t.day:  # advance to appropriate day
        one_month_later += one_day
        if one_month_later.month != target_month:  # gone too far
            one_month_later -= one_day
            break
    return one_month_later

def add_months(t, mons, pattern=None):
    for _ in xrange(0, mons):
        t = add_one_month(t)
    if pattern:
        return t.strftime(pattern)
    return t

def subtract_one_month(t):
    """Return a `datetime.date` or `datetime.datetime` (as given) that is
    one month later.

    Note that the resultant day of the month might change if the following
    month has fewer days:

        >>> subtract_one_month(datetime.date(2010, 3, 31))
        datetime.date(2010, 2, 28)
    """
    one_day = datetime.timedelta(days=1)
    one_month_earlier = t - one_day
    while one_month_earlier.month == t.month or one_month_earlier.day > t.day:
        one_month_earlier -= one_day
    return one_month_earlier

def subtract_months(t, mons, pattern=None):
    for _ in xrange(0, mons):
        t = subtract_one_month(t)
    if pattern:
        return t.strftime(pattern)
    return t


import setuptools

with open("README.md", "r") as fh:
    long_description = fh.read()

setuptools.setup(
    name="pyFCI",
    version="0.0.1",
    author="Vittorio Erba",
    author_email="vittorio.erba@unimi.it",
    description="A package for multiscale-full-correlation-integral intrinsic dimension estimation",
    long_description=long_description,
    long_description_content_type="text/markdown",
    url="https://github.com/vittorioerba/pyFCI",
    packages=setuptools.find_packages(),
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
        ],
    install_requires=[
        'numpy',
        'scipy',
        'numba',
        'sympy',
        'tabulate'
        ],
    python_requires='>=3.6',
)


# Smarter, dictionary-based brute force

import sys, socket, string, itertools, pathlib

current_path = pathlib.Path(__file__).parent.absolute()

args = sys.argv
# args = [' ', '127.0.0.1', '9090']
hostname = args[1]
port = int(args[2])

def pwd_crack(hostname, port):
    soc = socket.socket()
    soc.connect((hostname, port))

    file = open(current_path / "passwords.txt")

    bin_list = [0, 1]

    while True:
        for line in file:
            wd = list(line.strip())
            copy_wd = wd[:]
            len_wd= len(wd)
            for comb in itertools.product(bin_list, repeat=len_wd):
                i = 0
                for bit in comb:
                    if bit:
                        wd[i] = wd[i].upper()
                    i += 1

                pwd = "".join(wd)
                soc.send(pwd.encode())
                resp = soc.recv(1024).decode()
                if resp == "Connection success!":
                    soc.close()
                    file.close()
                    return pwd
                wd = copy_wd[:]

print(pwd_crack(hostname, port))


import rclpy
from rclpy.node import Node
from std_msgs.msg import Int16
from pymodbus.client import ModbusTcpClient

class MyNode(Node):

    def __init__(self):

        super().__init__("CLP")
        self.publisher1_ = self.create_publisher(Int16, "signal_feedback_driver1", 10)
        self.timer_= self.create_timer(0.5,self.Modbus_msg)
        self.modbus_client_ = ModbusTcpClient('192.168.0.10', 502)
        self.get_logger().info ('Conexão com CLP estabelicida')

    def Modbus_msg (self):

        addr1 = 1
        resultHold = self.modbus_client_.read_holding_registers(0,6)
        signal_feedback1 = (resultHold.registers[0])

        valor1 = signal_feedback1
        msg = Int16()

        self.modbus_client_.write_register(addr1, valor1)
        msg.data = signal_feedback1
        self.publisher1_.publish(msg)

def main():

    rclpy.init()
    node = MyNode()
    rclpy.spin(node)
    rclpy.shutdown()

if __name__ == "__main__":
    main()


import numpy as np
import numpy.linalg as LA
import cv2
import matplotlib.pyplot as plt
import random
from core import cfg
import torch.utils.data as data
import torch
import torch.nn.functional as F
from random import Random
import os
import glob
import pickle
from modeling.utils.baseline_utils import apply_color_to_map
import bz2
import _pickle as cPickle

class MP3DViewDataset(data.Dataset):

	def __init__(self, split, scene_name, data_folder=''):
		self.split = split
		self.scene_name = scene_name

		self.saved_folder = f'{data_folder}/{self.split}/{self.scene_name}'

		self.sample_name_list = [os.path.splitext(os.path.basename(x))[0] for x in sorted(glob.glob(f'{self.saved_folder}/*.pbz2'))]

	def __len__(self):
		return len(self.sample_name_list)

	def __getitem__(self, i):
		if self.split == 'val':
			#============================= load npy file and pickle file ===============================
			with bz2.BZ2File(f'{self.saved_folder}/{self.sample_name_list[i]}.pbz2', 'rb') as fp:
				npy_file = cPickle.load(fp)
				rgb_obs = npy_file['rgb']
				depth_obs = npy_file['depth']
				sseg_obs = npy_file['sseg']
				R = npy_file['R']
				D = npy_file['D']
				Din = npy_file['Din']
				Dout = npy_file['Dout']
		elif self.split == 'train':
			with bz2.BZ2File(f'{self.saved_folder}/{self.sample_name_list[i]}.pbz2', 'rb') as fp:
				npy_file = cPickle.load(fp)
				rgb_obs = npy_file['rgb']
				depth_obs = npy_file['depth']
				sseg_obs = npy_file['sseg']
				R = npy_file['R']
				D = npy_file['D']
				Din = npy_file['Din']
				Dout = npy_file['Dout']

		sseg_obs = np.where(sseg_obs < 0, 0, sseg_obs)

		#=================================== visualize M_p =========================================
		if cfg.PRED.VIEW.FLAG_VISUALIZE_PRED_LABELS:
			print(f'R = {R}, D = {D}, Din = {Din}, Dout = {Dout}')
			color_sseg_obs = apply_color_to_map(sseg_obs)

			fig, ax = plt.subplots(nrows=1, ncols=3, figsize=(20, 5))
			ax[0].imshow(rgb_obs, cmap='gray')
			ax[0].get_xaxis().set_visible(False)
			ax[0].get_yaxis().set_visible(False)
			ax[0].set_title('input: occupancy_map_Mp')
			ax[1].imshow(color_sseg_obs)
			ax[1].get_xaxis().set_visible(False)
			ax[1].get_yaxis().set_visible(False)
			ax[1].set_title('input: semantic_map_Mp')
			ax[2].imshow(depth_obs, cmap='gray')
			ax[2].get_xaxis().set_visible(False)
			ax[2].get_yaxis().set_visible(False)
			ax[2].set_title('observed_occ_map + frontiers')

			fig.tight_layout()
			plt.show()

		#================= convert to tensor=================
		tensor_depth = torch.tensor(depth_obs, dtype=torch.float32)
		tensor_sseg = torch.tensor(sseg_obs, dtype=torch.long)
		#print(f'tensor_depth.shape = {tensor_depth.shape}')
		#print(f'tensor_sseg.shape = {tensor_sseg.shape}')

		#================= convert input tensor into one-hot vector===========================
		tensor_depth = tensor_depth.unsqueeze(0)
		tensor_sseg = F.one_hot(tensor_sseg, num_classes=cfg.SEM_MAP.GRID_CLASS_SIZE).permute(2, 0, 1) # num_classes x H x W
		#print(f'tensor_sseg.shape = {tensor_sseg.shape}')
		tensor_input = torch.cat((tensor_depth, tensor_sseg), 0).float()
		tensor_output = torch.tensor([R, D, Din, Dout]).float()

		if cfg.PRED.VIEW.INPUT == 'depth_only':
			tensor_input = tensor_input[0].unsqueeze(0)

		#print(f'tensor_input.shape = {tensor_input.shape}')
		#print(f'tensor_output.shape = {tensor_output.shape}')

		return {'input': tensor_input, 'output': tensor_output}

def get_all_view_dataset(split, scene_list, data_folder):
	ds_list = []
	for scene in scene_list:
		scene_ds = MP3DViewDataset(split, scene, data_folder=data_folder)
		ds_list.append(scene_ds)

	concat_ds = data.ConcatDataset(ds_list)
	return concat_ds

if __name__ == "__main__":
	cfg.merge_from_file('configs/exp_train_input_view_depth_and_sem.yaml')
	cfg.freeze()

	split = 'val'
	if split == 'train':
		scene_list = cfg.MAIN.TRAIN_SCENE_LIST
	elif split == 'val':
		scene_list = cfg.MAIN.VAL_SCENE_LIST
	elif split == 'test':
		scene_list = cfg.MAIN.TEST_SCENE_LIST

	data_folder = 'output/training_data_input_view_1000samples'

	ds_list = []
	for scene in scene_list:
		scene_ds = MP3DViewDataset(split, scene, data_folder=data_folder)
		ds_list.append(scene_ds)

	concat_ds = data.ConcatDataset(ds_list)


from functools import cmp_to_key
from typing import List

class QueueReconstructionByHeight:
    def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
        people.sort(key=cmp_to_key(lambda l1,l2: l2[0]-l1[0] if l1[0]!=l2[0] else l1[1]-l2[1]))
        result=[]
        for each in people:
            result.insert(each[1], each)
        return result

if __name__ == '__main__':
    init = QueueReconstructionByHeight()
    print(init.reconstructQueue([[7, 0], [4, 4], [7, 1], [5, 0], [6, 1], [5, 2]]))
    print (init.reconstructQueue([[9,0],[7,0],[1,9],[3,0],[2,7],[5,3],[6,0],[3,4],[6,2],[5,2]])) #[[3,0],[6,0],[7,0],[5,2],[3,4],[5,3],[6,2],[2,7],[9,0],[1,9]]