import math
import os
import random
import shutil
import warnings
from pathlib import Path

import torch
import torch.nn as nn
import torch.backends.cudnn as cudnn
import torch.optim
import torch.utils.data
import torch.utils.data.distributed
import torchvision.transforms as transforms
import torchvision.datasets as datasets
import torchvision.models as models
from torch.utils.data import DataLoader
import torch.nn.functional as F
import numpy as np
from q3_solution  import SimSiam
from q3_misc import TwoCropsTransform, load_checkpoints, load_pretrained_checkpoints
from utils.func_tool import save_logs

model_names = sorted(name for name in models.__dict__
    if name.islower() and not name.startswith("__")
    and callable(models.__dict__[name]))

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# general
seed = 2022
num_workers = 2
save_path1 = Path("./SSL_FineTune_StopG_NoneMLP")
save_path1.mkdir(exist_ok = True)
save_path = "./SSL_FineTune_StopG_NoneMLP"
resume = None # None or a path to a pretrained model (e.g. *.pth.tar')
start_epoch = 0
epochs = 100 # Number of epoches (for this question 200 is enough, however for 1000 epoches, you will get closer results to the original paper)

# data
dir ='./data'
batch_size = 1024

# Siamese backbone model
arch = "resnet18"
fix_pred_lr = True # fix the learning rate of the predictor network

#Simsiam params
dim=2048 # 2048 | 4096
pred_dim=512

# ablation experiments
stop_gradient=True # (True or False)
MLP_mode=None # None|'no_pred_mlp'|'fixed_random_init'

# optimizer
lr = 0.03
momentum = 0.9
weight_decay = 0.0005

random.seed(seed)
torch.manual_seed(seed)
cudnn.deterministic = True
# Simsiam Model
print("=> creating model '{}'".format(arch))
model = SimSiam(models.__dict__[arch], dim, pred_dim, stop_gradient=stop_gradient, MLP_mode=MLP_mode)
model.to(device)

# define and set learning rates
init_lr = lr * batch_size / 256
if fix_pred_lr:
    optim_params = [{'params': model.encoder.parameters(), 'fix_lr': False},
                    {'params': model.predictor.parameters(), 'fix_lr': True}]
else:
    optim_params = model.parameters()

# define optimizer
optimizer = torch.optim.SGD(optim_params, init_lr,
                            momentum=momentum,
                            weight_decay=weight_decay)
# adjust LR
def adjust_learning_rate(optimizer, init_lr, epoch, epochs):
    """Decay the learning rate based on schedule"""
    cur_lr = init_lr * 0.5 * (1. + math.cos(math.pi * epoch / epochs))
    for param_group in optimizer.param_groups:
        if 'fix_lr' in param_group and param_group['fix_lr']:
            param_group['lr'] = init_lr
        else:
            param_group['lr'] = cur_lr

# linear eval
print("=> creating model '{}'".format(arch))
model = models.__dict__[arch]()

# freeze all layers but the last fc
for name, param in model.named_parameters():
    if name not in ['fc.weight', 'fc.bias']:
        param.requires_grad = False

# init the fc layer
model.fc.weight.data.normal_(mean=0.0, std=0.01)
model.fc.bias.data.zero_()
print(model)

# load the pre-trained model from previous steps
pretrained = 'runs/stopGrad_NoneMLP/checkpoint_0099.pth.tar'
# pretrained = '../SSL_results/stopGrad_NoneMLP/checkpoint_0099.pth.tar'

if pretrained:
    model, optimizer, start_epoch = load_pretrained_checkpoints(os.path.join(pretrained),model,optimizer,device)
if device is not None:
    model.to(device)

# define loss function (criterion) and optimizer
criterion = nn.CrossEntropyLoss().to(device)

# optimize only the linear classifier
parameters = list(filter(lambda p: p.requires_grad, model.parameters()))
assert len(parameters) == 2  # fc.weight, fc.bias

optimizer = torch.optim.SGD(parameters, init_lr,
                            momentum=momentum,
                            weight_decay=weight_decay)

# define train and test augmentation for linear evaluation
train_transform = transforms.Compose([
    transforms.RandomResizedCrop(32),
    transforms.RandomHorizontalFlip(p=0.5),
    transforms.RandomApply([transforms.ColorJitter(0.4, 0.4, 0.4, 0.1)], p=0.8),
    transforms.RandomGrayscale(p=0.2),
    transforms.ToTensor(),
    transforms.Normalize([0.4914, 0.4822, 0.4465], [0.2023, 0.1994, 0.2010])])

val_transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize([0.4914, 0.4822, 0.4465], [0.2023, 0.1994, 0.2010])])

train_dataset = datasets.CIFAR10(
    dir,
    transform=train_transform,
    download=True,
    train=True
    )
val_dataset = datasets.CIFAR10(
    dir,
    transform=val_transform,
    download=True,
    train=False
    )

train_loader = torch.utils.data.DataLoader(
    train_dataset, batch_size=batch_size, shuffle=True, #(train_sampler is None),
    num_workers=num_workers, pin_memory=True) #, sampler=train_sampler)

val_loader = torch.utils.data.DataLoader(
    val_dataset,
    batch_size=256, shuffle=False,
    num_workers=num_workers, pin_memory=True)

# train for one epoch
def train(train_loader, model, criterion, optimizer, device):

    """
    Switch to eval mode:
    Under the protocol of linear classification on frozen features/models,
    it is not legitimate to change any part of the pre-trained model.
    BatchNorm in train mode may revise running mean/std (even if it receives
    no gradient), which are part of the model parameters too.
    """
    model.eval()
    losses=[]
    top1=[]
    top5=[]
    for i, (images, target) in enumerate(train_loader):

        if device is not None:
            images = images.to(device, non_blocking=True)
        target = target.to(device, non_blocking=True)

        # compute output
        output = model(images)
        loss = criterion(output, target)

        # measure accuracy and record loss
        acc1, acc5 = accuracy(output, target, topk=(1, 5))
        losses.append(loss.item())
        top1.append(float(acc1[0].cpu()))
        top5.append(float(acc5[0].cpu()))

        # compute gradient and do SGD step
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    return top1, top5

# validation
def validate(val_loader, model, criterion, device):

    # switch to evaluate mode
    model.eval()
    losses=[]
    top1=[]
    top5=[]
    with torch.no_grad():

        for i, (images, target) in enumerate(val_loader):
            if device is not None:
                images = images.to(device, non_blocking=True)
            target = target.to(device, non_blocking=True)

            # compute output
            output = model(images)
            loss = criterion(output, target)

            # measure accuracy and record loss
            acc1, acc5 = accuracy(output, target, topk=(1, 5))
            losses.append(loss.item())
            top1.append(float(acc1[0].cpu()))
            top5.append(float(acc5[0].cpu()))

    return top1, top5

def sanity_check(state_dict, pretrained_weights):
    """
    Linear classifier should not change any weights other than the linear layer.
    This sanity check asserts nothing wrong happens (e.g., BN stats updated).
    """
    print("=> loading '{}' for sanity check".format(pretrained_weights))
    checkpoint = torch.load(pretrained_weights, map_location="cpu")
    state_dict_pre = checkpoint['state_dict']

    for k in list(state_dict.keys()):
        # only ignore fc layer
        if 'fc.weight' in k or 'fc.bias' in k:
            continue

        # name in pretrained model
        k_pre = 'encoder.' + k[len('module.'):] \
            if k.startswith('module.') else 'encoder.' + k

        assert ((state_dict[k].cpu() == state_dict_pre[k_pre]).all()), \
            '{} is changed in linear classifier training.'.format(k)

    print("=> sanity check passed.")

def accuracy(output, target, topk=(1,)):
    """Computes the accuracy over the k top predictions for the specified values of k"""
    with torch.no_grad():
        maxk = max(topk)
        batch_size = target.size(0)

        _, pred = output.topk(maxk, 1, True, True)
        pred = pred.t()
        correct = pred.eq(target.view(1, -1).expand_as(pred))

        res = []
        for k in topk:
            correct_k = correct[:k].reshape(-1).float().sum(0, keepdim=True)
            res.append(correct_k.mul_(100.0 / batch_size))
        return res

# train for the classififcation task

logger_c = dict()
logger_c['train_top1'] = [0]
logger_c['val_top1'] = [0]
logger_c['train_top5'] = [0]
logger_c['val_top5'] = [0]
for epoch in range(start_epoch, epochs):

    adjust_learning_rate(optimizer, init_lr, epoch, epochs)

    # train for one epoch
    acc1_1, acc1_5 = train(train_loader, model, criterion, optimizer,device)
    print('Train Epoch: [{}/{}] Train acc1:{:.2f}%'.format(epoch, epochs,np.array(acc1_1).mean() ))
    logger_c['train_top1'].append(np.array(acc1_1).mean())
    logger_c['train_top5'].append(np.array(acc1_5).mean())

    # evaluate on validation set
    acc2_1, acc2_5 = validate(val_loader, model, criterion, device)
    print('Val Epoch: [{}/{}] Val acc1:{:.2f}%'.format(epoch, epochs,np.array(acc2_1).mean() ))
    logger_c['val_top1'].append(np.array(acc2_1).mean())
    logger_c['val_top5'].append(np.array(acc2_5).mean())

save_logs(logger_c, "SSL_FineTune_StopG_NoneMLP/log_new_c", str(1))


import array

class BitArray(object):
    '''
        Simple Bit Array class for representing an array of booleans (bits)
    '''

    def __init__(self):
        pass

    def makeBitArray(self, bitSize, fill = 0):
        '''
            Creates a bit array

            Parameters
            ----------
            bitSize : int
                    Size of bit array
            fill : int
                    Always zero

            Returns
            -------
                Bit array of a determined size for bloom filter's usage
        '''
        intSize = bitSize >> 5                  # number of 32 bit integers
        if (bitSize & 31):                      # if bitSize != (32 * n) add
            intSize += 1                        #    a record for stragglers
        if fill == 1:
            fill = 4294967295                   # all bits set
        else:
            fill = 0                            # all bits cleared

        bitArray = array.array('I')             # 'I' = unsigned 32-bit integer
        bitArray.extend((fill,) * intSize)
        return(bitArray)

    def testBit(self, array_name, bit_num):
        '''
            Checks if a bit is set to 1

            Parameters
            ----------
            array_name : str
                    Name of bit array
            bit_num : int
                    Bit number

            Returns
            -------
                Nonzero result, 2**offset, if the bit at 'bit_num' is set to 1
        '''
        record = bit_num >> 5
        offset = bit_num & 31
        mask = 1 << offset
        return(array_name[record] & mask)

    def setBit(self, array_name, bit_num):
        '''
            Sets a specific bit to 1

            Parameters
            ----------
                array_name : str
                        Name of bit array
                bit_num : int
                        Bit number

            Returns
            -------
                Integer with the bit at 'bit_num' set to 1
        '''
        record = bit_num >> 5
        offset = bit_num & 31
        mask = 1 << offset
        array_name[record] |= mask
        return(array_name[record])

    def clearBit(self, array_name, bit_num):
        '''
            Sets a specific bit to 0

            Parameters
            ----------
                array_name : str
                        Name of bit array
                bit_num : int
                        Bit number

            Returns
            -------
                Integer with the bit at 'bit_num' cleared
        '''
        record = bit_num >> 5
        offset = bit_num & 31
        mask = ~(1 << offset)
        array_name[record] &= mask
        return(array_name[record])


stick = input()

stick = stick.replace('()','l')

result = 0
stack = []

for i in stick:
    if i == 'l':
        result += len(stack)
    if i == '(':
        stack.append(i)
    if i == ')':
        result += 1
        stack.pop()

print(result)


import requests

from django.contrib.auth import login, logout
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.views import LoginView
from django.core.files.base import ContentFile
from django.db.models import Count
from django.http import HttpResponseNotFound, HttpResponseServerError
from django.shortcuts import redirect, render
from django.template import loader
from django.urls import reverse_lazy
from django.views.generic import (CreateView, DeleteView, DetailView, FormView,
                                  ListView, TemplateView, UpdateView)
from transliterate import slugify
from .models import Category, Women

from .forms import (AddPostForm, ContactForm, EditPageForm, LoginUserForm,
                    RegisterUserForm)
from .utils import DataMixin, content_adjustment, is_owner, initial_photo, menu

class WomenHome(DataMixin, ListView):
    model = Women
    template_name = 'women/index.html'
    context_object_name = 'posts'

    def get_context_data(self, *, object_list=None, **kwargs):
        context = super().get_context_data(**kwargs)
        common_data = self.get_user_context(title='Main page')
        return context | common_data

    def get_queryset(self):
        return Women.objects.filter(is_published=True).select_related('cat')

class AboutView(DataMixin, TemplateView):
    template_name = 'women/about.html'

    def get_context_data(self, *, objects_list=None, **kwargs):
        context = super().get_context_data(**kwargs)
        # get_user_context - method from the DataMixin class in utils.py
        common_data = self.get_user_context(
            title='Feedback',
            text='Made by Meritus99 ╰‿╯',
            all_women=Women.objects.order_by('-time_update').filter(is_published=True),
            cats=Category.objects.all(),
            cat_selected=None,
        )
        # return(dict(list(context.items()) + list(common_data.items())))
        return context | common_data

class DeletePage(LoginRequiredMixin, DataMixin, DeleteView):
    def get(self, request, post_slug):
        cats = Category.objects.annotate(Count('get_posts'))
        women = Women.objects.get(slug=post_slug)
        cat_selected = women.cat_id
        context = {
            'women': women, 'title': 'Deleting an article', 'menu': menu,
            'cats': cats,
            'cat_selected': cat_selected,
        }

        html_template = is_owner(request, women)
        if not html_template:
            context['title'] = 'Hahaha'
            context['cat_selected'] = 0
        return render(request, 'women/delete_page.html', context=context)

    def post(self, request, post_slug):
        women = Women.objects.get(slug=post_slug)
        women.delete()
        return redirect('home')

class EditPage(LoginRequiredMixin, DataMixin, UpdateView):
    template_name = 'women/edit_page.html'
    slug_url_kwarg = 'post_slug'
    context_object_name = 'post'
    form_class = EditPageForm
    success_url = reverse_lazy('home')

    def get_context_data(self, *, object_list=None, **kwargs):
        context = super().get_context_data(**kwargs)
        check_owner = context["post"]

        """ Защита от проникновения """
        html_template = is_owner(self.request, check_owner)
        if not html_template:
            common_data = self.get_user_context(title='Hahaha', cat_selected=0)
        else:
            common_data = self.get_user_context(title='Editing an article', cat_selected=check_owner.cat_id)

        return context | common_data

    def get_queryset(self):
        return Women.objects.filter(slug=self.kwargs['post_slug'], is_published=True)

    def form_valid(self, form):
        form.instance.content = content_adjustment(self.request.POST['content'])
        form.instance.slug = slugify(self.request.POST['title'], 'ru')
        return super().form_valid(form)

class AddPage(LoginRequiredMixin, DataMixin, CreateView):
    form_class = AddPostForm
    template_name = 'women/add_page.html'
    success_url = reverse_lazy('home')
    raise_exception = True  # to generate a 403 error - access denied, instead of a redirect

    def get_context_data(self, *, object_list=None, **kwargs):
        context = super().get_context_data(**kwargs)
        common_data = self.get_user_context(title='Adding an article', cat_selected=None)
        return context | common_data

    def get_initial(self):
        initial = super().get_initial()
        response = requests.get(initial_photo)
        image_content = response.content
        file_name = initial_photo.split('/')[-1]
        initial['photo'] = ContentFile(image_content, name=file_name)
        return initial

    def form_valid(self, form):
        form.instance.content = content_adjustment(self.request.POST['content'])
        form.instance.owner = self.request.user
        form.instance.slug = slugify(self.request.POST['title'], 'ru')
        return super().form_valid(form)

class NoAccess(DataMixin, TemplateView):
    template_name = 'women/no_access.html'

    def get_context_data(self, *, objects_list=None, **kwargs):
        context = super().get_context_data(**kwargs)
        common_data = self.get_user_context(title='Access error')
        return context | common_data

class ContactFormView(DataMixin, FormView):
    # FormView standard class for forms that are not linked to a model (do not work with the database).
    form_class = ContactForm
    template_name = 'women/contact.html'
    success_url = reverse_lazy('home')

    def get_context_data(self, *, objects_list=None, **kwargs):
        # The get_context_data function generates the context for the template.
        context = super().get_context_data(**kwargs)
        common_data = self.get_user_context(title='Feedback', cat_selected=None)
        return context | common_data

    def form_valid(self, form):
        # Called if the user has filled in all fields of the ContactForm correctly
        with open('feedback.txt', 'a', encoding="utf-8") as f:
            for key, value in form.cleaned_data.items():
                if key == 'captcha':
                    continue
                f.write(str(key) + ': ' + str(value) + "\n")

        return redirect('home')

class ShowPost(DataMixin, DetailView):
    model = Women
    template_name = 'women/post.html'
    context_object_name = 'post'
    # pk_url_kwarg = # similar mechanics if using a pk rather than a slug
    slug_url_kwarg = 'post_slug'
    # By default, the view class takes the name of the slug as 'slug',
    # with this parameter slug_url_kwarg, we specify the correct name of the slug

    def get_context_data(self, *, object_list=None, **kwargs):
        context = super().get_context_data(**kwargs)
        common_data = self.get_user_context(
            title=f'Category - {context["post"].cat} - {context["post"].title}',
            cat_selected=context['post'].cat_id,
        )
        return context | common_data

    def get_queryset(self):
        return Women.objects.filter(slug=self.kwargs['post_slug'], is_published=True)

class WomenCategory(DataMixin, ListView):
    model = Women
    template_name = 'women/index.html'
    context_object_name = 'posts'
    allow_empty = False  # invoke a 404 error if the collection(list) is empty

    def get_context_data(self, *, object_list=None, **kwargs):
        context = super().get_context_data(**kwargs)
        category = Category.objects.get(slug=self.kwargs['cat_slug'])
        common_data = self.get_user_context(
            title=f'Category - {category.name}',
            cat_selected=category.pk,
        )
        return context | common_data

    def get_queryset(self):
        return Women.objects.filter(cat__slug=self.kwargs['cat_slug'], is_published=True).select_related('cat')
    # via the kwargs dictionary I can get all the parameters of our route (which is described in the urls)

class RegisterUser(DataMixin, CreateView):
    form_class = RegisterUserForm
    template_name = 'women/register.html'
    # success_url = reverse_lazy('login')

    def get_context_data(self, *, object_list=None, **kwargs):
        context = super().get_context_data(**kwargs)
        common_data = self.get_user_context(title="Registration", cat_selected=None)
        return context | common_data

    def form_valid(self, form):
        user = form.save()  # here we save the form in the database, i.e. we add the user to the database
        login(self.request, user)
        return redirect('home')

class LoginUser(DataMixin, LoginView):
    form_class = LoginUserForm
    template_name = 'women/login.html'

    def get_context_data(self, *, object_list=None, **kwargs):
        context = super().get_context_data(**kwargs)
        common_data = self.get_user_context(title='Authorization', cat_selected=None)
        return context | common_data

    def get_success_url(self):
        return reverse_lazy('home')

def logout_user(request):
    logout(request)
    return redirect('login')

def error_handler_404(request, exception):
    content = loader.render_to_string('women/error_404.html', {}, request)
    return HttpResponseNotFound(content)

def error_handler_500(request):
    content = loader.render_to_string('women/error_500.html', {}, request)
    return HttpResponseServerError(content)


# -*- coding: gbk -*-
'''
将电子站牌编号发送给服务端,服务端通过网络对该电子站牌进行配置
暂不提供 命令式操作
'''

import socket
import network

def netConfigNet(str):

    sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((network.REMOTE_HOST, network.PORT_OF_NETCONFIG))
    sock.send(bytes(str, 'gbk'))
    re=sock.recv(1024)
    print(re)
    return

def netConfigClient():
    running=True
    while running:
        s=input('$ ')
        #print(s)
        if s=='q':
            print('exit')
            break
        netConfigNet(s)
    return

if __name__=='__main__':
    netConfigClient()


from typing import Any, Optional

import torch

class BinarizedLinear(torch.autograd.Function):
    r"""
    Binary Operation에 대한 커스텀 Forward/Backward 정의
    Binary Operation Method는 `Deterministic`과 `Stochastic`으로 구분됨
    Refers:
        1). Custom Operation : https://pytorch.org/docs/stable/notes/extending.html
        2). Binary Operation Methods : https://arxiv.org/pdf/1511.00363.pdf
    """

    @staticmethod
    def forward(
        ctx: object,
        input: torch.Tensor,
        weight: torch.Tensor,
        bias: Optional[torch.Tensor] = None,
        mode: Optional[str] = "deterministic",
    ) -> torch.Tensor:
        r"""
        Binary forward operation을 정의한다.

        Note:
            forward는 binarized wegiths를 이용하지만, backward는 real-value weights를 이용한다.
            torch.nn.functional.linear를 참고하였다.
            `Deterministic`과 `Stochastic`을 별도로 구현한다.
            Refs: https://pytorch.org/docs/stable/_modules/torch/nn/functional.html#linear

        Args:
            ctx (object): forward/backward간 정보를 공유하기위한 context 정보
            input (torch.Tensor): :math:`(N, *, in\_features)` where `*` means any number of additional dimensions
            weight (torch.Tensor): :math:`(out\_features, in\_features)`
            bias (Optional[torch.Tensor]): :math:`(out\_features)`
            mode (str): `Deterministic`, `Stochastic` Method를 명시한다.

        Returns:
            (torch.Tensor) : binarized weights를 forwarding한 결과
        """

        # 별도로 Backward를 정의하므로 연산을 Computational Graph에 추가하지 않는다.
        with torch.no_grad():
            if mode == "deterministic":
                # torch.sign()함수는 Ternary로 Quantization 된다. [-1, 0, 1]
                # 따라서 `0`에 대한 별도 처리를 해야 Binary weight를 가질 수 있다.
                binarized_weight = weight.sign()
                binarized_weight[binarized_weight == 0] = 1
            elif mode == "stochastic":
                # weights를 sigmoid 입력으로 넣어 이를 확률값으로 변환한다. `sigmoid(weights)`
                # 해당 확률값을 이용하여 [-1, 1]을 생성한다.
                # +1 if w >= p, where p = sigmoid(w)
                # -1 else 1 - p

                # p값을 먼저 구한다.
                # [0, 1]사이의 값을 갖는 데이터에서 uniform 확률 분포로 데이터를 샘플링한다.
                # sampling된 값들이 p값 이상을 갖으면 1, 그렇지 않으면 -1로 정의한다.
                binarized_probability = torch.sigmoid(weight)
                uniform_matrix = torch.empty(binarized_probability.shape).uniform_(0, 1)
                binarized_weight = (binarized_probability >= uniform_matrix).type(torch.float32)
                binarized_weight[binarized_weight == 0] = -1.0
            else:
                raise RuntimeError(f"{mode} not supported")

            device = weight.device
            binarized_weight = binarized_weight.to(device)
            output = input.mm(binarized_weight.t())

            if bias is not None:
                output += bias.unsqueeze(0).expand_as(output)

        ctx.save_for_backward(input, binarized_weight, bias)

        return output

    @staticmethod
    def backward(ctx: object, grad_output: Any):
        r"""
        Binary backward operation을 정의한다.

        Note:
            forward는 binarized wegiths를 이용하지만, backward는 real-value weights를 이용한다.

        Args:
            ctx (object): forward/backward간 정보를 공유하기위한 context 정보
            grad_output (Any): Compuational graph를 통해서 들어오는 gradient정보를 받는다.

        Returns:
            (torch.Tensor) : Computational graph 앞으로 보내기위한 gradient 정보
        """

        input, binarized_weight, bias = ctx.saved_tensors

        grad_input = grad_weight = grad_bias = None

        with torch.no_grad():
            if ctx.needs_input_grad[0]:
                grad_input = grad_output.mm(binarized_weight)
            if ctx.needs_input_grad[1]:
                grad_weight = grad_output.t().mm(input)
            if (bias is not None) and (ctx.needs_input_grad[2]):
                grad_bias = grad_output.sum(0).squeeze(0)

        return grad_input, grad_weight, grad_bias, None

binarized_linear = BinarizedLinear.apply


def isPal(num):
    copy = num
    reverse = 0
    while copy > 0:
        reverse = reverse*10 + copy % 10
        copy = int(copy /10)
    if reverse == num:
        return True
    else:
        return False
max = 0
for i in range(1000):
    for j in range(1000):
        number = i*j
        if isPal(number) :
            if number > max:
                max = number
print(max)


import csv

filename = 'users.csv'

# Reading CSV Files With csv
print('\r\nReading CSV Files \n')

with open(filename) as csv_file:
    csv_reader = csv.reader(csv_file, delimiter=',')
    line_count = 0
    for row in csv_reader:
        if line_count == 0:
            print(f'{" | ".join(row)}'.upper())
            line_count += 1
        else:
            print(f'{row[0]} | {row[1]} | {row[2]} | {row[3]}')
            line_count += 1
    print(f'Processed {line_count} lines.')

# Reading CSV Files Into a Dictionary
print('\r\nReading CSV Files Into a Dictionary \n')

with open(filename, mode='r') as csv_file:
    csv_reader = csv.DictReader(csv_file)
    line_count = 0
    for row in csv_reader:
        if line_count == 0:
            print(f'{" | ".join(row)}'.upper())
            line_count += 1

        print(f'{row["firstname"]} | {row["lastname"]} | {row["email"]} | {row["phone"]}')
        line_count += 1
    print(f'Processed {line_count} lines.')


import datetime
import endpoints
import logging

from google.appengine.ext import ndb

from webapp.src import vtslab_status as Status
from webapp.src.endpoint import endpoint_base
from webapp.src.endpoint import host_info
from webapp.src.proto import model

LAB_INFO_RESOURCE = endpoints.ResourceContainer(model.LabInfoMessage)
LAB_HOST_INFO_RESOURCE = endpoints.ResourceContainer(model.LabHostInfoMessage)

@endpoints.api(name='lab', version='v1')
class LabInfoApi(endpoint_base.EndpointBase):
    """Endpoint API for lab_info."""

    @endpoints.method(
        LAB_INFO_RESOURCE,
        model.DefaultResponse,
        path="clear",
        http_method="POST",
        name="clear")
    def clear(self, request):
        """Clears lab info in DB."""
        lab_query = model.LabModel.query()
        existing_labs = lab_query.fetch(keys_only=True)
        if existing_labs and len(existing_labs) > 0:
            ndb.delete_multi(existing_labs)
        return model.DefaultResponse(
            return_code=model.ReturnCodeMessage.SUCCESS)

    @endpoints.method(
        LAB_INFO_RESOURCE,
        model.DefaultResponse,
        path="set",
        http_method="POST",
        name="set")
    def set(self, request):
        """Sets the lab info based on `request`."""
        if "host" in [x.name for x in request.all_fields()]:
            labs_to_put = []
            for host in request.host:
                duplicate_query = model.LabModel.query(
                    model.LabModel.name == request.name,
                    model.LabModel.owner == request.owner,
                    model.LabModel.hostname == host.hostname)
                duplicates = duplicate_query.fetch()
                if duplicates:
                    lab = duplicates[0]
                else:
                    lab = model.LabModel()
                lab.name = request.name
                lab.owner = request.owner
                lab.admin = request.admin
                lab.hostname = host.hostname
                lab.ip = host.ip
                lab.script = host.script

                null_device_count = 0
                devices_to_put = []
                for config_device in host.device:
                    if config_device.product == "null":
                        null_device_count += 1
                        continue
                    if config_device.serial and config_device.product:
                        device_query = model.DeviceModel.query(
                            model.DeviceModel.serial == config_device.serial)
                        devices = device_query.fetch()
                        if devices:
                            device = devices[0]
                            if (device.hostname != host.hostname) and (
                                    device.status !=
                                    Status.DEVICE_STATUS_DICT["no-response"]):
                                logging.error(
                                    "{} is alive in another host.".format(
                                        config_device.serial))
                                # TODO: send an alert to lab.admin
                                continue
                            if device.hostname == host.hostname and set(
                                    device.device_equipment) == set(
                                        config_device.device_equipment):
                                # no need to update.
                                continue
                        else:
                            device = model.DeviceModel()
                            device.status = Status.DEVICE_STATUS_DICT[
                                "no-response"]
                            device.product = config_device.product
                            device.serial = config_device.serial
                            device.hostname = host.hostname
                            device.scheduling_status = (
                                Status.DEVICE_SCHEDULING_STATUS_DICT["free"])
                            device.timestamp = datetime.datetime.now()
                        device.device_equipment = config_device.device_equipment
                        devices_to_put.append(device)
                    else:
                        logging.error("Lab config does not have device "
                                      "information correctly; it should "
                                      "specify device product and serial.")
                if devices_to_put:
                    ndb.put_multi(devices_to_put)

                lab.timestamp = datetime.datetime.now()
                labs_to_put.append(lab)

                if null_device_count > 0:
                    host_info.AddNullDevices(host.hostname, null_device_count)

            if labs_to_put:
                ndb.put_multi(labs_to_put)

        return model.DefaultResponse(
            return_code=model.ReturnCodeMessage.SUCCESS)

    @endpoints.method(
        LAB_HOST_INFO_RESOURCE,
        model.DefaultResponse,
        path="set_version",
        http_method="POST",
        name="set_version")
    def set_version(self, request):
        """Sets vtslab version of the host <hostname>"""
        lab_query = model.LabModel.query(
            model.LabModel.hostname == request.hostname)
        labs = lab_query.fetch()

        labs_to_put = []
        for lab in labs:
            lab.vtslab_version = request.vtslab_version.split(":")[0]
            labs_to_put.append(lab)
        if labs_to_put:
            ndb.put_multi(labs_to_put)

        return model.DefaultResponse(
            return_code=model.ReturnCodeMessage.SUCCESS)

    @endpoints.method(
        endpoint_base.GET_REQUEST_RESOURCE,
        model.LabResponseMessage,
        path="get",
        http_method="POST",
        name="get")
    def get(self, request):
        """Gets the labs from datastore."""
        return_list, more = self.Get(request=request,
                                     metaclass=model.LabModel,
                                     message=model.LabMessage)

        return model.LabResponseMessage(labs=return_list, has_next=more)

    @endpoints.method(
        endpoint_base.COUNT_REQUEST_RESOURCE,
        model.CountResponseMessage,
        path="count",
        http_method="POST",
        name="count")
    def count(self, request):
        """Gets total number of BuildModel entities stored in datastore."""
        filters = self.CreateFilterList(
            filter_string=request.filter, metaclass=model.LabModel)

        count = self.Count(metaclass=model.LabModel, filters=filters)

        return model.CountResponseMessage(count=count)


import json
import pathlib
from functools import cache

# reMarkable's device dimensions
RM_WIDTH = 1404
RM_HEIGHT = 1872

@cache
def read_meta_file(path, suffix=".metadata"):
    file = path.with_name(f"{path.stem}{suffix}")
    if not file.exists():
        return None
    data = json.loads(open(file).read())
    return data

def is_document(path):
    metadata = read_meta_file(path)
    return metadata["type"] == "DocumentType"

def get_document_filetype(path):
    content = read_meta_file(path, suffix=".content")
    return content["fileType"]

def get_visible_name(path):
    metadata = read_meta_file(path)
    return metadata["visibleName"]

def get_ui_path(path):
    metadata = read_meta_file(path)
    parent_filename = metadata["parent"]

    # Check the parent
    ui_path = pathlib.Path("")

    while parent_filename != "":
        # First get the total path of the parent
        parent_path = pathlib.Path(path.parent, metadata["parent"])

        # Get the meta data of this parent
        metadata = read_meta_file(parent_path)
        if not metadata:
            return pathlib.Path(".")

        parent_title = metadata["visibleName"]

        # These go in reverse order up to the top level
        ui_path = pathlib.Path(parent_title).joinpath(ui_path)

        # Get the parent of this one
        parent_filename = metadata["parent"]

    return ui_path

def get_pages_data(path):
    content = read_meta_file(path, suffix=".content")
    if "redirectionPageMap" in content:
        return content["pages"], content["redirectionPageMap"]
    return content["pages"], []

def list_ann_rm_files(path):
    content_dir = pathlib.Path(f"{path.parents[0]}/{path.stem}/")
    # print("content_dir", content_dir, not content_dir.is_dir())
    if not content_dir.is_dir():
        return []
    return list(content_dir.glob("*.rm"))

def list_hl_json_files(path):
    hl_dir = pathlib.Path(f"{path.parents[0]}/{path.stem}.highlights/")
    # print("hl_dir", hl_dir, not hl_dir.is_dir())
    if not hl_dir.is_dir():
        return []
    return list(hl_dir.glob("*.json"))

def load_json_file(path):
    with open(path) as f:
        data = json.load(f)
    return data

def prepare_subdir(base_dir, fmt):
    fmt_dir = pathlib.Path(f"{base_dir}/{fmt}/")
    fmt_dir.mkdir(parents=True, exist_ok=True)
    return fmt_dir

def rescale_given_device_aspect_ratio(page_dims):
    page_width, page_height = page_dims
    page_aspect_ratio = page_width / page_height
    device_aspect_ratio = RM_WIDTH / RM_HEIGHT

    scale = 1
    page_width_rescaled = page_width
    page_height_rescaled = page_height

    # If doc page is wider than reMarkable's aspect ratio,
    # use doc_width as reference for the scale ratio.
    # There should be no "leftover" (gap) on the horizontal
    if page_aspect_ratio >= device_aspect_ratio:
        scale = page_width / RM_WIDTH
        page_width_rescaled = RM_WIDTH * scale

    # PDF page is narrower than reMarkable's a/r,
    # use pdf_height as reference for the scale ratio.
    # There should be no "leftover" (gap) on the vertical
    else:
        scale = page_height / RM_HEIGHT
        page_height_rescaled = RM_HEIGHT * scale

    return (page_width_rescaled, page_height_rescaled), scale


from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
import os

# Init app
app = Flask(__name__)

# To make sure that we can correctly locate the database file
basedir = os.path.abspath(os.path.dirname(__file__))

# Set up database
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'db.sqlite')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# Initialize database
db = SQLAlchemy(app)

# Initialize Marshmallow
ma = Marshmallow(app)

# Product Class / Model
class Product(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), unique=True)
    description = db.Column(db.String(200))
    price = db.Column(db.Float)
    qty = db.Column(db.Integer)

    # id will be assigned automatically in an increasing order
    def __init__(self, name, description, price, qty):
        self.name = name
        self.description = description
        self.price = price
        self.qty = qty

# Product Schema
class ProductSchema(ma.Schema):
    class Meta:
        fields = ('id', 'name', 'description', 'price', 'qty')

# Initialize the Schema
product_schema = ProductSchema()
# To handle multiple products (Have to be distinguished)
products_schema = ProductSchema(many=True)

# Create a Product
@app.route('/product', methods=['POST'])
def add_product():
    name = request.json['name']
    description = request.json['description']
    price = request.json['price']
    qty = request.json['qty']

    # Turn received json information into the Product class
    new_product = Product(name, description, price, qty)

    # Add created Product class into db (SQLAlchemy)
    db.session.add(new_product)
    # To apply (save) the change, we need to commit
    db.session.commit()

    # Since it is dealing with a single item, we use product_schema
    # So, when the user post the product, it returns the information about the created product
    return product_schema.jsonify(new_product)

# Get All Products
@app.route('/product', methods=['GET'])
def get_products():
    # Since the class is using SQLAlchemy db.model, we can use .query.all()
    # , which returns all objects belong to the Product class
    all_products = Product.query.all()
    result = products_schema.dump(all_products)
    # No longer need to use 'result.data'
    return jsonify(result)

# Get single Products
@app.route('/product/<id>', methods=['GET'])
def get_product(id):
    # Since the class is using SQLAlchemy db.model, we can use .query.all()
    # , which returns all objects belong to the Product class
    product = Product.query.get(id)
    # No longer need to use 'result.data'
    return product_schema.jsonify(product)

# Update a Product (PUT Request is used for an update)
@app.route('/product/<id>', methods=['PUT'])
def update_product(id):
    product = Product.query.get(id)

    name = request.json['name']
    description = request.json['description']
    price = request.json['price']
    qty = request.json['qty']

    product.name = name
    product.description = description
    product.price = price
    product.qty = qty

    # For an update, we don't need to add. Just commit.
    db.session.commit()

    # Since it is dealing with a single item, we use product_schema
    # So, when the user post the product, it returns the information about the created product
    return product_schema.jsonify(product)

# Delete single Products
@app.route('/product/<id>', methods=['DELETE'])
def delete_product(id):
    product = Product.query.get(id)
    db.session.delete(product)

    # Make sure to commit after delete
    db.session.commit()

    return product_schema.jsonify(product)

"""
@app.route('/', methods=['Get'])
def get():
    return jsonify({'msg': 'Hello World'})
"""

# Run Server
if __name__ == '__main__':
    # This is same as "flask run" in the command line
    app.run(debug=True)


from flask import Flask, request
from keras.models import load_model
from PIL import Image
import numpy as np
import io
import base64
import zipfile

# Load your generator model
generator = load_model("data/models/generator_15000")

app = Flask(__name__)

@app.route('/generate', methods=['POST'])
def generate():
    data = request.get_json()
    num_images = data.get('num_images', 1)
    images = generate_avatars(generator, num_images)
    return {"images": images}

def generate_avatars(generator, num_images, noise_dim=100):
    images = []
    for _ in range(num_images):
        img = generate_avatar(generator, noise_dim)
        images.append(img)
    return images

def generate_avatar(generator, noise_dim):
    # Generate a random noise vector
    noise = np.random.normal(0, 1, (1, noise_dim))

    # Use the generator to create a new avatar
    img = generator.predict(noise)

    # Rescale the image from [-1,1] to [0,255]
    img = (0.5 * img[0] + 0.5) * 255
    img = img.astype(np.uint8)

    # Convert the image to base64 and then decode it to a string
    img = Image.fromarray(img)
    buffered = io.BytesIO()
    img.save(buffered, format="PNG")
    img_str = base64.b64encode(buffered.getvalue()).decode()

    return img_str

if __name__ == "__main__":
    app.run(port=5000, debug=True)


import sys
import pathlib

import hug

from overtime_calculator import auth, api

@hug.get("/", output=hug.output_format.html)
def base():
    return "
Hello, world
"

@hug.extend_api()
def with_other_apis():
    return [
        auth,
        api
    ]

if __name__ == '__main__':
    _file = pathlib.Path(sys.argv[0])
    module = _file.parent.name
    print(
        f"Start {module} with Hug, like so: hug --file {_file}",
        file=sys.stderr,
    )
    sys.exit(1)


import json
import os
import sys
from pip._internal import main as pip

import urllib.request as urllib

def get_last_release(name_package):
    urlpath = urllib.urlopen(os.path.join('https://pypi.org/pypi', name_package, 'json'))
    string = urlpath.read()

    wjdata = json.loads(string)
    releases = list(wjdata["releases"].keys())

    latest = releases[0]
    for release in releases:
        if wjdata["releases"][release][0]["upload_time"] > wjdata["releases"][latest][0]["upload_time"]:
            latest = release

    return latest

def install_latest_dev_package(name_package):
    latest_version = get_last_release(name_package)
    pip(['install', '--no-input', name_package + '==' + latest_version, '--upgrade'])

def main(argv=None):
    install_latest_dev_package(argv[1])

if __name__ == "__main__":
    main(sys.argv)


class game:
    def __init__(self, gameID, teamIDHome, teamNameHome, gameDate, WLHome, pointsHome, teamIDAway, teamNameAway, WLAway, pointsAway):
        self.gameID = gameID
        self.teamIDHome = teamIDHome
        self.teamNameHome = teamNameHome
        self.gameDate = gameDate
        self.WLHome = WLHome
        self.pointsHome = pointsHome
        self.teamIDAway = teamIDAway
        self.teamNameAway = teamNameAway
        self.WLAway = WLAway
        self.pointsAway = pointsAway


def singleNumber(nums):
    d = dict()
    for i in nums:
        if i in d.keys():
            d[i] = not((d[i]))
        else:
            d[i] = 1
    for i in d.keys():
    	if d[i] == 1:
    		return i

result = singleNumber([4,1,2,1,2])
print(result)


import os
import torch
def find_files_by_extension(paths, extension, search_depth=-1):
    if isinstance(paths, str):
        paths = [paths]

    file_list = []

    def search_files(current_path, current_depth):
        if search_depth >= 0 and current_depth > search_depth:
            return

        for item in os.listdir(current_path):
            item_path = os.path.join(current_path, item)

            if os.path.isfile(item_path) and item.endswith(f".{extension}"):
                file_list.append(item_path)
            elif os.path.isdir(item_path):
                search_files(item_path, current_depth + 1)

    for path in paths:
        if os.path.isfile(path):
            file_list.append(path)
        elif os.path.isdir(path):
            search_files(path, 0)

    return file_list

def normalize_volume(tensor):
    loudness = torch.max(torch.abs(tensor))
    return tensor / loudness

def split_and_pad(tensor, x):
    # Get the current shape of the tensor (1, x)
    shape = tensor.shape

    # Calculate the remainder when n is divided by x
    rem = shape[1] % x

    # Calculate the number of zeros to add
    num_zeros = x - rem if rem != 0 else 0

    # Create a new tensor by concatenating zeros along the second dimension
    padded_tensor = torch.cat((tensor.squeeze(0), torch.zeros(num_zeros)), dim=0).unsqueeze(0)
    print("!")
    # Calculate the new value of n after padding
    n_with_padding = shape[1] + num_zeros

    # Reshape the tensor to (1, batches, x)
    reshaped_tensor = padded_tensor.view(1, n_with_padding//x, x)

    return reshaped_tensor


# functions are first class citizens
# this means that they can be passed as arguments to other functions or returned as the result of other functions
# this also means they can be assigned to variables and used as such

def greet_user(username):
    """Display a simple greeting."""
    print(f"Hello, {username}! Welcome the the Python world.")

greet_user('John')

greeting = greet_user
greeting('Peter')

# function composition
def inner():
    print("inner function")

def outer(func):
    func()

outer(inner)

#lambda functions
reverse = lambda s: s[::-1]
print(reverse('hello'))

#reversing a list using a lambda function as the key for the sorted function
cars = ['Ford', 'BMW', 'Volvo']
sorted_cars  = sorted(cars, key=lambda s: -len(s))
print(sorted_cars)

# map function
animals = ['cat', 'dog', 'rabbit']
reverse_animals = list(map(lambda s: s[::-1], animals))
print(reverse_animals)


from sqlalchemy import Column, String, Integer, Sequence, VARCHAR
from db import Base, engine

class Usuarios(Base):
    __tablename__ = 'Usuarios'
    id = Column(Integer, autoincrement=True, primary_key=True)
    nombre = Column(VARCHAR(70))

Base.metadata.create_all(engine)


from unittest import mock
from View import *
from Contreller import *
from Module import *
import argparse

#op_id, sign, summary, dd, mm, yy, comment, Operation_History
test = create_method()

test.create = mock.MagicMock()
test.create.assert_call_once_with(0, 0, 0, 0, 0, 0, 0, {})

test = edit_method()

test.edit_sign = mock.MagicMock()
test.edit_sign.assert_call_once_with(0, 0, 0, 0, 0, 0, 0, {})

test.edit_summary = mock.MagicMock()
test.edit_summary.assert_call_once_with(0, 0, 0, 0, 0, 0, 0, {})

test.edit_dd = mock.MagicMock()
test.edit_dd.assert_call_once_with(0, 0, 0, 0, 0, 0, 0, {})

test.edit_mm = mock.MagicMock()
test.edit_mm.assert_call_once_with(0, 0, 0, 0, 0, 0, 0, {})

test.edit_yy = mock.MagicMock()
test.edit_yy.assert_call_once_with(0, 0, 0, 0, 0, 0, 0, {})

test.edit_comment = mock.MagicMock()
test.edit_comment.assert_call_once_with(0, 0, 0, 0, 0, 0, 0, {})

test = delete()

test.delete_operation = mock.MagicMock()
test.delete_operation.assert_call_once_with(0, 0, 0, 0, 0, 0, 0, {})

test = Geter()

test.get_dict = mock.MagicMock()
test.get_dict.assert_call_once_with(0, 0, 0, 0, 0, 0, 0, {})

test = database()

test.edit_all = mock.MagicMock()
test.edit_all.assert_call_once_with(0, 0, 0, 0, 0, 0, 0, {})

test.create = mock.MagicMock()
test.create.assert_call_once_with(0, 0, 0, 0, 0, 0, 0, {})

test.delete = mock.MagicMock()
test.delete.assert_call_once_with(0, 0, 0, 0, 0, 0, 0, {})

test = ViewMethod()

test.balance_plus = mock.MagicMock()
test.balance_plus.assert_call_once_with()
result = ViewMethod().balance_plus()
assert result == 235
print(result)

test.balance_minus = mock.MagicMock()
test.balance_minus.assert_call_once_with()
result = ViewMethod().balance_minus()
assert result == 1500
print(result)

test.balance_difference = mock.MagicMock()
test.balance_difference.assert_call_once_with()
result = ViewMethod().balance_difference()
assert result == -1265
print(result)

test.show_method = mock.MagicMock()
test.show_method()

test.show_list = mock.MagicMock()
test.show_list()

test.menu_create = mock.MagicMock()
test.menu_create()

test.menu_delete = mock.MagicMock()
test.menu_delete()

test.menu_edit = mock.MagicMock()
test.menu_edit()

test.menu_balance_plus = mock.MagicMock()
test.menu_balance_plus()

test.menu_balance_minus = mock.MagicMock()
test.menu_balance_minus()

test.menu_balance_all = mock.MagicMock()
test.menu_balance_all()

test.message = mock.MagicMock()
test.message.assert_call_once_with("Hello")

test = Console()

namespace = argparse.Namespace(add=0, delete=0, show =0, update=0, positive=0, negative=0, result=0)
#test.create_parser

test.parser_analyze = mock.MagicMock()
test.parser_analyze(namespace, {})

test = main()

test.menu = mock.MagicMock()
test.menu()


import typing
import webbrowser
from urllib.parse import quote_plus

def web_grafana_pop_health(server: str) -> None:
    graf_path = "https://grafana.global.ftlprod.net"
    server_short = server.replace("-data01", "")

    pop_health = f"{graf_path}/d/4JEipO57k/pop-health?var-pop={server_short}&var-level=All&var-services=All&var-server={server}&var-filter=&refresh=30s"  # noqa
    webbrowser.open(pop_health)

def web_grafana_globalturn_pop_overview(server: str) -> None:
    graf_path = "https://grafana.global.ftlprod.net"
    turn_health = f"{graf_path}/d/Yoi5Rlcnk/overview-per-pop?orgId=1&refresh=30s&var-realm=All&var-instance={server}&from=now-5m&to=now&refresh=30s"  # noqa
    webbrowser.open(turn_health)

def web_graph(graph: typing.Any, alpha: bool = False) -> None:
    quoted_popid = quote_plus(graph.pop_id)
    if alpha:
        graph_url = f"https://graph.subspace-alpha.com/pops/{quoted_popid}/details"
    else:
        graph_url = f"https://graph.subspace.com/pops/{quoted_popid}/details"
    webbrowser.open(graph_url)

def web_alice(server: str, as_number: str = None) -> None:
    alice_url = f"https://looking-glass.ftlprod.net/routeservers/{server}"
    if as_number:
        alice_url = f"{alice_url}?s=asn&o=asc&q={as_number}"
    webbrowser.open(alice_url)

def web_api_health() -> None:
    api_health_url = (
        "https://grafana.global.ftlprod.net/d/ApdbczCGz/api-health?orgId=1&refresh=5s"
    )
    webbrowser.open(api_health_url)

def web_netbox_device(nb_server: typing.Any) -> None:
    webbrowser.open(f"https://netbox.global.ftlprod.net/dcim/devices/{nb_server.id}")


#!/usr/bin/env python3

import re
import adventofcode

t1 = [
    'mxmxvkd kfcds sqjhc nhms (contains dairy, fish)',
    'trh fvjkl sbzzf mxmxvkd (contains dairy)',
    'sqjhc fvjkl (contains soy)',
    'sqjhc mxmxvkd sbzzf (contains fish)',
]

def parse(lines):
    foods = []
    for line in lines:
        m = re.match(r'^(.+) \(contains (.+)\)$', line)
        foods.append([m[1].split(), m[2].split(', ')])
    return foods

def find_safe(foods, all_ingredients, all_allergens):
    safe = set(all_ingredients)
    for a in all_allergens:
        p = set(all_ingredients)
        for f in foods:
            if a in f[1]:
                p &= set(f[0])
        safe = safe.difference(p)
    return safe

def find_possible_ingredients_for_allergens(foods, all_allergens, danger):
    could = {}
    for a in all_allergens:
        p = set(danger)
        for f in foods:
            if a in f[1]:
                p = p.intersection(f[0])
        could[a] = list(p)
    return could

def reduce_possibilities(could):
    """
    Takes a dict of keys to lists and returns a dict of keys to the item unique to each list

    >>> reduce_possibilities({'one': [1,2], 'two': [2]})
    {'two': 2, 'one': 1}
    """
    remaining = {k: v[:] for k, v in could.items()}  # don't change the input
    known = {k:v[0] for k, v in remaining.items() if len(v) == 1}
    toremove = set(known.values())
    while toremove:
        r = toremove.pop()
        for k, vl in remaining.items():
            if r in vl:
                vl.remove(r)
                if len(vl) == 1:
                    known[k] = vl[0]
                    toremove.add(vl[0])
    return known

def part1(lines):
    """
    >>> part1(t1)
    5
    """
    foods = parse(lines)
    all_ingredients = set(a for f in foods for a in f[0])
    all_allergens = set(a for f in foods for a in f[1])
    safe = find_safe(foods, all_ingredients, all_allergens)
    return sum(len(set(f[0]).intersection(safe)) for f in foods)

def part2(lines):
    """
    >>> part2(t1)
    'mxmxvkd,sqjhc,fvjkl'
    """
    foods = parse(lines)
    all_ingredients = set(a for f in foods for a in f[0])
    all_allergens = set(a for f in foods for a in f[1])
    safe = find_safe(foods, all_ingredients, all_allergens)

    danger = all_ingredients.difference(safe)
    could = find_possible_ingredients_for_allergens(foods, all_allergens, danger)

    results = reduce_possibilities(could)
    return ','.join(results[k] for k in sorted(results.keys()))

def main():
    puzzle_input = adventofcode.read_input(21)
    adventofcode.answer(1, 2874, part1(puzzle_input))
    adventofcode.answer(2, 'gfvrr,ndkkq,jxcxh,bthjz,sgzr,mbkbn,pkkg,mjbtz', part2(puzzle_input))

if __name__ == '__main__':
    import doctest
    doctest.testmod()
    main()


"""
EXERCISE 14: POLYGON FUNCTIONS
Write a function called polygonthat takes an integer as an argument and
makes the turtle draw a polygon with that integer’s number of sides.
"""

from turtle import *

def polygon(sidelength=100):
    for i in range(6):
        forward(sidelength)
        right(60)

polygon()


"""
Utility functions for interacting with HPC backend
"""
import os
from fabric import Connection
from .models import GenotypeSubmission, IdentifyJob, CrossesJob
from .models import get_identify_result_path, STATUS_CHOICES, CREATED, FINISHED, PROCESSING, FINISHED, QUEUED, ERROR
from patchwork.files import exists
from django.utils import timezone
from django.core.files import File
import tempfile
from datetime import datetime
import json
import re
import datetime, math
from django.conf import settings
import logging
from collections import OrderedDict

logger = logging.getLogger(__name__)

SBATCH_PATTERN = re.compile(r"Submitted batch job ([0-9]*)")

SLURM_STATUS_DICT = {'COMPLETED': FINISHED, 'RUNNING': PROCESSING, 'COMPLETING': PROCESSING, '': FINISHED, 'PENDING': QUEUED }
#FIXME make it configurable
BASE_DIR = '/scratch-cbe/users/%s/AraGeno/' % settings.HPC_USER
SUBMIT_SCRIPT_FOLDER = os.path.join(os.path.dirname(__file__),'submit_script_templates/CBE/')

connect_kwargs=None

if settings.SSH_KEY_FILENAME:
    connect_kwargs = { "key_filename": settings.SSH_KEY_FILENAME}

c = Connection(settings.HPC_HOST, user=settings.HPC_USER, connect_kwargs=connect_kwargs)

WALLTIME_MULTIPLIER = 2
MEMORY_MULTIPLIER = 5
DEFAULT_MEMORY = (1024*1024* 4)
MIN_MEMORY=1024*1024*4
DEFAULT_WALLTIME = 1200
MIN_WALLTIME=60*10

def sizeof_fmt(num, suffix='b'):
    for unit in ['k','m','g','t','p','e','z']:
        if abs(num) < 1024.0:
            return ("%3.0f%s%s" % (num, unit, suffix)).strip()
        num /= 1024.0
    return "%.0f%s%s" % (num, 'y', suffix)

def _get_memory(memory):
    # convert to bytes
    if not memory:
        memory = DEFAULT_MEMORY
    memory = math.ceil(max(memory * MEMORY_MULTIPLIER,MIN_MEMORY) )
    return sizeof_fmt(memory)

def _get_walltime(walltime):
    if not walltime:
        walltime = DEFAULT_WALLTIME
    return str(datetime.timedelta(seconds=math.ceil(max(walltime * WALLTIME_MULTIPLIER,MIN_WALLTIME) )))

def _read_file(id, filename):
    target_folder = _get_target_folder(id)
    return c.run(f"cd {target_folder} && cat {filename}" ,pty=True, hide=True)

def _get_target_folder(id):
    return os.path.join(BASE_DIR, str(id))

def _get_genotype(id):
    return GenotypeSubmission.objects.get(pk=id)

def _get_rendered_submit_script(submit_script, ctx):
    with open(os.path.join(SUBMIT_SCRIPT_FOLDER, submit_script)) as fh:
        content = fh.read()
        return content % ctx

def stagein_identify_job(id, force=False):
    """
    Function to stagein the genotype files
    """
    target_folder = _get_target_folder(id)
    if not force and exists(c, path=os.path.join(target_folder, str(id))):
        return
    genotype = _get_genotype(id)
    ext = genotype.get_file_ext()
    c.run(f'mkdir -p  {target_folder}')
    c.put(genotype.genotype_file.path, f"{target_folder}/{id}{ext}")

def upload_submit_script(script, target_folder, filename):
    with tempfile.NamedTemporaryFile(delete=False) as fp:
        fp.write(script.encode())
    c.put(fp.name, os.path.join(target_folder,filename))
    os.unlink(fp.name)

def submit_parse_job(id, on_hold=True):
    """
    Submit job to parse genotype
    """
    genotype = _get_genotype(id)
    ext = genotype.get_file_ext()
    target_folder = _get_target_folder(id)
    job_script = 'parse_job.sh'
    ctx = {
        "walltime": _get_walltime(genotype.walltime),
        "memory": _get_memory(genotype.memory),
        "id": id,
        "input_file": '%s%s' % (id, ext),
        "workdir": target_folder
    }
    rendered_script = _get_rendered_submit_script(job_script, ctx)
    upload_submit_script(rendered_script, target_folder, job_script)
    on_hold_flag = "-H" if on_hold else ""
    sbatch_cmd = f"sbatch {on_hold_flag} {target_folder}/{job_script}"
    logger.info("SBATCH call: %s" % sbatch_cmd)
    sbatch_output = c.run(sbatch_cmd)
    if sbatch_output.failed:
      raise Exception("Failed to submit Job: %s" % sbatch_output.stderr)
    match = SBATCH_PATTERN.match(sbatch_output.stdout)
    if not match:
        raise Exception('Failed to get jobid' % sbatch_output.stdout )
    job_id = match.group(1)
    genotype.jobid = job_id
    genotype.save()
    logger.info('Parse job sucessfully submitted (%s)' % job_id)
    return job_id

def get_parse_job_result(job):
    """
    Stage out the statistics from the parse job
    """
    output_result = _read_file(job.id, f"{job.id}.stats.json")
    return json.loads(output_result.stdout)

def get_crosses_job_result(job):
    """Returns the results from the crosses_check"""
    output_result = _read_file(job.identifyjob.genotype.id, f'{job.pk}_crosses.matches.json')
    return json.loads(output_result.stdout)

def get_identify_job_result(job):
    """
    Function to stage-out result files and cleanup
    """
    target_folder = _get_target_folder(job.genotype.id)
    output_path = os.path.join(tempfile.gettempdir(),f"{job.id}.tsv")
    c.get(os.path.join(target_folder,f'{job.id}.scores.txt'), output_path)
    output_result = _read_file(job.genotype.id, f'{job.id}.matches.json')
    data = json.loads(output_result.stdout)
    return data, output_path

def cleanup_files(id):
    """
    Clean up files
    """
    target_folder = _get_target_folder(id)
    c.run('rm -fr %s' % target_folder)

def submit_identify_jobs(id, job_id=None):
    """
    Submit job to identify job
    """
    # Find out if stagejob exists
    genotype = _get_genotype(id)
    target_folder = _get_target_folder(id)
    job_script = 'identify_job.sh'
    ctx = {
        "walltime": '01:00:00',
        "memory": '4G',
        "id": id,
        "identify_job_id": None,
        "dataset": None,
        "workdir": target_folder
    }
    depends = ''
    parse_job_id = genotype.jobid
    if parse_job_id is not None:
        depends = '-d afterok:%s' % parse_job_id
    jobs = genotype.identifyjob_set.filter(pk=job_id) if job_id else genotype.identifyjob_set.all()
    jobids = []
    for job in jobs:
        ctx['identify_job_id'] = job.id
        ctx['dataset'] = job.dataset.name.lower()
        ctx['walltime'] = _get_walltime(job.walltime)
        ctx['memory'] = _get_memory(job.memory)
        rendered_script = _get_rendered_submit_script(job_script, ctx)
        job_script_final = f"{ctx['dataset']}-{job_script}"
        upload_submit_script(rendered_script, target_folder, job_script_final)
        sbatch_cmd = f"sbatch {depends} {target_folder}/{job_script_final}"
        logger.info("SBATCH call: %s" % sbatch_cmd)
        sbatch_output = c.run(sbatch_cmd)
        if sbatch_output.failed:
            raise Exception("Failed to submit Job: %s" % sbatch_output.stderr)
        match = SBATCH_PATTERN.match(sbatch_output.stdout)
        if not match:
            raise Exception('Failed to get jobid' % sbatch_output.stdout )
        job_id = match.group(1)
        job.jobid = job_id
        job.save()
        jobids.append(job_id)
        logger.info('Identify job sucessfully submitted (%s)' % job_id)
    if parse_job_id is not None:
        c.run('scontrol release %s' % parse_job_id)
    return jobids

def submit_crosses_job(job):
    """
    Submit job to crosses job
    """
    # Find out if stagejob exists
    id = job.identifyjob.genotype.id
    target_folder = _get_target_folder(id)
    job_script = 'crosses_job.sh'
    submit_script = '%s/%s' % (SUBMIT_SCRIPT_FOLDER, job_script)
    ctx = {
        "walltime": _get_walltime(job.walltime),
        "memory": _get_memory(job.memory),
        "id": id,
        "crosses_job_id": job.pk,
        "dataset": job.identifyjob.dataset.name.lower(),
        "workdir": target_folder
    }
    rendered_script = _get_rendered_submit_script(job_script, ctx)
    upload_submit_script(rendered_script, target_folder, job_script)
    sbatch_cmd = f"sbatch {target_folder}/{job_script}"
    logger.info("SBATCH call: %s" % sbatch_cmd)
    sbatch_output = c.run(sbatch_cmd)
    if sbatch_output.failed:
        raise Exception("Failed to submit Job: %s" % sbatch_output.stderr)
    match = SBATCH_PATTERN.match(sbatch_output.stdout)
    if not match:
        raise Exception('Failed to get jobid' % sbatch_output.stdout )
    job_id = match.group(1)
    job.jobid = job_id
    job.save()
    logger.info('Crosses job sucessfully submitted (%s)' % job_id)

def get_job_status(job_id):
    # TODO check for pending state
    check_cmd = f"squeue -j {job_id} -o %T -h"
    check_output = c.run(check_cmd, warn=True)
    if check_output.failed or check_output.stdout == "":
        check_cmd = "sacct -j %s.batch -o state -pn" % job_id
        check_output = c.run(check_cmd)
        status = check_output.stdout[:-1]
    slurm_status = check_output.stdout.strip().replace("|","")
    status = SLURM_STATUS_DICT.get(slurm_status, ERROR)
    logger.info('Job state is %s' % status)
    return status

def update_job_results(job):
    if isinstance(job, IdentifyJob):
        data, output_path = get_identify_job_result(job)
        django_file = File(open(output_path,'rb'))
        job.identify_file.save(f'{job.id}.tsv', django_file)
        os.unlink(output_path)
    elif isinstance(job, GenotypeSubmission):
        data = get_parse_job_result(job)
        data = OrderedDict(
            sorted(data.items(), key=lambda t: t[0], reverse=True))
    elif isinstance(job,CrossesJob):
        data = get_crosses_job_result(job)
    else:
        raise ValueError(f'Object {job} not supported')
    return data

def update_job_status(job):
    data = json.loads(job.statistics) if job.statistics else None
    if job.status in (CREATED, QUEUED, PROCESSING):
        new_status = get_job_status(job.jobid)
        job.status = new_status
        if new_status == FINISHED:
            if not job.statistics:
                data = update_job_results(job)
                job.statistics = json.dumps(data)
            # retrieve result
            job.finished = timezone.now()
            job.progress = 100
        elif new_status == PROCESSING:
            if not job.started:
                job.started = timezone.now()
        job.save()
    return data

def update_genotype_status(genotype):
    """Check if job is finished"""
    update_job_status(genotype)
    if genotype.status == FINISHED:
        for identify_job in genotype.identifyjob_set.all():
            data = update_job_status(identify_job)
            if data is not None and data['interpretation']['case'] == 3:
                crosses_job, created = CrossesJob.objects.get_or_create(identifyjob=identify_job, defaults={'status': CREATED})
                if created or not crosses_job.jobid:
                    submit_crosses_job(crosses_job)
            if hasattr(identify_job, 'crossesjob'):
                update_job_status(identify_job.crossesjob)

    if genotype.identify_finished:
        cleanup_files(genotype.id)

def identify_pipeline(id):
    stagein_identify_job(id)
    submit_parse_job(id, True)
    submit_identify_jobs(id)


num = int(input("Enter the Number:"))

number = num
sum = 0
while num != 0:
    d1 = num % 10
    num //= 10
    d2 = num % 10
    if d1 % 2 == 0 and d2 % 2 == 0:
        sum += (d1*d2)
print(f"Sum of product of consecutive even digits of {number} is: {sum}")


import networkx as nx

# considered graph connected
numberOfFU = 16

def breadth_search(graph):

    dict = {}
    listClosed = []
    for n in graph.nodes():
        dict[n] = graph.in_degree(n)
        print(n, graph.in_degree(n))

    listNodes = []
    for n in dict.keys():
        if dict[n] == 0:
            listNodes.append(n)

    while len(listNodes) != 0:
        node = listNodes[0]
        listNodes.remove(node)
        listClosed.append(node)
        for s in graph.successors(node):
            dict[s] = dict[s] - 1
            if dict[s] == 0:
                listNodes.append(s)

    print("Busca em Largura:", listClosed)

    return graph

if __name__ == "__main__":

    G = nx.DiGraph(nx.drawing.nx_pydot.read_dot("res/grafo1.dot"))

    numberOfNodes = len(G.nodes())
    print(numberOfNodes)
    number = round((numberOfNodes / numberOfFU))
    print(number)

    if ((numberOfNodes / numberOfFU) - number) <= 0:
        numberOfConfig = 2 if (number < 2) else number
    else:
        numberOfConfig = 2 if ((number + 1) < 2) else (number + 1)

    # Permite apenas dois vértices de entrada
    i = 0
    novos_nos = []
    for n in G.nodes():
        #print(n)

        if len(list(G.predecessors(n))) > 2:
            list_pre = G.predecessors(n)
            x = str(n)
            for e in list_pre:
                G.remove_edge(e, n)

            while len(list_pre) != 2:
                nodo = x[:4] + "N" + str(int(x[-2:]) + i)
                list_pre.append(nodo)
                novos_nos.append(nodo)
                G.add_edge(list_pre[0], nodo)
                G.add_edge(list_pre[1], nodo)

                list_pre.remove(list_pre[0])
                list_pre.remove(list_pre[0])
                i = i + 1
            G.add_edge(list_pre[0], n)
            G.add_edge(list_pre[1], n)

    for n in novos_nos:
        print(G.predecessors(n))
        if len(G.predecessors(n)) > 2:
            list_pre = G.predecessors(n)
            x = str(n)

            for e in list_pre:
                G.remove_edge(e, n)

            while len(list_pre) != 2:
                nodo = x[:4] + "N" + str(int(x[-2:]) + i)
                list_pre.append(nodo)

                G.add_edge(list_pre[0], nodo)
                G.add_edge(list_pre[1], nodo)

                list_pre.remove(list_pre[0])
                list_pre.remove(list_pre[0])
                i = i + 1
            G.add_edge(list_pre[0], n)
            G.add_edge(list_pre[1], n)

    # return print of graph in breadth
    G = breadth_search(G)

    config = []
    time = []

    nx.drawing.nx_pydot.write_dot(G, "res/grafo_final.dot")

    for n in G.nodes():
        if len(list(G.predecessors(n))) > 2:
            print("Something is WRONG")
            print(n)


import os
from launch import git_clone, is_installed, run_pip

def main():
    packages = [
        'webuiapi',
        'peakutils',
        'ffmpeg'
    ]
    for m in packages:
        try:
            if not is_installed(m):
                run_pip(f'install {m}', f'mov-scale: {m}')
        except Exception as e:
            print(e)

    sd_root = os.getcwd()
    sd_extensions = os.path.join(sd_root, 'extensions')

    # git_clone('https://github.com/pkuliyi2015/sd-webui-stablesr.git',
    #           os.path.join(sd_extensions, 'sd-webui-stablesr'), "StableSR")
    # git_clone('https://github.com/pkuliyi2015/multidiffusion-upscaler-for-automatic1111.git',
    #           os.path.join(sd_extensions, 'multidiffusion-upscaler-for-automatic1111'), "Tiled Diffusion & VAE")

if __name__ == "__main__":
    main()


"""
David Wang (23064035)
Hannah Doret (22846377)
"""

from rdflib import Graph, Literal, RDFS
from rdflib.namespace import RDF, Namespace
from assessments import determine_assessments
import json

#Open and parse json objects
with open('units.json', 'r') as units:
    units_data = json.load(units)
units.close()

with open('majors.json', 'r') as majors:
    majors_data = json.load(majors)
majors.close()

#Create Graph and Namespace
g = Graph()
h = Namespace("http://university.org/")

g.bind("handbook", h)

#Create classes
unit = h.unit
school = h.school
board_of_examiners = h.board_of_examiners
delivery_mode = h.delivery_mode
level = h.level
assessment = h.assessment
major = h.major
course = h.course

#Add Classes
g.add((unit, RDF.type, RDFS.Class))
g.add((unit, RDFS.label, Literal("Unit")))
g.add((school, RDF.type, RDFS.Class))
g.add((school, RDFS.label, Literal("School")))
g.add((board_of_examiners, RDF.type, RDFS.Class))
g.add((board_of_examiners, RDFS.label, Literal("Board of Examiners")))
g.add((delivery_mode, RDF.type, RDFS.Class))
g.add((delivery_mode, RDFS.label, Literal("Delivery Mode")))
g.add((level, RDF.type, RDFS.Class))
g.add((level, RDFS.label, Literal("Level")))
g.add((assessment, RDF.type, RDFS.Class))
g.add((assessment, RDFS.label, Literal("Assessment")))
g.add((major, RDF.type, RDFS.Class))
g.add((major, RDFS.label, Literal("Major")))
g.add((course, RDF.type, RDFS.Class))
g.add((course, RDFS.label, Literal("Course")))

# Create specific assessment objects
participation = h.participation
group = h.group
practical = h.practical
oral = h.oral
written = h.written
multimedia = h.multimedia
project = h.project
exam = h.exam
test = h.test
misc = h.misc

# Add assessment objects (type = assessment class)
g.add((participation, RDF.type, assessment))
g.add((group, RDF.type, assessment))
g.add((practical, RDF.type, assessment))
g.add((oral, RDF.type, assessment))
g.add((written, RDF.type, assessment))
g.add((multimedia, RDF.type, assessment))
g.add((project, RDF.type, assessment))
g.add((exam, RDF.type, assessment))
g.add((test, RDF.type, assessment))
g.add((misc, RDF.type, assessment))

#Create relations
has_title = h.has_title
has_school = h.has_school
has_board_of_examiners = h.has_board_of_examiners
has_unit_delivery_mode = h.has_unit_delivery_mode
has_level = h.has_level
has_description = h.has_description
has_credit = h.has_credit
has_outcome = h.has_outcome
has_assessment = h.has_assessment
has_prerequisite = h.has_prerequisite
has_advisable_prior_study = h.has_advisible_prior_study
has_note = h.has_note
major_of_courses = h.major_of_courses
has_unit = h.has_unit
has_bridging = h.has_bridging
has_major = h.has_major
has_name = h.has_name # used for assessment object names eg. "exam"
has_number = h.has_number # used to give level objects an integer literal, bc integers are easier to use in SHACL
has_contact_hrs = h.has_contact_hrs

#Add relations
g.add((has_title, RDF.type, RDF.Property))
g.add((has_school, RDF.type, RDF.Property))
g.add((has_board_of_examiners, RDF.type, RDF.Property))
g.add((has_unit_delivery_mode, RDF.type, RDF.Property))
g.add((has_level, RDF.type, RDF.Property))
g.add((has_description, RDF.type, RDF.Property))
g.add((has_credit, RDF.type, RDF.Property))
g.add((has_outcome, RDF.type, RDF.Property))
g.add((has_assessment, RDF.type, RDF.Property))
g.add((has_prerequisite, RDF.type, RDF.Property))
g.add((has_advisable_prior_study, RDF.type, RDF.Property))
g.add((has_note, RDF.type, RDF.Property))
g.add((major_of_courses, RDF.type, RDF.Property))
g.add((has_unit, RDF.type, RDF.Property))
g.add((has_bridging, RDF.type, RDF.Property))
g.add((has_major, RDF.type, RDF.Property))
g.add((has_name, RDF.type, RDF.Property))
g.add((has_number, RDF.type, RDF.Property))
g.add((has_contact_hrs, RDF.type, RDF.Property))

#Use Json object to add to graph
for unit_name in units_data:
    unit_code = h[unit_name]
    unit_school = h[units_data[unit_name]["school"].replace(" ", "_")]
    unit_board_of_examiners = h[units_data[unit_name]["board_of_examiners"].replace(" ", "_")]
    unit_delivery_mode = h[units_data[unit_name]["delivery_mode"].replace(" ", "_")]
    unit_level = h[units_data[unit_name]["level"].replace(" ", "_")]

    #Name
    g.add((unit_code, RDF.type, unit))
    g.add((unit_code, RDFS.label, Literal(unit_name)))

    #Title
    g.add((unit_code, has_title, Literal(units_data[unit_name]["title"])))

    #School
    g.add((unit_school, RDF.type, school))
    g.add((unit_school, RDFS.label, Literal(units_data[unit_name]["school"])))
    g.add((unit_code, has_school, unit_school))

    #Board of Examiners
    if units_data[unit_name]["board_of_examiners"] != "" and units_data[unit_name]["board_of_examiners"] != "NA":
        g.add((unit_board_of_examiners, RDF.type, board_of_examiners))
        g.add((unit_board_of_examiners, RDFS.label, Literal(units_data[unit_name]["board_of_examiners"])))
        g.add((unit_code, has_board_of_examiners, unit_board_of_examiners))

    #Delivery mode
    g.add((unit_delivery_mode, RDF.type, delivery_mode))
    g.add((unit_delivery_mode, RDFS.label, Literal(units_data[unit_name]["delivery_mode"])))
    g.add((unit_code, has_unit_delivery_mode, unit_delivery_mode))

    #Level
    g.add((unit_level, RDF.type, level))
    g.add((unit_level, has_number, Literal(int(units_data[unit_name]["level"]))))
    g.add((unit_code, has_level, unit_level))

    #Description
    g.add((unit_code, has_description, Literal(units_data[unit_name]["description"])))

    #Credit
    if units_data[unit_name].get("credit") != None:
        credit = int(units_data[unit_name]["credit"])
        g.add((unit_code, has_credit, Literal(int(credit))))
    else:
        g.add((unit_code, has_credit, Literal(int(0))))

    #Assessments
    assessments = []
    for assessment_item in units_data[unit_name]["assessment"]:
        these_assessments = determine_assessments(assessment_item)
        # add assessments we found to the assessments list, without duplicates
        for assessment in these_assessments:
            if assessment not in assessments:
                assessments.append(assessment)
    for a in assessments:
        # refer to the URI we already created for this type of assessment, and add relation to it
        assessment_object = h[a]
        g.add((unit_code, has_assessment, assessment_object))

    #Outcomes
    if units_data[unit_name].get("outcomes") != None:
        for unit_outcome in units_data[unit_name]["outcomes"]:
            g.add((unit_code, has_outcome, Literal(unit_outcome)))

    #Prerequisites
    if units_data[unit_name].get("prerequisites_cnf") != None:
        full_prerequisite = []
        for prerequisite_thing in units_data[unit_name]["prerequisites_cnf"]:
            for prereq in prerequisite_thing:
                full_prerequisite.append(prereq)
        for prerequisite_item in full_prerequisite:
            g.add((unit_code, has_prerequisite, h[prerequisite_item.replace(" ", "_")]))

    #Advisable Prior Study
    if units_data[unit_name].get("advisable_prior_study") != None:
        for advisable_item in units_data[unit_name]["advisable_prior_study"]:
            g.add((unit_code, has_advisable_prior_study, h[advisable_item.replace(" ", "_")]))

    #Contact hours
    if units_data[unit_name].get("contact") != None:
        hours = 0
        for contact_item in units_data[unit_name]["contact"]:
            hours += int(units_data[unit_name]["contact"][contact_item])
        g.add((unit_code, has_contact_hrs, Literal(int(hours))))
    else:
        g.add((unit_code, has_contact_hrs, Literal(int(0))))

    #Note
    if units_data[unit_name].get("note") != None:
        g.add((unit_code, has_note, Literal(units_data[unit_name]["note"])))

#Add majors data
for major_name in majors_data:
    major_code = h[major_name]
    g.add((major_code, RDF.type, major))
    g.add((major_code, RDFS.label, Literal(major_name)))
    g.add((major_code, has_title, Literal(majors_data[major_name]["title"])))
    g.add((major_code, has_description, Literal(majors_data[major_name]["description"])))

    for this_course in majors_data[major_name]["courses"]:
        major_course = h[this_course]
        g.add((major_course, RDF.type, course))
        g.add((major_code, major_of_courses, major_course))

    major_school = h[majors_data[major_name]["school"].replace(" ", "_")]
    g.add((major_school, RDF.type, school))
    g.add((major_school, RDFS.label, Literal(majors_data[major_name]["school"])))
    g.add((major_code, has_school, major_school))

    for bridging_unit in majors_data[major_name]["bridging"]:
        unit_code = h[bridging_unit]
        g.add((unit_code, RDF.type, unit))
        g.add((major_code, has_bridging, unit_code))

    for taught_unit in majors_data[major_name]["units"]:
        unit_code = h[taught_unit]
        g.add((unit_code, RDF.type, unit))
        g.add((major_code, has_unit, unit_code))
        g.add((unit_code, has_major, major_code))

    if majors_data[major_name].get("outcomes") != None:
        for major_outcome in majors_data[major_name]["outcomes"]:
            g.add((major_code, has_outcome, Literal(major_outcome)))

# output graph
g.serialize(destination = "handbook.ttl", format='ttl', indent=4)


"""Utility Functions (lib/utils.c).

https://github.com/thom311/libnl/blob/libnl3_2_25/lib/utils.c

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation version 2.1
of the License.
"""

def __type2str(type_, buf, _, tbl):
    """https://github.com/thom311/libnl/blob/libnl3_2_25/lib/utils.c#L968.

    Positional arguments:
    type_ -- integer, key to lookup in `tbl`.
    buf -- bytearray().
    _ -- unused.
    tbl -- dict.

    Returns:
    Reference to `buf`.
    """
    del buf[:]
    if type_ in tbl:
        buf.extend(tbl[type_].encode('ascii'))
    else:
        buf.extend('0x{0:x}'.format(type_).encode('ascii'))
    return buf


#！/user/bin/env pythone2.7
#! -*- coding:utf-8 -*-
#! @Time : 2019/8/1 14:13
#! @Auther : Yu Kunjiang
#! @File : excel_to_list.py

import xlrd

def excel_to_list(data_file, sheet):
    '''
    excel文件要求首行为表头，组成dict的key，其余为数据，组成value，最后得到一个list，其中元素都是字典，
    字典的key即为第一行表头，每一行数据加上对应的key组成一个字典类型
    :param data_file: file path
    :param sheet: sheet name
    :return: [{key1:a,key2:b}, {key1:c,key2:d}...]
    '''
    data_list = []
    wb = xlrd.open_workbook(data_file)
    sh = wb.sheet_by_name(sheet)
    header = sh.row_values(0)
    for i in range(1,sh.nrows):
        d = dict(zip(header,sh.row_values(i)))
        data_list.append(d)
    return data_list


class User:
    def __init__(self, username, email_address):
        self.name = username
        self.email = email_address
        self.account = BankAccount(int_rate = 0.02, balance=0)

    def make_deposit(self, amount):
        self.account.deposit(amount)
        return self

    def make_withdrawal(self, amount):
        self.account.withdraw(amount)
        return self

    def display_user_balance(self):
        self.account.display_account_info
        return self

    def transfer_money(self, user, amount):
        self.account.withdraw(amount)
        user.account.deposit(amount)
        return self

class BankAccount:
    def __init__(self, int_rate, balance=0):
        self.balance = balance
        self.int_rate = int_rate

    def deposit(self, amount):
        self.balance += amount
        return self

    def withdraw(self, amount):
        if self.balance - amount > 0:
            self.balance -= amount
        else:
            print('Insufficient funds: Charging a $5 fee.')
            self.balance -= (amount + 5)
        return self

    def display_account_info(self):
        print('Balance: $' + str(self.balance))
        return self

    def yield_interest(self):
        if self.balance > 0:
            self.balance *= (self.int_rate * 100)
        return self

acct1 = BankAccount(.3, 400)
acct2 = BankAccount(.2)

acct1.deposit(400).deposit(32).deposit(99).withdraw(44).yield_interest().display_account_info()
acct2.deposit(11).deposit(44).withdraw(88).withdraw(1).withdraw(2).withdraw(33).yield_interest().display_account_info()

user1 = User('Big Ron', 'br@69.com')
user2 = User('Scott A', 's@a.a')
user3 = User('Steaky', 'bramble@69')

user1.make_deposit(10).make_deposit(400).make_deposit(100000).make_withdrawal(44).display_user_balance()

user2.make_deposit(50).make_deposit(44).make_withdrawal(11).make_withdrawal(1).display_user_balance()

user3.make_deposit(5000).make_withdrawal(44)
user3.make_withdrawal(22).make_withdrawal(6666666).display_user_balance()

user1.transfer_money(user3, 500000).display_user_balance()
user3.display_user_balance()


# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def sumEvenGrandparent(self, root: TreeNode) -> int:
        graph = defaultdict(list)
        ans = 0
        visited = set()
        add = []

        def helper(head, depth):
            if not head:
                return
            if depth == 2:
                if head not in visited:
                    nonlocal ans
                    ans += head.val
                    add.append(head.val)
                return

            helper(head.left, depth+1)
            helper(head.right, depth+1)

            return

        def dfs(head):
            if not head:
                return

            if head.val % 2 == 0:
                helper(head, 0)

            dfs(head.left)
            dfs(head.right)

            return

        dfs(root)
        # print('ans: ', ans)
        # print('arr: ', add)

        return ans


import gym
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.distributions import Categorical

action_size = 2
state_size = 4

class ActorCritic2(nn.Module) :
    def __init__(self) :
        super(ActorCritic2, self).__init__()

        self.dense_1 = nn.Linear(state_size, 128)
        self.probability = nn.Linear(128, action_size)
        self.value = nn.Linear(128, 1)

    def forward(self, x) :
        print("Data ", x, x.shape)
        out_1 = F.relu(self.dense_1(x))
        probs = self.probability(out_1)
        value = self.value(out_1)
        return F.softmax(probs, dim = -1), value

class Runner() :
    def __init__(self, env, gamma = 0.99, n_episode = 10000) :
        self.model = ActorCritic2()
        self.env = env
        self.optimizer = optim.Adam(self.model.parameters(), lr = 1e-2)
        self.memory = []
        self.gamma = gamma
        self.log_delay = 50
        self.n_episode = n_episode
        self.batch_size = 32
        self.epsilon = np.finfo(np.float32).eps.item()

    def select_action(self, state) :
        state = torch.from_numpy(state).float()
        probs, value = self.model(state)
        m = Categorical(probs)
        action = m.sample()
        self.memory.append((m.log_prob(action), value))
        return action.item()

    def replay(self, rewards_log) :
        memorized = self.memory
        policy_loss = []
        value_loss = []
        rewards = []
        R = 0
        for rew in rewards_log[::-1]: # Compute reward for trajectoire
            R = rew + self.gamma * R
            rewards.append(R)
        rewards.reverse()
        rewards = torch.tensor(rewards)
        rewards = (rewards - rewards.mean()) / (rewards.std() + self.epsilon) # Normalize
        for (log_prob, value), r in zip(memorized, rewards):
            Advantage = r - value.item() # Advantage estimate
            policy_loss.append(-log_prob * Advantage) # Policy gradient loss
            value_loss.append(F.smooth_l1_loss(value, torch.tensor([r]))) # Minimize R_T - prediction
        self.optimizer.zero_grad()
        loss = torch.stack(policy_loss).sum() + torch.stack(value_loss).sum() # Remove gradient, maintain loss value
        loss.backward()
        self.optimizer.step()
        self.memory = []

    def run(self) :
        rewards = []
        for i_episode in range(self.n_episode) :
            state = self.env.reset()
            ep_reward = 0
            for t in range(1000) : # Collect trajectoire
                action = self.select_action(state)
                state, reward, done, _ = env.step(action)
                ep_reward += reward
                rewards.append(reward)
                if done :
                    break
            self.replay(rewards)
            rewards = []
            if i_episode % self.log_delay == 0:
                print("Episode {} with reward : {}".format(i_episode, ep_reward))

if __name__ == '__main__' :
    env = gym.make('CartPole-v0')
    env.seed(42)
    torch.manual_seed(42)
    runner = Runner(env)
    runner.run()


import pandas as pd
import numpy as np
from PIL import Image

BUCKET_NAME = "GlobalGreening"
images_dir = "NDVI_2002" # NDVI_2010 NDVI_2014 NDVI_2018 NDVI_2022
masks_dir = "ESA_worldcover"
dataset_root_folder = "/Users/timfrith/code/Alastair908/GlobalGreening/raw_data"

def load_images_ndvi(dataset_root_folder, images_dir, DataFrame_locations):
    images_dataset = []

    for index,row in DataFrame_locations.iterrows():
        id_ = index
        longitude = row['longitude']
        latitude = row['latitude']

        image_file =f'image{id_}_{longitude}_{latitude}.png'
        path_image = f'{dataset_root_folder}/{images_dir}/{image_file}'
        # print(f'loading the image from these file {path_image}')

        image = Image.open(path_image)
        type(image)
        if np.asarray(image).shape  == (512,512,2):
            image = image.convert('L')

        image = np.asarray(image)
        images_dataset.append(image)
        # print(f'appended image of size {image.shape}')

    images_dataset = np.array(images_dataset)

    return images_dataset

def ndvi_mean(mask, image):
    '''Calculate the mean result of the mask and image'''

    np_image = np.array(image)

    layered = mask[:,:,0] * np_image

    mean =  layered[np.nonzero(layered)].mean()

    return mean

def ndvi_mid_layer(mask, image):

    np_image = np.array(image)

    layered = mask[:,:,0] * np_image

    return layered


from .message import Message
from .bigbox import Bigbox

class Gimbal:
    """Represent a Levitezer Gimbal. This class help to control a Gimbal"""
    _deviceType = 1
    _degreeUnit = 0.02197265625

    def __init__(self, bigbox, deviceId):
        """Init a Gimbal by initializing it with the conencted bigbox and it Id"""
        self.deviceId = deviceId
        self.states = GimbalStates()
        self.bigbox = bigbox
        self.bigbox.addListener(self.deviceId, self.states.updateStates)

    def setAngle(self, roll, pitch, yaw, rollSpeed, pitchSpeed, yawSpeed):
        """Set the Gimbal position"""
        mode = 2

        # convert angle to raw value
        rawRoll = int(roll / Gimbal._degreeUnit)
        rawPitch = int(pitch / Gimbal._degreeUnit)
        rawYaw = int(yaw / Gimbal._degreeUnit)

        message = Message(self.deviceId, Gimbal._deviceType)

        message.parameters.append({'id': 4, 'value': rawRoll})
        message.parameters.append({'id': 5, 'value': rawPitch})
        message.parameters.append({'id': 6, 'value': rawYaw})

        message.parameters.append({'id': 10, 'value': rollSpeed})
        message.parameters.append({'id': 11, 'value': pitchSpeed})
        message.parameters.append({'id': 12, 'value': yawSpeed})

        message.parameters.append({'id': 16, 'value': mode})

        self.bigbox.sendMessage(message)

    def move(self, rollSpeed, pitchSpeed, yawSpeed):
        """Move Gimbal in the specified direction. Positive values for clockwise direction and negative values for counterclockwise direction"""
        mode = 1

        message = Message(self.deviceId, Gimbal._deviceType)

        message.parameters.append({'id': 10, 'value': rollSpeed})
        message.parameters.append({'id': 11, 'value': pitchSpeed})
        message.parameters.append({'id': 12, 'value': yawSpeed})

        message.parameters.append({'id': 16, 'value': mode})

        self.bigbox.sendMessage(message)

    def reset(self):
        """Shortcut to set Gimbal to initial position"""
        self.setAngle(0, 0, 0, 500, 500, 1000)

    def setFrequency(self, ms):
        """Set how much time to wait in miliseconds before that Gimbal returns a message"""
        message = Message(self.deviceId, Gimbal._deviceType)
        message.parameters.append({'id': 19, 'value': ms})
        self.bigbox.sendMessage(message)

class GimbalStates:
    """Helper class to store values received from Gimbal"""
    def __init__(self):
        self.imu_roll = None
        self.imu_pitch = None
        self.imu_yaw = None
        self.roll = None
        self.pitch = None
        self.yaw = None
        self.timestamp = None
        self.accel_roll = None
        self.accel_pitch = None
        self.accel_yaw = None
        self.angle_completed = None
        self.request_real_time_data = None
        self.board_version = None
        self.firmware_version = None

    def updateStates(self, message):
        for parameter in message.parameters:
            id = parameter['id']
            value = parameter['value']
            if id == 1:
                self.imu_roll = int(value * Gimbal._degreeUnit)
            if id == 2:
                self.imu_pitch = int(value * Gimbal._degreeUnit)
            if id == 3:
                self.imu_yaw = int(value * Gimbal._degreeUnit)
            if id == 4:
                self.roll = int(value * Gimbal._degreeUnit)
            if id == 5:
                self.pitch = int(value * Gimbal._degreeUnit)
            if id == 6:
                self.yaw = int(value * Gimbal._degreeUnit)
            if id == 7:
                self.timestamp = value
            if id == 13:
                self.accel_roll = value
            if id == 14:
                self.accel_pitch = value
            if id == 15:
                self.accel_yaw = value
            if id == 18:
                self.angle_completed = value
            if id == 19:
                self.request_real_time_data = value
            if id == 21:
                self.board_version = value
            if id == 22:
                self.firmware_version = value


from django.urls import path
from . import views

app_name = 'data'

urlpatterns = [
     path('visualise/', views.visualise_coordinates, name='visualise_coordinates'),
     path('frames/upload/', views.frames_upload, name='frames_upload'),
     path('session/init/', views.session_init, name='session_init'),
     path('api/init_user/', views.user_init, name='init_user'),
]