import os
import sys
import json
import warnings
warnings.filterwarnings("ignore")

import math
import time
import random
import argparse
import numpy as np
from copy import deepcopy
from tqdm import tqdm

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import models, transforms, datasets

from models import get_backbone_class
from util.methods import get_semisup_method_class
from util.dataset import ImageFolderSemiSup, x_u_split, MergeDataset
from util.transform import get_semisup_transform_class
from util.misc import *

DATASET_CONFIG = {'cars': (196, 8144), 'flowers': (102, 2040), 'pets': (37, 3680), 'aircraft': (100, 6667), 'cub': (200, 5990),
                  'dogs': (120, 12000), 'mit67': (67, 5360), 'stanford40': (40, 4000), 'dtd': (47, 3760), 'celeba': (307, 4263),
                  'food11': (11, 13296), 'imagenet100': (100, 130000), 'imagenet': (1000, 1281167)}

def parse_args():
    parser = argparse.ArgumentParser('argument for open-set semi-supervised learning')

    parser.add_argument('--seed', type=int, default=0)
    parser.add_argument('--print_freq', type=int, default=10)
    parser.add_argument('--save_freq', type=int, default=10)
    parser.add_argument('--save_dir', type=str, default='./save')
    parser.add_argument('--tag', type=str, default='',
                        help='tag for experiment name')

    # optimization
    parser.add_argument('--optimizer', type=str, default='sgd')
    parser.add_argument('--learning_rate', type=float, default=0.03)
    parser.add_argument('--lr_decay_epochs', type=str, default='60,80')
    parser.add_argument('--lr_decay_rate', type=float, default=0.1)
    parser.add_argument('--weight_decay', type=float, default=1e-4)
    parser.add_argument('--momentum', type=float, default=0.9)
    parser.add_argument('--cosine', action='store_true',
                        help='using cosine annealing')
    parser.add_argument('--warm', action='store_true',
                        help='warm-up for large batch training')
    parser.add_argument('--warm_epochs', type=int, default=0,
                        help='warmup epochs')
    parser.add_argument('--total_step', default=2**14, type=int,
                        help='number of total steps to run, SimCore (2**14) and scratch (2**16)')
    parser.add_argument('--eval_step', default=512, type=int,
                        help='number of eval steps to run')

    # dataset
    parser.add_argument('--dataset', type=str, default='cars')
    parser.add_argument('--data_folder', type=str, default='./data/')
    parser.add_argument('--num_workers', type=int, default=16)
    parser.add_argument('--img_size', type=int, default=224)
    parser.add_argument('--batch_size', type=int, default=64,
                        help='only Self-Training with SimCore ckpt used 256')
    parser.add_argument('--label_ratio', type=float, default=0.5,
                        help='ratio for the labeled samples')
    parser.add_argument('--mu', type=float, default=1,
                        help='coefficient of unlabeled batch size, SelfTrain (1) and OpenMatch (2)')
    # for Self-Training
    parser.add_argument('--data_folder2', type=str, default='./data/',
                        help='data folder root for WebFG-496 dataset')
    parser.add_argument('--teacher_batch_size', type=int, default=64,
                        help='batch size for teacher_labeled_loader, SimCore (256) and scratch (64)')

    # model & method
    parser.add_argument('--model', type=str, default='resnet50')
    parser.add_argument('--method', type=str, default=None)
    parser.add_argument('--pretrained', action='store_true')
    parser.add_argument('--pretrained_ckpt', type=str, default=None,
                        help='path to pre-trained model')
    parser.add_argument('--teacher_pretrained_ckpt', type=str, default=None,
                        help='path to pre-trained teacher model')
    parser.add_argument('--use_ema', action='store_true',
                        help='whether to use exponential moving average of encoder model')
    parser.add_argument('--ema_decay', default=0.999, type=float,
                        help='EMA decay rate')
    parser.add_argument('--clip', default=0, type=float,
                        help='clip gradient value')

    parser.add_argument('--semisup_method', default='self_training', type=str,
                        help='semi-supervised learning algorithm')

    ### Self-Training ###
    parser.add_argument('--teacher_epochs', default=100, type=int,
                        help='epochs to train teacher network, SimCore (100) and scratch (500)')
    parser.add_argument('--T', default=1, type=float,
                        help='pseudo label temperature')
    parser.add_argument('--lambda_u', default=0.5, type=float,
                        help='coefficient of unlabeled loss')

    ### OpenMatch ###
    parser.add_argument('--start_fix', default=5, type=int,
                        help='epoch to start fixmatch training, SimCore (5) and scratch (20)')
    parser.add_argument('--lambda_oem', default=0.1, type=float,
                        help='coefficient of OEM loss')
    parser.add_argument('--lambda_socr', default=0.5, type=float,
                        help='coefficient of SOCR loss')
    # parser.add_argument('--T', default=1, type=float,
    #                     help='pseudo label temperature')
    parser.add_argument('--threshold', default=0.0, type=float,
                        help='pseudo label threshold')

    args = parser.parse_args()

    args.epochs = math.ceil(args.total_step / args.eval_step)
    iterations = args.lr_decay_epochs.split(',')
    args.lr_decay_epochs = list([])
    for it in iterations:
        args.lr_decay_epochs.append(int(it))
    args.wd_scheduler = False

    args.model_name = '{}_{}'.format(args.dataset, args.model)

    args.model_name += '_{}_semisup'.format(args.semisup_method)

    if not args.pretrained:
        assert args.pretrained_ckpt is None
        args.model_name += '_from_scratch'

    if args.tag:
        args.model_name += '_{}'.format(args.tag)

    args.save_folder = os.path.join(args.save_dir, args.model_name)
    if not os.path.isdir(args.save_folder):
        os.makedirs(args.save_folder)

    if args.warm:
        args.warmup_from = args.learning_rate * 0.1**3
        args.warm_epochs = args.warm_epochs
        if args.cosine:
            eta_min = args.learning_rate * (args.lr_decay_rate ** 3)
            args.warmup_to = eta_min + (args.learning_rate - eta_min) * (
                    1 + math.cos(math.pi * args.warm_epochs / args.epochs)) / 2
        else:
            args.warmup_to = args.learning_rate

    if args.dataset in DATASET_CONFIG:
        args.n_cls, args.n_data = DATASET_CONFIG[args.dataset]
    else:
        raise NotImplementedError

    args.num_labeled = int(args.n_data * args.label_ratio)
    assert args.num_labeled >= args.batch_size

    return args

def set_loader(args):
    # construct data loader
    if args.dataset in DATASET_CONFIG:
        mean = (0.485, 0.456, 0.406)
        std = (0.229, 0.224, 0.225)
    else:
        raise NotImplementedError
    normalize = transforms.Normalize(mean=mean, std=std)

    train_transform = transforms.Compose([
        transforms.RandomResizedCrop(size=args.img_size, scale=(0.2, 1.)),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        normalize,
    ])
    val_transform = transforms.Compose([transforms.Resize(256),
                                        transforms.CenterCrop(args.img_size),
                                        transforms.ToTensor(),
                                        normalize])

    # split labeled and unlabeled dataset
    train_labeled_idxs, train_unlabeled_idxs = x_u_split(args)
    TRANSFORM = get_semisup_transform_class(args.semisup_method)

    if args.dataset == 'imagenet':
        traindir = os.path.join(args.data_folder, 'train') # under ~~/Data/CLS-LOC
        valdir = os.path.join(args.data_folder, 'val')
    else: # for fine-grained dataset
        if args.dataset == 'aircraft' or args.dataset == 'cars':
            traindir = os.path.join(args.data_folder, args.dataset, 'train')
            valdir = os.path.join(args.data_folder, args.dataset, 'test')
        elif args.dataset == 'celeba':
            traindir = os.path.join(args.data_folder, 'celeba_maskhq', 'train')
            valdir = os.path.join(args.data_folder, 'celeba_maskhq', 'test')
        else:
            traindir = os.path.join(args.data_folder, args.dataset, 'train')
            valdir = os.path.join(args.data_folder, args.dataset, 'test')

    if args.semisup_method == 'openmatch':
        train_transform = TRANSFORM(args.img_size, mean, std)

    train_labeled_dataset = ImageFolderSemiSup(root=traindir,
                                                transform=train_transform,
                                                index=train_labeled_idxs)
    train_unlabeled_dataset = ImageFolderSemiSup(root=traindir,
                                                 transform=TRANSFORM(args.img_size, mean, std),
                                                 index=train_unlabeled_idxs)

    traindir = os.path.join(args.data_folder2, 'train')
    webfg_ul_dataset = datasets.ImageFolder(root=traindir, transform=TRANSFORM(args.img_size, mean, std))
    train_unlabeled_dataset = MergeDataset(train_unlabeled_dataset, webfg_ul_dataset)

    val_dataset = datasets.ImageFolder(root=valdir,
                                       transform=val_transform)

    if args.semisup_method == 'self_training':
        train_labeled_loader = [torch.utils.data.DataLoader(train_labeled_dataset, batch_size=args.batch_size, shuffle=True,
                                                            num_workers=8, pin_memory=True, drop_last=True),
                                torch.utils.data.DataLoader(train_labeled_dataset, batch_size=args.teacher_batch_size, shuffle=True,
                                                            num_workers=8, pin_memory=True, drop_last=True)]
    elif args.semisup_method == 'openmatch':
        train_labeled_loader = torch.utils.data.DataLoader(
                train_labeled_dataset, batch_size=args.batch_size, shuffle=True,
                num_workers=4, pin_memory=True, drop_last=True)

    train_unlabeled_loader = torch.utils.data.DataLoader(
            train_unlabeled_dataset, batch_size=int(args.batch_size*args.mu), shuffle=True,
            num_workers=4, pin_memory=True, drop_last=True)
    val_loader = torch.utils.data.DataLoader(
            val_dataset, batch_size=args.batch_size, shuffle=False,
            num_workers=4, pin_memory=True)

    return train_labeled_loader, train_unlabeled_loader, val_loader, args

def set_model(args):
    model = get_backbone_class(args.model)()
    feat_dim = model.final_feat_dim
    classifier = nn.Linear(feat_dim, args.n_cls)  # reset fc layer
    criterion = nn.CrossEntropyLoss()
    semisup_criterion = get_semisup_method_class(args.semisup_method)(args)

    if args.pretrained_ckpt is not None:
        ckpt = torch.load(args.pretrained_ckpt, map_location='cpu')
        state_dict = ckpt['model']

        # HOTFIX: always dataparallel during pretraining
        new_state_dict = {}
        for k, v in state_dict.items():
            if "module." in k:
                k = k.replace("module.", "")
            if "backbone." in k:
                k = k.replace("backbone.", "")
            new_state_dict[k] = v
        state_dict = new_state_dict
        model.load_state_dict(state_dict, strict=False)
        print('pretrained model loaded from: {}'.format(args.pretrained_ckpt))

    if torch.cuda.device_count() > 1:
        model = torch.nn.DataParallel(model)
    else:
        raise NotImplementedError

    model.cuda()
    ema_model = ModelEMA(model, args.ema_decay) if args.use_ema else None

    classifier.cuda()
    criterion = criterion.cuda()
    semisup_criterion = semisup_criterion.cuda()
    optim_params = list(model.parameters()) + list(classifier.parameters())

    if args.semisup_method == 'openmatch':
        classifier_open = nn.Linear(feat_dim, args.n_cls*2, bias=False).cuda()
        optim_params += list(classifier_open.parameters())
        classifier = (classifier, classifier_open)

    if args.optimizer == 'sgd':
        optimizer = optim.SGD(optim_params,
                            lr=args.learning_rate,
                            momentum=args.momentum,
                            weight_decay=args.weight_decay,
                            nesterov=True)
    elif args.optimizer == 'adam':
        optimizer = optim.Adam(optim_params,
                               lr=args.learning_rate,
                               weight_decay=args.weight_decay)

    return model, ema_model, classifier, criterion, semisup_criterion, optimizer

def train_teacher(train_loader, model, classifier, criterion, optimizer, epoch, args):
    model.train()
    classifier.train()

    batch_time = AverageMeter()
    data_time = AverageMeter()
    losses = AverageMeter()
    top1 = AverageMeter()

    end = time.time()
    for idx, (images, labels) in enumerate(train_loader):
        data_time.update(time.time() - end)

        images = images.cuda(non_blocking=True)
        labels = labels.cuda(non_blocking=True)
        bsz = labels.shape[0]

        # warmup_learning_rate(args, epoch, idx, len(train_loader), optimizer)

        if not args.e2e:
            with torch.no_grad():
                features = model(images)
            output = classifier(features.detach())
        else:
            output = classifier(model(images))
        loss = criterion(output, labels)

        losses.update(loss.item(), bsz)
        [acc1, acc5], _ = accuracy(output, labels, topk=(1, 5))
        top1.update(acc1[0], bsz)

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        # measure elapsed time
        batch_time.update(time.time() - end)
        end = time.time()

        # print info
        if (idx + 1) % args.print_freq == 0:
            print('Train: [{0}][{1}/{2}]\t'
                  'BT {batch_time.val:.3f} ({batch_time.avg:.3f})\t'
                  'DT {data_time.val:.3f} ({data_time.avg:.3f})\t'
                  'loss {loss.val:.3f} ({loss.avg:.3f})\t'
                  'Acc@1 {top1.val:.3f} ({top1.avg:.3f})'.format(
                   epoch, idx + 1, len(train_loader), batch_time=batch_time,
                   data_time=data_time, loss=losses, top1=top1))
            sys.stdout.flush()

    return losses.avg, top1.avg

def train_selftraining(train_labeled_loader, train_unlabeled_loader, model, ema_model, classifier, semisup_criterion, optimizer, scaler, epoch, args, teacher_model=None):
    model.train()
    classifier.train()

    batch_time, data_time = AverageMeter(), AverageMeter()
    l_losses, u_losses = AverageMeter(), AverageMeter()
    top1 = AverageMeter()

    labeled_iter = iter(train_labeled_loader)
    unlabeled_iter = iter(train_unlabeled_loader)

    end = time.time()
    for idx in range(args.eval_step):
        try:
            labeled_data = next(labeled_iter)
        except:
            labeled_iter = iter(train_labeled_loader)
            labeled_data = next(labeled_iter)

        try:
            unlabeled_data = next(unlabeled_iter)
        except:
            unlabeled_iter = iter(train_unlabeled_loader)
            unlabeled_data = next(unlabeled_iter)

        data_time.update(time.time() - end)

        warmup_learning_rate(args, epoch, idx, args.eval_step, optimizer)

        # semi-supervised learning methods
        epoch_info = [epoch, idx]
        with torch.cuda.amp.autocast():
            if teacher_model is None:
                loss, Lx, Lu, logits_x, targets_x = semisup_criterion(labeled_data, unlabeled_data, model, classifier, epoch_info)
            else:
                loss, Lx, Lu, logits_x, targets_x = semisup_criterion(labeled_data, unlabeled_data, model, classifier, epoch_info, teacher_model)

        bsz = targets_x.shape[0]
        l_losses.update(Lx.item(), bsz)
        u_losses.update(Lu.item(), bsz)
        [acc1, acc5], _ = accuracy(logits_x, targets_x, topk=(1, 5))
        top1.update(acc1[0], bsz)

        optimizer.zero_grad()
        scaler.scale(loss).backward()
        if args.clip > 0:
            torch.nn.utils.clip_grad_norm_(model.parameters(), args.clip)
            torch.nn.utils.clip_grad_norm_(classifier.parameters(), args.clip)

        scaler.step(optimizer)
        scaler.update()
        if args.use_ema:
            ema_model.update(model)

        # measure elapsed time
        batch_time.update(time.time() - end)
        end = time.time()

        # print info
        if (idx + 1) % args.print_freq == 0:
            print('Train: [{0}][{1}/{2}]\t'
                  'BT {batch_time.val:.3f} ({batch_time.avg:.3f})\t'
                  'DT {data_time.val:.3f} ({data_time.avg:.3f})\t'
                  'l_loss {l_loss.val:.3f} ({l_loss.avg:.3f})\t'
                  'u_loss {u_loss.val:.3f} ({u_loss.avg:.3f})\t'
                  'Acc@1 {top1.val:.3f} ({top1.avg:.3f})'.format(
                   epoch, idx + 1, args.eval_step, batch_time=batch_time, data_time=data_time,
                   l_loss=l_losses, u_loss=u_losses, top1=top1))
            sys.stdout.flush()

    return l_losses.avg, top1.avg

def exclude_dataset(args, dataset, model, classifier, classifier_open, exclude_known=False):
    end = time.time()
    # dataset.init_index()
    test_loader = torch.utils.data.DataLoader(
        dataset,
        batch_size=args.batch_size,
        num_workers=4,
        drop_last=True,
        shuffle=False)

    model.eval()
    classifier.eval()
    classifier_open.eval()
    with torch.no_grad():
        for batch_idx, ((_, _, inputs), targets) in enumerate(tqdm(test_loader)):
            inputs = inputs.cuda(non_blocking=True)
            feat = model(inputs)
            outputs, outputs_open = classifier(feat), classifier_open(feat)
            outputs = F.softmax(outputs, 1)
            out_open = F.softmax(outputs_open.view(outputs_open.size(0), 2, -1), 1)
            tmp_range = torch.range(0, out_open.size(0) - 1).long().cuda()
            pred_close = outputs.data.max(1)[1]
            unk_score = out_open[tmp_range, 0, pred_close]
            known_ind = unk_score < 0.5
            if batch_idx == 0:
                known_all = known_ind
            else:
                known_all = torch.cat([known_all, known_ind], 0)
    known_all = known_all.data.cpu().numpy()
    if exclude_known:
        ind_selected = np.where(known_all == 0)[0]
    else:
        ind_selected = np.where(known_all != 0)[0]
    print("selected ratio %s"%( (len(ind_selected)/ len(known_all))))
    model.train()
    classifier.train()
    classifier_open.train()
    return ind_selected

def train_openmatch(train_labeled_loader, train_unlabeled_loader, model, ema_model, classifier, semisup_criterion, optimizer, scaler, epoch, args, teacher_model=None):
    model.train()
    classifier, classifier_open = classifier
    classifier.train()
    classifier_open.train()

    batch_time, data_time = AverageMeter(), AverageMeter()
    losses, losses_x = AverageMeter(), AverageMeter()
    losses_o, losses_oem, losses_socr, losses_fix = AverageMeter(), AverageMeter(), AverageMeter(), AverageMeter()
    top1 = AverageMeter()

    labeled_iter = iter(train_labeled_loader)
    unlabeled_all_iter = iter(train_unlabeled_loader)

    unlabeled_dataset = deepcopy(train_unlabeled_loader.dataset)

    if epoch >= args.start_fix:
        indices_inlier = exclude_dataset(args, unlabeled_dataset, model, classifier, classifier_open)
    else:
        indices_inlier = range(len(unlabeled_dataset))

    unlabeled_sampler = torch.utils.data.SubsetRandomSampler(indices_inlier, generator=None)
    unlabeled_trainloader = torch.utils.data.DataLoader(
                            unlabeled_dataset, batch_size=int(args.batch_size*args.mu), sampler=unlabeled_sampler,
                            num_workers=4, pin_memory=True, drop_last=True)
    unlabeled_iter = iter(unlabeled_trainloader)

    end = time.time()
    for idx in range(args.eval_step):
        try:
            labeled_data = next(labeled_iter)
        except:
            labeled_iter = iter(train_labeled_loader)
            labeled_data = next(labeled_iter)

        try:
            unlabeled_data = next(unlabeled_iter)
        except:
            unlabeled_iter = iter(unlabeled_trainloader)
            unlabeled_data = next(unlabeled_iter)

        try:
            unlabeled_data_all = next(unlabeled_all_iter)
        except:
            unlabeled_all_iter = iter(train_unlabeled_loader)
            unlabeled_data_all = next(unlabeled_all_iter)

        data_time.update(time.time() - end)

        warmup_learning_rate(args, epoch, idx, args.eval_step, optimizer)

        # semi-supervised learning methods
        epoch_info = [epoch, idx]
        with torch.cuda.amp.autocast():
            loss, Lx, Lo, L_oem, L_socr, L_fix, logits_x, targets_x = semisup_criterion(labeled_data, unlabeled_data, unlabeled_data_all, model, classifier, classifier_open, epoch_info)

        bsz = targets_x.shape[0]
        losses.update(loss.item(), bsz)
        losses_x.update(Lx.item(), bsz)
        losses_o.update(Lo.item(), bsz)
        losses_oem.update(L_oem.item(), bsz)
        losses_socr.update(L_socr.item(), bsz)
        losses_fix.update(L_fix.item(), bsz)

        [acc1, acc5], _ = accuracy(logits_x, targets_x, topk=(1, 5))
        top1.update(acc1[0], bsz)

        optimizer.zero_grad()
        scaler.scale(loss).backward()
        if args.clip > 0:
            torch.nn.utils.clip_grad_norm_(model.parameters(), args.clip)
            torch.nn.utils.clip_grad_norm_(classifier.parameters(), args.clip)

        scaler.step(optimizer)
        scaler.update()
        if args.use_ema:
            ema_model.update(model)

        # measure elapsed time
        batch_time.update(time.time() - end)
        end = time.time()

        # print info
        if (idx + 1) % args.print_freq == 0:
            print('Train: [{0}][{1}/{2}]\t'
                  'BT {batch_time.val:.3f} ({batch_time.avg:.3f})\t'
                  'DT {data_time.val:.3f} ({data_time.avg:.3f})\t'
                  'loss {losses.val:.3f} ({losses.avg:.3f})\t'
                  'loss_x {losses_x.val:.3f} ({losses_x.avg:.3f})\t'
                  'loss_o {losses_o.val:.3f} ({losses_o.avg:.3f})\t'
                  'loss_oem {losses_oem.val:.3f} ({losses_oem.avg:.3f})\t'
                  'loss_socr {losses_socr.val:.3f} ({losses_socr.avg:.3f})\t'
                  'loss_fix {losses_fix.val:.3f} ({losses_fix.avg:.3f})\t'
                  'Acc@1 {top1.val:.3f} ({top1.avg:.3f})'.format(
                   epoch, idx + 1, args.eval_step, batch_time=batch_time, data_time=data_time,
                   losses=losses, losses_x=losses_x, losses_o=losses_o, losses_oem=losses_oem,
                   losses_socr=losses_socr, losses_fix=losses_fix, top1=top1))
            sys.stdout.flush()

    return losses_x.avg, top1.avg

def validate(val_loader, model, classifier, criterion, args, best_acc, best_model):
    model.eval()
    if isinstance(classifier, tuple):
        classifier = classifier[0]
    classifier.eval()

    batch_time = AverageMeter()
    losses = AverageMeter()
    top1, top5 = AverageMeter(), AverageMeter()
    if args.dataset in ['aircraft', 'pets', 'flowers', 'mit67']: # mean per-class accuracy
        top1, top5 = AverageClassMeter(args.n_cls), AverageClassMeter(args.n_cls)

    with torch.no_grad():
        end = time.time()
        for idx, (images, labels) in enumerate(val_loader):
            images = images.cuda(non_blocking=True)
            labels = labels.cuda(non_blocking=True)
            bsz = labels.shape[0]

            output = classifier(model(images))
            loss = criterion(output, labels)

            losses.update(loss.item(), bsz)
            top1, top5 = update_metric(output, labels, top1, top5, args)
            batch_time.update(time.time() - end)
            end = time.time()
            if (idx + 1) % args.print_freq == 0:
                print('Test: [{0}/{1}]\t'
                      'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t'
                      'Loss {loss.val:.4f} ({loss.avg:.4f})\t'
                      'Acc@1 {top1.val:.3f} ({top1.avg:.3f})'.format(
                       idx + 1, len(val_loader), batch_time=batch_time,
                       loss=losses, top1=top1))

    print(' * Acc@1 {top1.avg:.2f}, Acc@5 {top5.avg:.2f}'.format(top1=top1, top5=top5))
    best_acc, bool = get_best_acc(top1.avg, top5.avg, best_acc)
    if bool:
        best_model = [deepcopy(model.state_dict()), deepcopy(classifier.state_dict())]

    return best_acc, best_model

def main():
    args = parse_args()
    with open(os.path.join(args.save_folder, 'train_args.json'), 'w') as f:
        json.dump(vars(args), f, indent=4)

    # fix seed
    random.seed(args.seed)
    np.random.seed(args.seed)
    torch.manual_seed(args.seed)
    torch.cuda.manual_seed(args.seed)

    best_acc, best_model = [0, 0, 0], None
    train_labeled_loader, train_unlabeled_loader, val_loader, args = set_loader(args)
    model, ema_model, classifier, criterion, semisup_criterion, optimizer = set_model(args)
    if args.semisup_method == 'self_training':
        model2, _, classifier2, _, _, optimizer2 = set_model(args)
    scaler = torch.cuda.amp.GradScaler()

    teacher_model = None
    if args.semisup_method == 'self_training':
        # for Self-Training, train a teacher network with labeled dataset
        train_labeled_loader, teacher_labeled_loader = train_labeled_loader
        if args.teacher_pretrained_ckpt is None:
            args.e2e = True
            for t_epoch in range(1, args.teacher_epochs+1):
                adjust_lr_wd(args, optimizer2, t_epoch)
                loss, acc = train_teacher(teacher_labeled_loader, model2, classifier2, criterion, optimizer2, t_epoch, args)

                if t_epoch % 5 == 0:
                    best_acc, best_model = validate(val_loader, model2, classifier2, criterion, args, best_acc, best_model)

            save_file = os.path.join(args.save_folder, 'teacher_best.pth')
            model2.load_state_dict(best_model[0])
            classifier2.load_state_dict(best_model[1])
            save_model(model2, optimizer2, args, t_epoch, save_file, classifier=classifier2)

            _, _ = validate(val_loader, model2, classifier2, criterion, args, best_acc, best_model)

            teacher_model = [model2, classifier2]
            best_acc, best_model = [0, 0, 0], None
        else:
            print('teacher pretrained model loaded from: {}'.format(args.teacher_pretrained_ckpt))
            ckpt = torch.load(args.teacher_pretrained_ckpt, map_location='cpu')
            model2.load_state_dict(ckpt['model'])
            classifier2.load_state_dict(ckpt['classifier'])
            teacher_model = [model2, classifier2]

            _, _ = validate(val_loader, model2, classifier2, criterion, args, best_acc, best_model)

        model2.eval()
        classifier2.eval()

    for epoch in range(1, args.epochs+1):
        adjust_lr_wd(args, optimizer, epoch)

        # train for one epoch
        time1 = time.time()
        if args.semisup_method == 'self_training':
            loss, acc = train_selftraining(train_labeled_loader, train_unlabeled_loader, model, ema_model, classifier, semisup_criterion, optimizer, scaler, epoch, args, teacher_model)
        elif args.semisup_method == 'openmatch':
            loss, acc = train_openmatch(train_labeled_loader, train_unlabeled_loader, model, ema_model, classifier, semisup_criterion, optimizer, scaler, epoch, args)

        time2 = time.time()
        print('Train epoch {}, total time {:.2f}, accuracy:{:.2f}'.format(
            epoch, time2-time1, acc))
        best_acc[2] = acc.item()

        # eval for one epoch
        if args.use_ema:
            best_acc, best_model = validate(val_loader, ema_model.model, classifier, criterion, args, best_acc, best_model)
        else:
            best_acc, best_model = validate(val_loader, model, classifier, criterion, args, best_acc, best_model)

        if epoch % args.save_freq == 0:
            save_file = os.path.join(args.save_folder, 'epoch_{}.pth'.format(epoch))
            if args.use_ema:
                save_model(ema_model.model, optimizer, args, epoch, save_file)
            else:
                save_model(model, optimizer, args, epoch, save_file)

    save_file = os.path.join(args.save_folder, 'best.pth')
    model.load_state_dict(best_model[0])
    save_model(model, optimizer, args, epoch, save_file)
    update_json('%s' % args.model_name, best_acc, path=os.path.join(args.save_dir, 'results.json'))

if __name__ == '__main__':
    main()


BOT_NAME = 'caymannational'

SPIDER_MODULES = ['caymannational.spiders']
NEWSPIDER_MODULE = 'caymannational.spiders'
FEED_EXPORT_ENCODING = 'utf-8'
LOG_LEVEL = 'ERROR'
DOWNLOAD_DELAY = 0

ROBOTSTXT_OBEY = True

ITEM_PIPELINES = {
	'caymannational.pipelines.CaymannationalPipeline': 100,

}


import pygame
from pygame import *

from entities import constants
from levels import Level
from .entity import Entity

def draw_sprite(TILE_X, TILE_Y):
    image_file = "images/sprites/items/ladderMid.png"
    temp = pygame.image.load(image_file)
    temp = pygame.transform.scale(temp, (TILE_X, TILE_Y))
    return temp

def draw_procedural_simple(TILE_X, TILE_Y):
    temp = Surface((TILE_X, TILE_Y))
    temp.convert()
    temp.fill(Color(constants.COLOR_STAIRS_BCKGRND))
    for i_step in range(TILE_Y // 4):
        temp.fill(Color(constants.COLOR_STAIRS), Rect(0, 8 * i_step, TILE_X, 1))
    return temp

def draw_procedural(TILE_X, TILE_Y):
    COLOR_BAR_LIGHT = "#ffe699"
    COLOR_BAR = "#ffbf00"
    COLOR_BAR_DARK = "#b38600"
    temp = Surface((TILE_X, TILE_Y))
    temp.convert()
    temp.fill(Color(constants.COLOR_STAIRS_BCKGRND))
    i_step = 0
    while i_step <= TILE_Y:
        if TILE_Y<32:
            temp.fill(Color(COLOR_BAR_LIGHT), Rect(0, i_step, TILE_X, 1))
            temp.fill(Color(COLOR_BAR), Rect(0, i_step+1, TILE_X, 1))
            temp.fill(Color(COLOR_BAR_DARK), Rect(0, i_step+2, TILE_X, 1))
            i_step = i_step + 8
        else:
            temp.fill(Color(COLOR_BAR_LIGHT), Rect(0, i_step, TILE_X, 1))
            temp.fill(Color(COLOR_BAR), Rect(0, i_step+1, TILE_X, 2))
            temp.fill(Color(COLOR_BAR_DARK), Rect(0, i_step+3, TILE_X, 1))
            i_step = i_step + 8
    return temp

class StairsBlock(Entity):

    def __init__(self, level_loaded: Level, x, y):
        Entity.__init__(self)
        self.collides = False
        self.has_grip = True
        self.item = False
        self.collectable = False
        self.transformed = False
        self.fly = False

        self.image = draw_procedural(level_loaded.TILE_X, level_loaded.TILE_Y)
        self.rect = Rect(x, y, level_loaded.TILE_X, level_loaded.TILE_Y)


#-*- coding: utf-8 -*-
from __future__ import print_function, absolute_import # For Py2 retrocompatibility
from builtins import str
from django.http import HttpResponse,Http404,JsonResponse
from django.shortcuts import render,redirect

# For the API
from django.views.decorators.csrf import csrf_exempt
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser

# Forthe database
from .models import Tweet,User,LdaModel,semanticField
from django.db import connection #for direct SQL requests
from django.db.models import Max

# For time and date processing
import random
from django.utils import timezone
import time
import pytz
from datetime import datetime

# Data Processing
from .extraction import *
from .semanticAnalysis import *
import string
import json
import ast # convert string to list
import math
from collections import Counter,defaultdict

# Decorators
from django.views.decorators.http import require_GET
#==============================#
#=========== OTHERS ===========#
#==============================#

def handler404(request,typed):
    """A basic 404 error handler"""
    return JsonResponse({"error":"Page "+typed+" not found"}, status=404)

@require_GET
def sources(request):
    """GET Tweets'sources for all or individual candidate"""
    # Getting tweets' sources
    global requestToGetSources

    # GET user and check if he exist
    userId = request.GET.get("id", "")
    try:
        if userId != "":
            User.objects.get(id=userId)
    except BaseException as e:
        return JsonResponse({"sources":-1,"num":-1,"error":str(e)}, status=500)

    cursor = connection.cursor()
    try:
        if userId == "":
            cursor.execute(requestToGetSources)
        else:
            cursor.execute("SELECT DISTINCT source, COUNT(source) AS nb FROM api_tweet WHERE user_id_id ='"+ str(userId)+"' GROUP BY source ORDER BY nb DESC")
    except BaseException as e: # No data in DB
        print("API - sources()\nError : ", e)
        return JsonResponse({"sources":-1,"num":-1,"error":str(e)}, status=500)
    res = cursor.fetchall()

    sources = []
    num = []
    for (s,n) in res:
        sources.append(s)
        num.append(n)

    # Keeping only the most commons stats
    if len(sources)>5 :
        sources = sources[0:5]
        sources.append("Others")
        num[5] = sum(num[5:-1])
        num = num[0:6]

    return JsonResponse({"sources":sources,"num":num}, status=200)

@require_GET
def userExist(request):
    # GET user and check if he exist
    userId = request.GET.get("id", "")
    if userId == "":
        return JsonResponse({"id":userId,"exist":False}, status=200)
    else:
        try:
            User.objects.get(id=userId)
        except BaseException as e:
            return JsonResponse({"id":userId,"exist":False}, status=200)
        return JsonResponse({"id":userId,"exist":True}, status=200)

@require_GET
def user(request):
    """GET candidate's informations such as followers_count, profile picture, profile description and screen name"""
    # GET user and check if he exist
    userId = request.GET.get("id", "")
    try:
        if userId != "":
            User.objects.get(id=userId)
    except BaseException as e:
        return JsonResponse({"users":-1,"error":str(e)}, status=500)

    cursor = connection.cursor()
    try:
        if userId == "":
            cursor.execute("SELECT id, screen_name, name, description, followers_count, verified, profile_image_url FROM api_user")
        else:
            cursor.execute("SELECT id, screen_name, name, description, followers_count, verified, profile_image_url FROM api_user WHERE id ='"+ str(userId)+ "'")
    except BaseException as e: # No data in DB
        print("API - userInfo()\nError : ", e)
        return JsonResponse({"users":-1,"error":str(e)}, status=500)
    res = cursor.fetchall()
    users = []
    for user in res:
        users.append({"id":user[0], "screen_name":user[1], "name": user[2], "description": user[3], "followers_count": user[4], "verified" : user[5], "profile_image_url": user[6].replace('_normal.jpg','.jpg')})

    return JsonResponse({"users":users}, status=200)

@require_GET
def nbTweets(request):
    """GET number of tweets for each candidates"""
    # Getting the number of tweets for each user
    cursor = connection.cursor()
    try:
        cursor.execute("SELECT u.name, COUNT(t.id) AS nbTweets FROM api_tweet t, api_user u WHERE u.id = t.user_id_id GROUP BY u.name ORDER BY nbTweets DESC")
    except BaseException as e: # No data in DB
        print("API - nbTweets()\nError : ", e)
        return JsonResponse({"politics":-1,"nbTweets":-1,"error":str(e)}, status=400)
    res = cursor.fetchall()

    politics = []
    nbTweets = []
    for (p,n) in res:
        politics.append(p)
        nbTweets.append(n)
    # JSON Formating
    return JsonResponse({"politics":politics,"nbTweets":nbTweets}, status=200)

@require_GET
def lastTweet(request):
    """GET date of the last tweet saved in DB"""
    # Getting the date of the last tweet
    try:
        lastTweetReq = Tweet.objects.aggregate(Max('id'))
        lastId = lastTweetReq["id__max"]
        lastTweet = Tweet.objects.get(id=lastId).created_at
    except BaseException as e:
        print("API - lestTweet()\nError : ", e)
        return JsonResponse({"lasttweet":-1,"error":str(e)}, status=500)

    return HttpResponse(lastTweet, status=200)

@require_GET
def hours(request):
    """GET tweets hours distribution for one or all candidates"""
    # GET user and check if he exist
    userId = request.GET.get("id", "")
    try:
        if userId != "":
            User.objects.get(id=userId)
    except BaseException as e:
        return JsonResponse({"hours":-1,"error":str(e)}, status=500)

    cursor = connection.cursor()
    try:
        if userId == "":
            cursor.execute("SELECT DISTINCT created_at AS timePosted FROM api_tweet ORDER BY timePosted")
        else:
            cursor.execute("SELECT DISTINCT created_at AS timePosted FROM api_tweet WHERE user_id_id ='"+ str(userId)+"'ORDER BY timePosted")
    except BaseException as e: # No data in DB
        print("API - hours()\nError : ", e)
        return JsonResponse({"hours":-1,"error":str(e)}, status=400)
    res = cursor.fetchall()

    hours =[0]*24
    for (time,) in res:
        hours[time.time().hour]+=1

    # JSON Formating
    return JsonResponse({"hours":hours}, status=200)

@require_GET
def wordCount(request):
    userId = request.GET.get("id", "")

    # tokenArray is stored as a string : we need to get the list back
    try:
        if userId == "":
            allTokenArray = Tweet.objects.values('tokenArray')
        else:
            allTokenArray = Tweet.objects.filter(user_id=userId).values('tokenArray')
    except BaseException as e:
        print("API - wordCount()\nError : ", e)
        return JsonResponse({"words":-1,"error":str(e)}, status=500)

    words = [ast.literal_eval(t["tokenArray"]) for t in allTokenArray]
    words = toJsonForGraph(countWords(words))

    # words is a JSON list of dict like : {"word":"foo", "occur":42}
    return JsonResponse({"words":words}, status=200)

@require_GET
def lemmeCount(request):
    userId = request.GET.get("id", "")

    # lemmaArray is stored as a string : we need to get the list back
    try:
        if userId == "":
            allLemmaArray = Tweet.objects.values('lemmaArray')
        else:
            allLemmaArray = Tweet.objects.filter(user_id=userId).values('lemmaArray')
    except BaseException as e:
        print("API - lemmeCount()\nError : ", e)
        return JsonResponse({"lemmes":-1,"error":str(e)}, status=500)

    lemmes = [ast.literal_eval(t["lemmaArray"]) for t in allLemmaArray]
    lemmes = toJsonForGraph(countWords(lemmes))

    # lemmes is a JSON list of dict like : {"word":"foo", "occur":42}
    return JsonResponse({"lemmes":lemmes}, status=200)

@require_GET
def ldaTopics(request):
    # GET user and check if he exist
    userId = request.GET.get("id", 0)

    # Get LDA topics distribution for table
    try :
        ldamodel = pickle.loads(LdaModel.objects.get(user_id=userId).ldamodel)
    except BaseException as e:
        print("API - ldaTopics()\nError : ", e)
        return JsonResponse({"ldaTopics":-1,"error":str(e)}, status=500)

    topics = ldamodel.show_topics(num_topics=-1, num_words=10, log=False, formatted=False)
    tableJson = {"label":"ldaTopics","topics":[]}
    for index, topic in enumerate(topics):
        tableJson["topics"].append({"label":topic[0],"words":[]})
        for word in topic[1]:
            tableJson["topics"][index]["words"].append({"label":word[0],"weight":math.floor(300*word[1])})

    return JsonResponse(tableJson, status=200)

@require_GET
def netTweets(request):
    # Get users and link them to semantic fields
    try:
        semanticField_db = semanticField.objects.all().values()
        users = User.objects.all().values("screen_name", "name")
        cursor = connection.cursor()
        cursor.execute("SELECT u.screen_name, COUNT(t.id) AS nbTweets FROM api_tweet t, api_user u WHERE u.id = t.user_id_id GROUP BY u.screen_name")
    except BaseException as e:
        print("API - netTweets()\nError : ", e)
        return JsonResponse({"error":str(e)}, status=500)

    tweetCount = dict(cursor.fetchall())
    # tweetCount['total'] = sum(tweetCount.values())

    network = {"nodes":[], "edges":[]}
    nodeId = 1
    edgeId = 1
    appendedNodes = dict()
    appendedThemes = dict()
    maxScore = 0

    # User nodes
    for user in users:
        network["nodes"].append({"id":nodeId,"label":user["name"],"screen_name":user["screen_name"],"size":50,"color":"#ff9800"})
        appendedNodes[user["screen_name"]] = nodeId
        nodeId += 1

    # Semantic theme nodes
    for semanticLine in semanticField_db:
        if semanticLine["baseWord"] not in appendedThemes:
            network["nodes"].append({"id":nodeId,"label":semanticLine["baseWord"],"weight":0,"size":50,"color":"#2196f3"})
            network["nodes"].append({"id":nodeId+1,"label":semanticLine["baseWord"],"size":10,"color":"#607d8b"})
            network["edges"].append({"id":edgeId,"source":nodeId,"target":nodeId+1,"weight":50,"color":"rgba(96,125,139,0.05)"})
            appendedThemes[semanticLine["baseWord"]] = nodeId
            appendedNodes[semanticLine["baseWord"]] = nodeId+1
            nodeId += 2
            edgeId += 1

        uScores = ast.literal_eval(semanticLine["usersScores"])
        for screen_name,score in uScores.items():
            if (score/tweetCount[screen_name]) > maxScore:
                maxScore = score/tweetCount[screen_name]

    # Associated semantic words nodes + links all those nodes together
    for semanticLine in semanticField_db:
        uScores = ast.literal_eval(semanticLine["usersScores"])
        if not all(score == 0 for score in uScores.values()):
            if semanticLine["word"] not in appendedNodes:
                network["nodes"].append({"id":nodeId,"label":semanticLine["word"],"size":10,"color":"#607d8b"})
                network["edges"].append({"id":edgeId,"source":appendedThemes[semanticLine["baseWord"]],"target":nodeId,"weight":50,"color":"rgba(96,125,139,0.05)"})
                appendedNodes[semanticLine["word"]] = nodeId
                nodeId += 1
            else:
                network["edges"].append({"id":edgeId,"source":appendedThemes[semanticLine["baseWord"]],"target":appendedNodes[semanticLine["word"]],"weight":50,"color":"rgba(96,125,139,0.05)"})
            edgeId += 1

            for screen_name,score in uScores.items():
                if score != 0:
                    computedWeigth = (score/tweetCount[screen_name]*90/maxScore)+10
                    network["edges"].append({"id":edgeId,"source":appendedNodes[screen_name],"target":appendedNodes[semanticLine["word"]],"weight":computedWeigth,"color":"rgba(255,152,0,0.01)"})
                    edgeId += 1

    return JsonResponse({"network":network}, status=200)

#==============================#
#===========  DATA  ===========#
#==============================#

def getData(request):
    """Save the latest tweets from all the users defined in screen_nameToExtract
     and stores info about a users in the database not already done"""
    global screen_nameToExtract
    global semanticWords

    # SAVING USERS
    for screen_name in screen_nameToExtract:
        print ("GET User info : "+screen_name)
        userInfo = returnUser(screen_name,toClean=True)

        if not(userInfo): #If the user doesn't exist
            success = False
            error = "The user doesn't exist"
            return JsonResponse({"res":{"success":success,"error":error}}, status=500)

        # Saving the user
        success = saveUser(userInfo)
        if not(success):
            error = "Error during saving in DB"
            return JsonResponse({"res":{"success":success,"error":error}}, status=500)

    # SAVING TWEETS
    lastId = 0
    nbTweets = 0 # number of extracted tweets

    for screen_name in screen_nameToExtract:
        print ("GET USER TWEETS : "+screen_name)
        try:
            idUser = User.objects.filter(screen_name=screen_name).values('id')[0]["id"]
        except BaseException as e : # If the user does not exist
            continue # continue with the next user

        try: # We try to get the id of the user's last tweet
            lastTweet = Tweet.objects.filter(user_id=idUser).aggregate(Max('id'))
            lastId = lastTweet["id__max"]
            if lastId == None: # No tweet in the data base
                lastId = 0
        except BaseException as e :
            return JsonResponse({"res":{"success":success,"error":error}}, status=500)

        # The important request here : returns the new tweets from the Twitter API
        tweets = returnTweetsMultiple(screen_name,lastId)

        lenghtTweets = len(tweets)
        nbTweets += lenghtTweets

        # After this operations each tweet in tweets contains 2 more fields : 'tokenArray' & 'lemmaArray'
        tweets = tokenizeAndLemmatizeTweets(tweets)

        # Saving tweets in database
        userFrom = User.objects.get(screen_name=screen_name)
        nbTweetsSaved = 1; #counter for printing
        for t in tweets:
            print ("SAVING {1} TWEETS FROM {0} ; {2:0.2f} %".format(screen_name,lenghtTweets,nbTweetsSaved/lenghtTweets*100))
            success = saveTweet(t,userFrom) and success
            nbTweetsSaved += 1;

    # MAKING LDA MODELS
    for screen_name in screen_nameToExtract:
        print ("MAKING LDA MODEL FOR : "+screen_name)
        try:
            idUser = User.objects.filter(screen_name=screen_name).values('id')[0]["id"]
        except BaseException as e : # If the user does not exist or table not present
            return JsonResponse({"res":{"success":success,"error":error}}, status=500)

        makeLdaModel(idUser)
    print("MAKING GLOBAL LDA MODEL")
    makeLdaModel(0)

    # POPULATING SEMANTIC FIELDS
    print("MAKING SEMANTIC FIELDS")
    semanticField.objects.all().delete()
    globalLemmesOccurences = {}
    # Pour chaque candidat, on compte l'occurence de ses lemmes à l'avance
    for screen_name in screen_nameToExtract:
        try:
            idUser = User.objects.filter(screen_name=screen_name).values('id')[0]["id"]
            allLemmaArray = Tweet.objects.filter(user_id=idUser).values("lemmaArray")
        except BaseException: # If the user does not exist or table to present
            continue # continue with the next user
        allLemmaArray = [ast.literal_eval(t["lemmaArray"]) for t in allLemmaArray]
        userLemmesOccurences = defaultdict(lambda: 0)
        for lemmaArray in allLemmaArray:
            currentOccurences = dict(Counter(lemmaArray))
            for k in list(currentOccurences.keys()):
                userLemmesOccurences[k] += currentOccurences[k]
        globalLemmesOccurences[screen_name] = userLemmesOccurences
    # Pour chaque mot de base, on cherche le champs lexical associé
    for baseWord in semanticWords:
        semanticFieldTable = getSemanticField(baseWord)
        # Pour chaque mot du champ lexical, on regarde le nombre d'occurence pour chaque candidat et on sauvegarde
        for word in semanticFieldTable:
            wordOccur = {}
            for screen_name in screen_nameToExtract:
                wordOccur[screen_name] = globalLemmesOccurences[screen_name][word]
            semanticField_db = semanticField()
            semanticField_db.baseWord = baseWord
            semanticField_db.word = word
            semanticField_db.usersScores = wordOccur
            try:
                semanticField_db.save()
            except BaseException as e:
                print("getData() ; error in making semantic fields : ", e)

    print("\nEVERYTHING DONE !")
    return JsonResponse({"res":{"success":success,"error":0}}, status=200)


class Circle:
    def __init__(self, x, y, r):
        self.x = x
        self.y = y
        self.r = r
        self.number = 1
        self.row = None
        self.column = None

newcircle = Circle(33, 21, 10)
realCircles = [newcircle]

rows = [10, 20 ,30]

for circle in realCircles:
        for i in range(0, len(rows)):
            if 10 < circle.y and circle.y < 20:
                circle.row = i
            else:
                circle.row = None
            if 30 < circle.x and circle.x < 40:
                circle.column = i
            else:
                circle.column = None
            print(circle.row, circle.column)


# variáveis

#numeros
velocidade_internet = 10
print(velocidade_internet)

#valores float
nota_filme = 8.5

#valores boleanos
sessao_iniciou = True

#Strings
nome_curso = 'python_logic'

'''Como variáveis sao usadas em projetos reais?'''

#setar variaveis e pegar valores
salario_mes = input('Qual seu salário mensal? ')
horas_trabalhadas = input('Qual quantidade horas trabalhadas? ')
#definir valor hora
valor_hora = int(salario_mes) / int(horas_trabalhadas)
#mostrar resultado
print(valor_hora)


def getPrime():
    primes = [2, 3]
    i = 0  # i表示下次发射的质数
    while True:
        # 生成一个新的质因数
        if i == len(primes):
            n = primes[-1] + 2
            while True:
                for prime in primes:
                    if n % prime == 0:
                        break
                else:
                    primes.append(n)
                    break
                n += 2
        yield primes[i]
        i += 1

def factor(n):
    res = []
    primeGen = getPrime()
    while n != 1:
        prime = next(primeGen)
        while n % prime == 0:
            res.append(prime)
            n //= prime
    return res

n = int(input())
print("{}={}".format(n, "*".join(map(str, factor(n)))))


import RPi.GPIO as GPIO
import time

def feed():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(18, GPIO.OUT)

    try:
        servo = GPIO.PWM(18,50)
        servo.start(2.5)
        time.sleep(0.44)

    finally:
        servo.stop()
        GPIO.cleanup()

def feedSnack():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(18, GPIO.OUT)

    try:
        servo = GPIO.PWM(18,50)
        servo.start(2.5)
        time.sleep(.22)

    finally:
        servo.stop()
        GPIO.cleanup()

if __name__ == '__main__':
    feed()


M=float(input("\nDime el valor total de la compra "))
if (M>5000000):
    F=float(M*0.55)
    C=float(M*0.25)
    P=float(M*0.30)
    I=float(C*0.20)
else:
    F=float(M*0.70)
    C=float(M*0.30)
    I=float(C*0.20)
    P=0
print(f"Los fondos utilizados de la empresa son: {F}")
print(f"El credito al fabricante es de: {C}")
print(f"Por intereses del fabricante se tiene: {I}")
print(f"El prestamo del banco es de: {P}")

Taller estructuras de control selectivas/ejercicio4.py


import os
import pytest

from slack_sdk import WebClient
from slack_bolt import App

@pytest.fixture
def mocked_slack_app(monkeypatch):
    signing_secret = "secret"
    valid_token = "xoxb-valid"
    mock_api_server_base_url = "http://localhost:8888"

    web_client = WebClient(
        token=valid_token,
        base_url=mock_api_server_base_url
    )
    app = App(
        client=web_client,
        signing_secret=signing_secret
    )

    monkeypatch.setattr('slack_bolt.App', app)


#   Crie um programa que tenha uma função chamada "voto()" que vai receber
#   como parâmetro o ano de nascimento de uma pessoa, retornando um valor literal
#   indicando se a pessoa tem voto NEGADO, OPCIONAL ou OBRIGATÓRIO nas eleições.

#   FUNÇÕES UTILIZADAS NA ESTÉTICA DO PROGRAMA
cor = {'azul': '\033[1:34m',
         'red': '\033[1:31m',
         'verde':'\033[1:32m',
         'amarelo': '\033[1:33m',
         'negrito': '\033[1m',
         'cls': '\033[m'}
def título(txt):
    print(f'{cor["amarelo"]}-={cor["cls"]}' * 25)
    print(f"{cor['verde']}{txt:^50}{cor['cls']}")
    print(f'{cor["amarelo"]}-={cor["cls"]}' * 25)

#   CABEÇALHO APENAS PARA EFEITOS VISUAIS
título('FUNÇÕES PARA VOTAÇÃO')

#   INÍCIO DO PROGRAMA

def voto(num):
    from datetime import date
    idade = date.today().year - num
    if idade < 16:
        return f'Com {idade} anos: NÃO VOTA.'
    elif 18 < idade < 65:
        return f'Com {idade} anos: VOTO OBRIGATÓRIO.'
    elif idade > 65 or 15 < idade < 18:
        return f'Com {idade} anos: VOTO OPCIONAL'

ano = int(input('INFORME O ANO DE NASCIMENTO: '))
print(voto(ano))


from __future__ import annotations
from .base import *

def _find_close_token(token_list: list[str], character: str, start_index: int = 0) -> int:
    open_token = character + '('
    close_token = character + ')'
    assert token_list[start_index] == open_token, 'Invalid program'
    parentheses = 1
    for i, t in enumerate(token_list[start_index+1:]):
        if t == open_token:
            parentheses += 1
        elif t == close_token:
            parentheses -= 1
        if parentheses == 0:
            return i + 1 + start_index
    raise Exception('Invalid program')

def _str_to_node(token_list: list[str]) -> Node:
    if len(token_list) == 0:
        return EmptyStatement()

    capitalized = token_list[0][0].upper() + token_list[0][1:]
    if capitalized in [c.__name__ for c in TerminalNode.__subclasses__()]:
        if len(token_list) > 1:
            s1 = globals()[capitalized]()
            s2 = _str_to_node(token_list[1:])
            return Conjunction.new(s1, s2)
        return globals()[capitalized]()

    if token_list[0] == '<HOLE>':
        if len(token_list) > 1:
            s1 = None
            s2 = _str_to_node(token_list[1:])
            return Conjunction.new(s1, s2)
        return None

    if token_list[0] == 'DEF':
        assert token_list[1] == 'run', 'Invalid program'
        assert token_list[2] == 'm(', 'Invalid program'
        assert token_list[-1] == 'm)', 'Invalid program'
        m = _str_to_node(token_list[3:-1])
        return Program.new(m)

    elif token_list[0] == 'IF':
        c_end = _find_close_token(token_list, 'c', 1)
        i_end = _find_close_token(token_list, 'i', c_end+1)
        c = _str_to_node(token_list[2:c_end])
        i = _str_to_node(token_list[c_end+2:i_end])
        if i_end == len(token_list) - 1:
            return If.new(c, i)
        else:
            return Conjunction.new(
                If.new(c, i),
                _str_to_node(token_list[i_end+1:])
            )
    elif token_list[0] == 'IFELSE':
        c_end = _find_close_token(token_list, 'c', 1)
        i_end = _find_close_token(token_list, 'i', c_end+1)
        assert token_list[i_end+1] == 'ELSE', 'Invalid program'
        e_end = _find_close_token(token_list, 'e', i_end+2)
        c = _str_to_node(token_list[2:c_end])
        i = _str_to_node(token_list[c_end+2:i_end])
        e = _str_to_node(token_list[i_end+3:e_end])
        if e_end == len(token_list) - 1:
            return ITE.new(c, i, e)
        else:
            return Conjunction.new(
                ITE.new(c, i, e),
                _str_to_node(token_list[e_end+1:])
            )
    elif token_list[0] == 'WHILE':
        c_end = _find_close_token(token_list, 'c', 1)
        w_end = _find_close_token(token_list, 'w', c_end+1)
        c = _str_to_node(token_list[2:c_end])
        w = _str_to_node(token_list[c_end+2:w_end])
        if w_end == len(token_list) - 1:
            return While.new(c, w)
        else:
            return Conjunction.new(
                While.new(c, w),
                _str_to_node(token_list[w_end+1:])
            )
    elif token_list[0] == 'REPEAT':
        n = _str_to_node([token_list[1]])
        r_end = _find_close_token(token_list, 'r', 2)
        r = _str_to_node(token_list[3:r_end])
        if r_end == len(token_list) - 1:
            return Repeat.new(n, r)
        else:
            return Conjunction.new(
                Repeat.new(n, r),
                _str_to_node(token_list[r_end+1:])
            )

    elif token_list[0] == 'not':
        assert token_list[1] == 'c(', 'Invalid program'
        assert token_list[-1] == 'c)', 'Invalid program'
        c = _str_to_node(token_list[2:-1])
        return Not.new(c)
    elif token_list[0] == 'and':
        c1_end = _find_close_token(token_list, 'c', 1)
        assert token_list[c1_end+1] == 'c(', 'Invalid program'
        assert token_list[-1] == 'c)', 'Invalid program'
        c1 = _str_to_node(token_list[2:c1_end])
        c2 = _str_to_node(token_list[c1_end+2:-1])
        return And.new(c1, c2)
    elif token_list[0] == 'or':
        c1_end = _find_close_token(token_list, 'c', 1)
        assert token_list[c1_end+1] == 'c(', 'Invalid program'
        assert token_list[-1] == 'c)', 'Invalid program'
        c1 = _str_to_node(token_list[2:c1_end])
        c2 = _str_to_node(token_list[c1_end+2:-1])
        return Or.new(c1, c2)

    elif token_list[0].startswith('R='):
        num = int(token_list[0].replace('R=', ''))
        assert num is not None
        return ConstIntNode.new(num)
    else:
        raise Exception(f'Unrecognized token: {token_list[0]}.')

def _node_to_str(node: Node) -> str:
    if node is None:
        return '<HOLE>'

    if node.__class__ == ConstIntNode:
        return 'R=' + str(node.value)
    if node.__class__ == ConstBoolNode:
        return str(node.value)
    if node.__class__ in TerminalNode.__subclasses__():
        return node.name

    if node.__class__ == Program:
        m = _node_to_str(node.children[0])
        return f'DEF run m( {m} m)'

    if node.__class__ == While:
        c = _node_to_str(node.children[0])
        w = _node_to_str(node.children[1])
        return f'WHILE c( {c} c) w( {w} w)'
    if node.__class__ == Repeat:
        n = _node_to_str(node.children[0])
        r = _node_to_str(node.children[1])
        return f'REPEAT {n} r( {r} r)'
    if node.__class__ == If:
        c = _node_to_str(node.children[0])
        i = _node_to_str(node.children[1])
        return f'IF c( {c} c) i( {i} i)'
    if node.__class__ == ITE:
        c = _node_to_str(node.children[0])
        i = _node_to_str(node.children[1])
        e = _node_to_str(node.children[2])
        return f'IFELSE c( {c} c) i( {i} i) ELSE e( {e} e)'
    if node.__class__ == Conjunction:
        s1 = _node_to_str(node.children[0])
        s2 = _node_to_str(node.children[1])
        return f'{s1} {s2}'

    if node.__class__ == Not:
        c = _node_to_str(node.children[0])
        return f'not c( {c} c)'
    if node.__class__ == And:
        c1 = _node_to_str(node.children[0])
        c2 = _node_to_str(node.children[1])
        return f'and c( {c1} c) c( {c2} c)'
    if node.__class__ == Or:
        c1 = _node_to_str(node.children[0])
        c2 = _node_to_str(node.children[1])
        return f'or c( {c1} c) c( {c2} c)'

class Parser:

    TOKENS = [
        'DEF', 'run', 'm(', 'm)', 'move', 'turnRight', 'turnLeft', 'pickMarker', 'putMarker',
        'r(', 'r)', 'R=0', 'R=1', 'R=2', 'R=3', 'R=4', 'R=5', 'R=6', 'R=7', 'R=8', 'R=9', 'R=10',
        'R=11', 'R=12', 'R=13', 'R=14', 'R=15', 'R=16', 'R=17', 'R=18', 'R=19', 'REPEAT', 'c(',
        'c)', 'i(', 'i)', 'e(', 'e)', 'IF', 'IFELSE', 'ELSE', 'frontIsClear', 'leftIsClear',
        'rightIsClear', 'markersPresent', 'noMarkersPresent', 'not', 'w(', 'w)', 'WHILE',
        '<pad>', '<HOLE>'
    ]

    T2I = {token: i for i, token in enumerate(TOKENS)}
    I2T = {i: token for i, token in enumerate(TOKENS)}

    @staticmethod
    def nodes_to_tokens(node: Node) -> list[int]:
        """Converts a complete program to a list of tokens"""
        return Parser.str_to_tokens(Parser.nodes_to_str(node))

    @staticmethod
    def tokens_to_nodes(prog_tokens: list[int]) -> Node:
        """Converts a list of tokens to a complete program"""
        return Parser.str_to_nodes(Parser.tokens_to_str(prog_tokens))

    @staticmethod
    def nodes_to_str(node: Node) -> str:
        """Converts a complete program to a string of tokens"""
        return _node_to_str(node)

    @staticmethod
    def str_to_nodes(prog_str: str) -> Node:
        token_list = prog_str.split(' ')
        return _str_to_node(token_list)

    @staticmethod
    def str_to_tokens(prog_str: str) -> list[int]:
        token_list = prog_str.split(' ')
        return [Parser.T2I[i] for i in token_list]

    @staticmethod
    def pad_tokens(prog_tokens: list[int], length: int) -> list[int]:
        return prog_tokens + [Parser.T2I['<pad>'] for _ in range(length - len(prog_tokens))]

    @staticmethod
    def tokens_to_str(prog_tokens: list[int]) -> str:
        token_list = [Parser.I2T[i] for i in prog_tokens]
        return ' '.join(token_list)


import torch.nn as nn

class SingleLayerClassifier(nn.Module):
    def __init__(self, input_size, hidden_size, number_of_classes, linear=False):
        super(SingleLayerClassifier, self).__init__()
        self.input_size = input_size
        self.hidden_size = hidden_size
        self.feature_extractor = FeatureExtractor(input_size, hidden_size, linear=linear)
        self.classifier = Classifier(self.hidden_size, number_of_classes, linear=linear)

    def forward(self, x):
        features = self.feature_extractor(x)
        output = self.classifier(features)
        return output

class FeatureExtractor(nn.Module):
    def __init__(self, input_size, hidden_size, linear=False):
        super(FeatureExtractor, self).__init__()
        self.input_size = input_size
        self.hidden_size = hidden_size
        self.linear_layer = nn.Linear(self.input_size, self.hidden_size)
        self.is_linear = linear
        if not linear:
            self.relu = nn.ReLU()

    def forward(self, x):
        projection = self.linear_layer(x)
        if self.is_linear:
            return projection

        features = self.relu(projection)
        return features

class Classifier(nn.Module):
    def __init__(self, feature_dim, num_classes, linear=False):
        super(Classifier, self).__init__()
        self.feature_dim = feature_dim
        self.num_classes = num_classes
        self.linear_layer = nn.Linear(feature_dim, num_classes)
        self.is_linear = linear
        if not self.is_linear:
            self.relu = nn.ReLU()

    def forward(self, x):
        projection = self.linear_layer(x)
        if self.is_linear:
            return projection
        classification = self.relu(projection)
        return classification


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

import group_sync

import unittest
from unittest import mock

class GroupSyncTest(unittest.TestCase):

  @mock.patch("auth_util.get_credentials")
  def test_get_group_members_as_list_cloud_identity(self, au):
    au.get_credentials.return_value = mock.MagicMock()
    gs = group_sync.GroupSync("admin@example.com", "example.com", True)

    gs.bq_client = mock.MagicMock()
    gs.service = mock.MagicMock()
    gs.service.groups().list().execute.return_value = {
        "groups": [{
            "name": "groups/test-group",
            "groupKey": {
                "id": "test-group",
                "namespace": "identitysources/example.com"
            },
            "parent": "identitysources/example.com",
            "displayName": "Test Group",
            "description": "Group for testing purposes",
            "createTime": "2019-02-11T11:49:28+0000",
            "updateTime": "2019-02-11T11:49:28+0000",
            "labels": {
                "labels/system/groups/external": "",
            }
        }],
        "nextPageToken": ""
    }
    gs.service.memberships().list().execute.return_value = {
        "memberships": [{
            "name": "groups/test-group/memberships/user1",
            "memberKey": {
                "id": "user1",
                "namespace": "identitysources/example.com"
            },
            "createTime": "2019-02-11T11:49:28+0000",
            "updateTime": "2019-02-11T11:49:28+0000",
            "roles": [{
                "name": "MEMBER"
            }]
        }],
        "nextPageToken": ""
    }

    all_group_members = gs.get_group_members_as_list()

    self.assertListEqual(all_group_members, [("test-group", "user1")])

if __name__ == "__main__":
  unittest.main()


from keras.models import Model
from keras.layers import Input, Conv1D, BatchNormalization, MaxPool1D, Conv2D, Deconv2D, Concatenate, Lambda, MaxPooling2D, ZeroPadding2D, Reshape, Activation, Conv2DTranspose
from keras import backend as K

from keras_layers.keras_layer_AnchorBoxes import AnchorBoxes
from keras_layers.keras_layer_L2Normalization import L2Normalization
from keras_layers.keras_layer_DecodeDetections import DecodeDetections
from keras_layers.keras_layer_DecodeDetectionsFast import DecodeDetectionsFast

D = 9
N = 100
C = 64

def make_pillar_feature_net():
    x = Input(shape=(N, D), name='input')
    conv_1 = Conv1D(filters=C, kernel_size=1, strides=1, activation='relu', name='conv_1')(x)
    bn_1 = BatchNormalization(name='bn_1')(conv_1)
    pool_1 = MaxPool1D(pool_size=100, strides=1, name='output')(bn_1)

    return Model(inputs=x, outputs=pool_1)

def make_backbone(width, height, feature_C):
    x = Input(shape=(height, width, feature_C), name='input')

    y = rpn_conv_block(x, feature_C, 3, name='rpn_conv1')
    y_deconv1 = Conv2DTranspose(2*feature_C, 3, strides=1, padding='same', name='rpn_deconv1')(y)
    y = rpn_conv_block(y, 2*feature_C, 5, name='rpn_conv2')
    y_deconv2 = Conv2DTranspose(2*feature_C, 2, strides=2, padding='same', name='rpn_deconv2')(y)
    y = rpn_conv_block(y, 4*feature_C, 5, name='rpn_conv3')
    y = Conv2DTranspose(2*feature_C, 4, strides=4, padding='same', name='rpn_deconv3')(y)
    y = Concatenate()([y, y_deconv2, y_deconv1])

    print (K.int_shape(y))

    return Model(inputs=x, outputs=ssd_300(y))

def _rpn_conv(x, cout, k, s, p, name, i=None):
    if i is not None:
        name += '_blk' + str(i)
    x = ZeroPadding2D(p, name=name + '_pad')(x)
    x = Conv2D(cout, k, strides=s, name=name + '_conv')(x)
    x = BatchNormalization(name=name + '_bn')(x)
    x = Activation('relu', name=name + '_relu')(x)
    return x

def rpn_conv_block(x, cout, q, name='rpn_conv'):
    x = _rpn_conv(x, cout, 3, 2, 1, name)
    for i in range(q):
        x = _rpn_conv(x, cout, 3, 1, 1, name, i + 1)
    return x

def ssd_300(x):
    n_classes = 2
    two_boxes_for_ar1 = True
    aspect_ratios_per_layer = [[1.0, 2.0, 0.5],
                               [1.0, 2.0, 0.5, 3.0, 1.0/3.0],
                                [1.0, 2.0, 0.5, 3.0, 1.0/3.0],
                                [1.0, 2.0, 0.5, 3.0, 1.0/3.0],
                                [1.0, 2.0, 0.5],
                                [1.0, 2.0, 0.5]]

    n_boxes = []
    for ar in aspect_ratios_per_layer:
        if (1 in ar) & two_boxes_for_ar1:
            n_boxes.append(len(ar) + 1)  # +1 for the second box for aspect ratio 1
        else:
            n_boxes.append(len(ar))

    conv1_1 = Conv2D(64, (3, 3), activation='relu', padding='same', name='conv1_1')(x)
    conv1_2 = Conv2D(64, (3, 3), activation='relu', padding='same', name='conv1_2')(conv1_1)
    pool1 = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), padding='same', name='pool1')(conv1_2)

    conv2_1 = Conv2D(128, (3, 3), activation='relu', padding='same', name='conv2_1')(pool1)
    conv2_2 = Conv2D(128, (3, 3), activation='relu', padding='same', name='conv2_2')(conv2_1)
    pool2 = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), padding='same', name='pool2')(conv2_2)

    conv3_1 = Conv2D(256, (3, 3), activation='relu', padding='same', name='conv3_1')(pool2)
    conv3_2 = Conv2D(256, (3, 3), activation='relu', padding='same', name='conv3_2')(conv3_1)
    conv3_3 = Conv2D(256, (3, 3), activation='relu', padding='same', name='conv3_3')(conv3_2)
    pool3 = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), padding='same', name='pool3')(conv3_3)

    conv4_1 = Conv2D(512, (3, 3), activation='relu', padding='same', name='conv4_1')(pool3)
    conv4_2 = Conv2D(512, (3, 3), activation='relu', padding='same', name='conv4_2')(conv4_1)
    conv4_3 = Conv2D(512, (3, 3), activation='relu', padding='same', name='conv4_3')(conv4_2)
    pool4 = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), padding='same', name='pool4')(conv4_3)

    conv5_1 = Conv2D(512, (3, 3), activation='relu', padding='same', name='conv5_1')(pool4)
    conv5_2 = Conv2D(512, (3, 3), activation='relu', padding='same', name='conv5_2')(conv5_1)
    conv5_3 = Conv2D(512, (3, 3), activation='relu', padding='same', name='conv5_3')(conv5_2)
    pool5 = MaxPooling2D(pool_size=(3, 3), strides=(1, 1), padding='same', name='pool5')(conv5_3)

    fc6 = Conv2D(1024, (3, 3), dilation_rate=(6, 6), activation='relu', padding='same', name='fc6')(pool5)

    fc7 = Conv2D(1024, (1, 1), activation='relu', padding='same', name='fc7')(fc6)

    conv6_1 = Conv2D(256, (1, 1), activation='relu', padding='same', name='conv6_1')(fc7)
    conv6_1 = ZeroPadding2D(padding=((1, 1), (1, 1)), name='conv6_padding')(conv6_1)
    conv6_2 = Conv2D(512, (3, 3), strides=(2, 2), activation='relu', padding='valid', name='conv6_2')(conv6_1)

    conv7_1 = Conv2D(128, (1, 1), activation='relu', padding='same', name='conv7_1')(conv6_2)
    conv7_1 = ZeroPadding2D(padding=((1, 1), (1, 1)), name='conv7_padding')(conv7_1)
    conv7_2 = Conv2D(256, (3, 3), strides=(2, 2), activation='relu', padding='valid', name='conv7_2')(conv7_1)

    conv8_1 = Conv2D(128, (1, 1), activation='relu', padding='same', name='conv8_1')(conv7_2)
    conv8_2 = Conv2D(256, (3, 3), strides=(1, 1), activation='relu', padding='valid', name='conv8_2')(conv8_1)

    conv9_1 = Conv2D(128, (1, 1), activation='relu', padding='same', name='conv9_1')(conv8_2)
    conv9_2 = Conv2D(256, (3, 3), strides=(1, 1), activation='relu', padding='valid', name='conv9_2')(conv9_1)

    # Feed conv4_3 into the L2 normalization layer
    conv4_3_norm = L2Normalization(gamma_init=20, name='conv4_3_norm')(conv4_3)

    conv4_3_norm_mbox_conf = Conv2D(n_boxes[0] * n_classes, (3, 3), padding='same', name='conv4_3_norm_mbox_conf')(conv4_3_norm)
    fc7_mbox_conf = Conv2D(n_boxes[1] * n_classes, (3, 3), padding='same', name='fc7_mbox_conf')(fc7)
    conv6_2_mbox_conf = Conv2D(n_boxes[2] * n_classes, (3, 3), padding='same', name='conv6_2_mbox_conf')(conv6_2)
    conv7_2_mbox_conf = Conv2D(n_boxes[3] * n_classes, (3, 3), padding='same', name='conv7_2_mbox_conf')(conv7_2)
    conv8_2_mbox_conf = Conv2D(n_boxes[4] * n_classes, (3, 3), padding='same', name='conv8_2_mbox_conf')(conv8_2)
    conv9_2_mbox_conf = Conv2D(n_boxes[5] * n_classes, (3, 3), padding='same', name='conv9_2_mbox_conf')(conv9_2)
    # We predict 4 box coordinates for each box, hence the localization predictors have depth `n_boxes * 4`
    # Output shape of the localization layers: `(batch, height, width, n_boxes * 4)`
    conv4_3_norm_mbox_loc = Conv2D(n_boxes[0] * 4, (3, 3), padding='same', name='conv4_3_norm_mbox_loc')(conv4_3_norm)
    fc7_mbox_loc = Conv2D(n_boxes[1] * 4, (3, 3), padding='same', name='fc7_mbox_loc')(fc7)
    conv6_2_mbox_loc = Conv2D(n_boxes[2] * 4, (3, 3), padding='same', name='conv6_2_mbox_loc')(conv6_2)
    conv7_2_mbox_loc = Conv2D(n_boxes[3] * 4, (3, 3), padding='same', name='conv7_2_mbox_loc')(conv7_2)
    conv8_2_mbox_loc = Conv2D(n_boxes[4] * 4, (3, 3), padding='same', name='conv8_2_mbox_loc')(conv8_2)
    conv9_2_mbox_loc = Conv2D(n_boxes[5] * 4, (3, 3), padding='same', name='conv9_2_mbox_loc')(conv9_2)

    conv4_3_norm_mbox_conf_reshape = Reshape((-1, n_classes), name='conv4_3_norm_mbox_conf_reshape')(
        conv4_3_norm_mbox_conf)
    fc7_mbox_conf_reshape = Reshape((-1, n_classes), name='fc7_mbox_conf_reshape')(fc7_mbox_conf)
    conv6_2_mbox_conf_reshape = Reshape((-1, n_classes), name='conv6_2_mbox_conf_reshape')(conv6_2_mbox_conf)
    conv7_2_mbox_conf_reshape = Reshape((-1, n_classes), name='conv7_2_mbox_conf_reshape')(conv7_2_mbox_conf)
    conv8_2_mbox_conf_reshape = Reshape((-1, n_classes), name='conv8_2_mbox_conf_reshape')(conv8_2_mbox_conf)
    conv9_2_mbox_conf_reshape = Reshape((-1, n_classes), name='conv9_2_mbox_conf_reshape')(conv9_2_mbox_conf)
    # Reshape the box predictions, yielding 3D tensors of shape `(batch, height * width * n_boxes, 4)`
    # We want the four box coordinates isolated in the last axis to compute the smooth L1 loss
    conv4_3_norm_mbox_loc_reshape = Reshape((-1, 4), name='conv4_3_norm_mbox_loc_reshape')(conv4_3_norm_mbox_loc)
    fc7_mbox_loc_reshape = Reshape((-1, 4), name='fc7_mbox_loc_reshape')(fc7_mbox_loc)
    conv6_2_mbox_loc_reshape = Reshape((-1, 4), name='conv6_2_mbox_loc_reshape')(conv6_2_mbox_loc)
    conv7_2_mbox_loc_reshape = Reshape((-1, 4), name='conv7_2_mbox_loc_reshape')(conv7_2_mbox_loc)
    conv8_2_mbox_loc_reshape = Reshape((-1, 4), name='conv8_2_mbox_loc_reshape')(conv8_2_mbox_loc)
    conv9_2_mbox_loc_reshape = Reshape((-1, 4), name='conv9_2_mbox_loc_reshape')(conv9_2_mbox_loc)
    # Reshape the anchor box tensors, yielding 3D tensors of shape `(batch, height * width * n_boxes, 8)`

    mbox_conf = Concatenate(axis=1, name='mbox_conf')([conv4_3_norm_mbox_conf_reshape,
                                                       fc7_mbox_conf_reshape,
                                                       conv6_2_mbox_conf_reshape,
                                                       conv7_2_mbox_conf_reshape,
                                                       conv8_2_mbox_conf_reshape,
                                                       conv9_2_mbox_conf_reshape])

    mbox_loc = Concatenate(axis=1, name='mbox_loc')([conv4_3_norm_mbox_loc_reshape,
                                                     fc7_mbox_loc_reshape,
                                                     conv6_2_mbox_loc_reshape,
                                                     conv7_2_mbox_loc_reshape,
                                                     conv8_2_mbox_loc_reshape,
                                                     conv9_2_mbox_loc_reshape])

    mbox_conf_softmax = Activation('softmax', name='mbox_conf_softmax')(mbox_conf)
    predictions = Concatenate(axis=2, name='predictions')([mbox_conf_softmax, mbox_loc])
    return predictions

if __name__ == '__main__':

    # pillar_feature_net_model = make_pillar_feature_net()
    # pillar_feature_net_model.summary()

    backbone_model = make_backbone(440, 800, 64)
    backbone_model.summary()


import pygame
from player import *
from pygame.locals import (
    K_UP,
    K_DOWN,
    K_LEFT,
    K_RIGHT,
    K_ESCAPE,
    KEYDOWN,
    QUIT,
)

SCREEN_SIZE = [1080, 720]
screen = pygame.display.set_mode(SCREEN_SIZE)

def main():
    pygame.init()
    player = Player()
    running = True

    while running:

        # Check for events
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

        # Update player position
        pressed_keys = pygame.key.get_pressed()
        player.update(pressed_keys, SCREEN_SIZE)

        # Update screen
        screen.fill((128, 200, 128))
        screen.blit(player.surf, player.rect)
        pygame.display.flip()

    pygame.quit()

if __name__ == '__main__':
    main()


#WIP
import pandas as pd
import sqlite3
import os
from datetime import datetime

path = os.getcwd()
print(path)
print("Beginning connection...")
con = sqlite3.connect("ChatStorage.sqlite")
print("Connection successful, querying...")
tables = pd.read_sql_query("SELECT name FROM sqlite_master WHERE type='table'", con)
print("Query ok, showing high level tables...")
print(tables)
print("Querying for available messages...")
df = pd.read_sql_query("SELECT * from ZWAMESSAGE", con)
print("Query ok, showing message info...")
print('\n'.join([str(i+1)+' '+x for i, x in enumerate(df.columns)]))
#print(datetime.fromtimestamp(df.ZMESSAGEDATE.iloc[0]))
timestamp_to_apple = lambda x: datetime.fromtimestamp(x) + (datetime(2001,1,1) - datetime.fromtimestamp(0))
#print(df.ZMESSAGEDATE.iloc[0])
#print(timestamp_to_apple(df.ZMESSAGEDATE.iloc[0]))
#Methods for searching for messages
get_df_by_number = lambda df, num: df[df.ZTOJID.str.contains(num).fillna(False) | df.ZFROMJID.str.contains(num).fillna(False)]
get_df_by_contact_name = lambda df, name: df[df.ZPUSHNAME.str.contains(name).fillna(False)]
get_df_by_chat_session_id = lambda df, sid: df[df.ZCHATSESSION == sid]
grep_for_message_text = lambda df, txt: df[df.ZTEXT.str.contains(txt).fillna(False)]

print("Making dates human readable from WhatsApp")
df['Date'] = df.ZMESSAGEDATE.apply(timestamp_to_apple)
df.index = df.Date
df = df.sort_index()
df.head()

df2 = get_df_by_number(df, '7')
print(len(df2))
print(list(df2.ZTEXT))

df3 = pd.read_sql_query("SELECT ZPUSHNAME from ZWAMESSAGE", con)

#print(df3)
#print('\n'.join([str(i+1)+' '+x for i, x in enumerate(df3.)]))
print(len(df3))

print("Closing connection...")
con.close()


# The selenium module
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

import requests, time, re
import ExcelOperations as EO
from bs4 import BeautifulSoup
import DownloadImage as downloader

already_found_url = []

def get_html(url):
    error_count = 0
    error = True
    page_obj = None
    while error and error_count < 3:
        try:
            r = requests.get(url, headers={'User-Agent': 'Mozilla/5.0'}, timeout=30)
            r.encoding = "utf-8"
            page = r.text
            page_obj = BeautifulSoup(page, "lxml")
            error = False
        except:
            error = True
            error_count = error_count + 1
            print("%s URL not accessible " % (url))

    return page_obj

def get_alphabets_unit(value):
    only_alpha = ""
    for char in value:
        if char.isalpha():
            only_alpha += char
    return only_alpha

def convert_to_standard_unit(value):
    non_decimal = re.compile(r'[^\d.-]+')
    unit = get_alphabets_unit(value).strip()
    try:
        if unit.lower() == "kg":
            return value
        elif unit.lower() == "cm":
            return value
        elif unit.lower() == "g":
            value = non_decimal.sub('', value).strip()
            if "." in value:
                value = str(float(value) / 1000) + "kg"
            else:
                value = str(int(value) / 1000) + "kg"
        elif unit.lower() == "mm":
            value = non_decimal.sub('', value).strip()
            if "." in value:
                value = str(float(value) / 10) + "cm"
            else:
                value = str(int(value) / 10) + "cm"
        elif unit.lower() == "m":
            value = non_decimal.sub('', value).strip()
            if "." in value:
                value = str(float(value) * 100) + "cm"
            else:
                value = str(int(value) * 100) + "cm"
    except Exception as e:
        pass
    return value

def increase_price_15_percent(price):
    price = price.replace("£", "").strip()
    price = float(price)
    price = price + (price * 0.15)
    return "£" + str(price)

def scrape_product(driver, main_cat, cat_name, cat_link, sub_cat_name, sub_cat_link, sub_sub_cat_name, sub_sub_cat_link, product_title, product_link, start_url):
    try:
        driver.get(product_link)
        time.sleep(1)
        page_obj = BeautifulSoup(driver.page_source, "lxml")
        if page_obj is not None:
            product_price = page_obj.find("div", attrs={"data-test-id": "product-primary-price"}).text.strip().replace("\n", "").replace(",", "").replace('"', '').strip()
            product_price = increase_price_15_percent(product_price)
            product_details_section = page_obj.find("section", attrs={"class": "_2cf5ecfb _042bbf7f"})
            product_details_section = product_details_section.find("div", attrs={"class": "fef30cae _5e7ce7a9 _461d0ef9 d4281212"})
            #product_details_div = product_details_section.find("div", attrs={"data-test-id": "ProductDescText"})
            product_info_section = product_details_section.findAll("div", attrs={"class": "_7be6e5a0 _66dabd6a e0657c31"})
            product_details_div = product_info_section[0]
            spec_table = product_details_section.find("table", attrs={"class": "f16ac490 eddf1b8e"}).find("tbody").findAll("tr")
            spec_table_html = str(product_info_section[-1])
            special_fields = {}
            for data in spec_table:
                heading = data.find("th").text.replace("\n", "").replace(",", "").replace('"', '').replace("|", "").replace("#", "").strip()
                val = data.find("td").text.replace("\n", "").replace(",", "").replace('"', '').replace("|", "").replace("#", "").strip()
                value = convert_to_standard_unit(val)
                if val != value:
                    spec_table_html = spec_table_html.replace(val, value)
                if "height" in heading.lower():
                    special_fields["height"] = value
                elif "length" in heading.lower():
                    special_fields["length"] = value
                elif "weight" in heading.lower():
                    special_fields["weight"] = value
                elif "width" in heading.lower():
                    special_fields["width"] = value
                elif "thickness" in heading.lower():
                    special_fields["thickness"] = value
                elif "diameter" in heading.lower():
                    special_fields["diameter"] = value
                elif "depth" in heading.lower():
                    special_fields["depth"] = value
                elif "mesh size" in heading.lower():
                    special_fields["mesh size"] = value
                elif "product code" in heading.lower():
                    special_fields["code"] = value

            spec_table_html = spec_table_html.replace(",", "")

            try:
                #images_div = page_obj.findAll("div", attrs={"class": "slick-list"})[-1]
                images_div = page_obj.findAll("div", attrs={"class": "slick-list"})[0]
                images_list = images_div.findAll("img")
                list_images = []
                for img in images_list:
                    list_images.append(img.attrs["src"])
                list_images = list(set(list_images))
                while len(list_images) < 5:
                    list_images.append("")
            except Exception as e:
                list_images = ["", "", "", "", ""]

            list_images_names = []
            for x in range(0, 5):
                if list_images[x] is not "":
                    file_name = special_fields["code"] + "_img_" + str(x)
                    file_name = downloader.download_image(list_images[x], file_name)
                    list_images_names.append(file_name)
                else:
                    list_images_names.append("")

            try:
                try:
                    product_details_div.find("button").decompose()
                except:
                    pass
                product_info = str(product_details_div).replace(",", "")
                product_feat = ""
            except:
                product_info = ""
                product_feat = ""
            print("=> Scraped product = " + product_title)
            EO.write_excel_file(main_cat, cat_name, sub_cat_name, sub_sub_cat_name, product_title, product_price, list_images_names, spec_table_html, special_fields, product_info)
    except Exception as e:
        print(e)

def scrape_products_list(CHROME_PATH, start_url, base_url, main_cat, cat_name, cat_link, sub_cat_name, sub_cat_link, sub_sub_cat_name, sub_sub_cat_link, products_page_link):
    link_to_go = products_page_link
    if link_to_go in already_found_url:
        print("Already scraped => " + link_to_go)
    else:
        WINDOW_SIZE = "1920,1080"
        CHROME_DRIVER_PATH = "ChromDriver/chromedriver"
        driver = None
        chrome_options = Options()
        # chrome_options.add_argument("--headless")
        chrome_options.add_argument("--window-size=%s" % WINDOW_SIZE)
        chrome_options.binary_location = CHROME_PATH
        chrome_options.add_argument('disable-infobars')
        chrome_options.add_argument("disable-notifications")
        driver = webdriver.Chrome(executable_path=CHROME_DRIVER_PATH, options=chrome_options)
        try:
            driver.get(link_to_go)
            driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
            time.sleep(2)
            execute = True
            counter = 0
            loading = True
            try:
                load_more = driver.find_element_by_xpath('//*[@id="content"]/div/div[1]/div/div/div[2]/div[3]/div/div[3]/div[2]/main/div/a[2]')
            except:
                loading = False
                load_more = None
            if loading:
                while execute or counter < 3:
                    try:
                        driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
                        load_more.click()
                        time.sleep(1)
                        driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
                        time.sleep(3)
                        counter = 0
                        execute = True
                    except:
                        execute = False
                        counter = counter + 1
            page_obj = BeautifulSoup(driver.page_source, 'lxml')
            products_div = page_obj.findAll("ul", attrs={"class": "_40158784 _6b5bb6a7 _190cafcd"})[0]
            products_list = products_div.findAll("li", attrs={"class": "b9bdc658"})
            for product in products_list:
                try:
                    a_tag = product.find("a", attrs={"data-test-id": "product-panel-main-section"})
                    product_title = a_tag.find("p", attrs={"data-test-id": "productTitle"}).text.replace("\n", "").replace("\r", "").replace(",", "").replace('"', '').strip()
                    product_link = base_url + a_tag.attrs["href"]
                    scrape_product(driver, main_cat, cat_name, cat_link, sub_cat_name, sub_cat_link, sub_sub_cat_name, sub_sub_cat_link, product_title, product_link, start_url)
                except Exception as e:
                    pass
        except Exception as e:
            print(e)
        finally:
            driver.close()
            already_found_url.append(link_to_go)

def scrape_sub_categories(main_cat, cat_name, cat_link, sub_cat_name, sub_cat_link, CHROME_PATH, start_url, base_url):
    page_obj = get_html(sub_cat_link)
    if page_obj is not None:
        try:
            #sub_sub_categories = page_obj.findAll("div", attrs={"class": "sc-1ulaoyw-0 fqZatT"})[0]
            #sub_sub_categories = sub_sub_categories.find("div", attrs={"data-test-id": "grid-sections"})
            #sub_sub_categories_list = sub_sub_categories.findAll("a", attrs={"class": "sc-cnb8ll-0 hHvddy"})

            sub_sub_categories_list = page_obj.findAll("ul", attrs={"id": "side-navigation-menu-1"})[0].findAll("li")

            for sub_sub_cat in sub_sub_categories_list:
                try:
                    a_tag = sub_sub_cat.find("a")
                    sub_sub_cat_name = a_tag.text.replace("\n", "").replace("\r", "").replace(",", "").replace('"', '').strip()
                    #sub_sub_cat_name = sub_sub_cat.find("div", attrs={"data-test-id": "category-tile-content"}).find("h3").text.replace("\n", "").replace("\r", "").replace(",", "").replace('"', '').strip()
                    #sub_sub_cat_link = base_url + sub_sub_cat.attrs["href"]
                    sub_sub_cat_link = base_url + a_tag.attrs["href"]
                    print("Sub Sub Category = " + sub_sub_cat_name)
                    scrape_products_list(CHROME_PATH, start_url, base_url, main_cat, cat_name, cat_link, sub_cat_name, sub_cat_link, sub_sub_cat_name, sub_sub_cat_link, sub_sub_cat_link)
                except Exception as e:
                    pass
        except:
            print("Sub Sub Category = ")
            scrape_products_list(CHROME_PATH, start_url, base_url, main_cat, cat_name, cat_link, sub_cat_name, sub_cat_link, "", "", sub_cat_link)

def scrape_categories(main_cat, cat_name, cat_url, CHROME_PATH, start_url, base_url):
    page_obj = get_html(cat_url)
    if page_obj is not None:
        try:
            #sub_categories = page_obj.findAll("div", attrs={"class": "sc-1ulaoyw-0 fqZatT"})[0]
            #sub_categories = sub_categories.find("div", attrs={"data-test-id": "grid-sections"})
            #sub_categories_list = sub_categories.findAll("a", attrs={"class": "sc-cnb8ll-0 hHvddy"})

            ####
            sub_categories_list = page_obj.findAll("ul", attrs={"id": "side-navigation-menu-1"})[0].findAll("li")
            for sub_cat in sub_categories_list:
                try:
                    a_tag = sub_cat.find("a")
                    # sub_cat_name = sub_cat.find("div", attrs={"data-test-id": "category-tile-content"}).find("h3").text.replace("\n", "").replace("\r", "").replace(",", "").replace('"', '').strip()
                    sub_cat_name = a_tag.text.replace("\n", "").replace("\r", "").replace(",", "").replace('"',
                                                                                '').strip()
                    # sub_cat_link = base_url + sub_cat.attrs["href"]
                    sub_cat_link = base_url + a_tag.attrs["href"]
                    print("Sub Category = " + sub_cat_name)
                    scrape_sub_categories(main_cat, cat_name, cat_url, sub_cat_name, sub_cat_link, CHROME_PATH,
                                          start_url, base_url)
                except Exception as e:
                    pass
        except:
            print("Sub Sub Category = ")
            scrape_products_list(CHROME_PATH, start_url, base_url, main_cat, cat_name, cat_url, "",
                                 "", "", "", cat_url)


import resolve_condition

def replace_condition(tab_tmp,tab,x,y):
    tmp = resolve_rule(tab_tmp)
    tab.insert(x,tmp[0])
    del(tab[x+1:y+2])
    return(tab)

def handle_parentheses(tab):
    if ('('  in tab):
        x = 0
        while(x < len(tab)):
            if (tab[x] == ')'):
                break
            x += 1
        y = x
        while (x != 0):
            if (tab[x] == '('):
                break
            x -= 1
        return(replace_condition(tab[(x+1):y],tab,x,y))
    return(tab)

def resolve_rule(tab):
    while ('(' in tab):
        tab = handle_parentheses(tab)
    while (len(tab) != 1):
        tab = resolve_condition.resolve_condition(tab)
    return(tab)

def put_boolean(s,dic):
    if (s[0] == '!'):
        if (dic["facts"][s[1:]] == True):
            return(False)
        else:
            return(True)
    else:
            return(dic["facts"][s])

def create_tab(str):
    tab = []
    tmp = ""
    for c in str:
        tmp = tmp + c
        if (c != '!'):
            tab.append(tmp)
            tmp = ""
    return (tab)

def clean_rule(rule):
    clean_rule = {}
    tmp = ""
    for c in rule:
        if (c == '='):
            clean_rule["condition"] = tmp
            tmp = ""
        tmp = tmp + c
    if (clean_rule["condition"][-1] == '<'):
        clean_rule["opperand"] = '<' + tmp[:2]
        clean_rule["condition"] = clean_rule["conditions"][:-1]
    else:
        clean_rule["opperand"] = tmp[:2]
    tmp = tmp[2:]
    clean_rule["conclusion"] = tmp
    return(clean_rule)

def begin(dic):
    for rule in dic["rules"]:
        c_rule = clean_rule(rule)
        tab_tmp = create_tab(c_rule["condition"])
        tab_conclusion = create_tab(c_rule["conclusion"])
        tab = []
        for elem in tab_tmp:
            if (elem.isupper()):
                elem = put_boolean(elem,dic)
            tab.append(elem)
        print ("\n\n","-Starting to resolve the rule:",rule,'\n',c_rule,"\n","Resolving condition","\n",tab_tmp,"\n",tab)
        ret = resolve_rule(tab)
        if (len(tab_conclusion) == 1):
            dic["facts"][c_rule["conclusion"]] = ret[0]
            print('\n',c_rule["conclusion"],'=',ret[0],'\n',dic['facts'],'\n\n')
        elif(len(tab_conclusion) == 3):
            tab_conclusion = create_tab(c_rule["conclusion"])
            dic["facts"] = resolve_condition.resolve_conclusion(ret[0],tab_conclusion,dic["facts"])
        else:
            print("Error: Conclusion of",rule,"rule is to complex")
            sys.exit(1)
    return(dic)


from openerp import fields, models

class ResCompany(models.Model):
    _inherit = 'res.company'

    cra_transmitter_number = fields.Char(
        'Canada Revenu Agency Transmitter Number',
        help="The first time you send a T4 summary, you must use "
        "the number MM000000. When the CRA receives your first summary, "
        "they will create and send you a number to replace MM000000.",
        default='MM000000',
    )
    cra_payroll_number = fields.Char(
        'CRA Payroll Number',
        size=15,
        help="This number contains the buisness number followed by RP and "
        "the payroll account number 4 digits",
    )


class Stack:
    def __init__(self):
        self.stack = list()
    def push(self,data):
        self.stack.append(data)
    def pop(self):
        if len(self.stack) > 0:
            return self.stack.pop()
        else:
            return -1
    def isEmpty(self):
        return len(self.stack) == 0
    def size(self):
        return len(self.stack)

s = Stack()

def dfs_main(g,color):
    for i in range(len(g)):
        if color[i] == 0:
            dfs(g,color,i)
def dfs(g,color,i):
    color[i] = 1
    for index in g[i]:
        if color[index] == 0:
            dfs(g,color,index)
    s.push(i)
    color[i] = 2
def color(g,color,gr):
    count = 0
    while not s.isEmpty():
        tmp = s.pop()
        if color[tmp] == 0:
            count+=1
            dfs2(g,color,gr,count,tmp)
def dfs2(g,color,gr,count,i):
    color[i] = 1
    gr[i] = count
    for index in g[i]:
        if color[index] == 0:
            dfs2(g,color,gr,count,index)
    color[i] = 2

v,e = [int(e) for e in input().split()]
a = [[] for i in range(v)]
c = [0 for i in range(v)]
a_inverse = [[] for i in range(v)]
c_inverse = [0 for i in range(v)]
group = [0 for i in range(v)]

for i in range(e):
    start,end = [int(e) for e in input().split()]
    a[start].append(end)
    a_inverse[end].append(start)

print(a)
print(a_inverse)
dfs_main(a_inverse,c_inverse)
color(a,c,group)

for i in range(len(group)):
    print("index : "+str(i)+". the group is "+str(group[i]))