# -*- coding: utf-8 -*-
"""
Author   : Alexandre
Created  : 2021-06-30 11:58:56

Comments : (low-level) functions handling export of data / figures for HAL
"""

# %% IMPORTS

# -- global
import logging
import h5py
import numpy as np
from pathlib import Path
from datetime import datetime
from PyQt5.QtWidgets import QFileDialog, QMessageBox

# -- local

# -- logger
logger = logging.getLogger(__name__)

# %% DATA EXPORT FUNCTION

# == LOW LEVEL

def _exportDataDictAsCSV(self, dic, file_out):
    # -- gather all data from dic
    # get variable names
    variables = set()
    for dataset, meta_dic in dic.items():
        variables.update(meta_dic.keys())
    # gather all values
    dic_out = {"dataset": []}
    dic_out.update({name: [] for name in variables})
    for dataset, meta_dic in dic.items():
        if not meta_dic:
            continue
        n_runs = len(next(iter(meta_dic.values()))["val"])
        dataset_name = dataset.replace(" ", "_")
        dic_out["dataset"] += [dataset_name for i in range(n_runs)]
        for name, value in meta_dic.items():
            dic_out[name] += list(value["val"])
    # -- prepare output array
    set_name_length = np.max([len(name) for name in dic.keys()])
    dtype = [("dataset", f"U{set_name_length}")] + [(name, float) for name in variables]
    fmt = ["%s"] + ["%.8e" for name in variables]
    array_out = np.zeros(len(dic_out["dataset"]), dtype=dtype)
    for key, value in dic_out.items():
        array_out[key] = value
    # -- prepare header
    sep = "-" * 48 + "\n"
    header = f"Generated by {self._name} v{self._version}"
    header += f" on {datetime.now():%Y-%m-%d %H:%M:%S} \n"
    header += sep
    header += "data info : \n"
    header += "----------- \n"
    for name, value in meta_dic.items():
        info = value["info"]
        info_str = ""
        for field in ["name", "unit", "comment"]:
            if field in info and info[field]:
                info_str += f"     - {field} : {info[field]} \n"
        if info_str:
            header += f"  + {name} \n" + info_str
    header += sep
    header += "data order : " + ", ".join([d[0] for d in dtype]) + "\n"
    header += sep[:-1]
    # -- save
    np.savetxt(file_out, array_out, header=header, comments="# ", fmt=" ".join(fmt))

def _exportDataDictAsHDF5(self, dic, file_out):
    with h5py.File(str(file_out), "w") as f:
        # set global attributes
        f.attrs["software name"] = self._name
        f.attrs["software version"] = self._version
        f.attrs["software url"] = self._url
        f.attrs["created on"] = f"{datetime.now():%Y-%m-%d %H:%M:%S}"
        # store data for each dataset
        for dataset, meta_dic in dic.items():
            group = f.create_group(dataset)
            for name, value in meta_dic.items():
                dset = group.create_dataset(name, data=value["val"])
                for k, v in value["info"].items():
                    if k in ["unit", "comment", "name"]:
                        dset.attrs[k] = v

# == HIGH LEVEL

def exportDataDictAs(self, dic):
    """Exports a data dictionnary in various formats"""
    # -- prepare available formats
    export_list = {}
    export_list["csv file (*.csv)"] = (_exportDataDictAsCSV, ".csv")
    export_list["hdf5 file (*.hdf5)"] = (_exportDataDictAsHDF5, ".hdf5")
    # -- select output file
    folder = self.current_export_folder
    folder = str(folder) if folder is not None else folder
    dlg = QFileDialog(self, "Select output file", folder)
    dlg.setNameFilters(list(export_list.keys()))
    dlg.setFileMode(QFileDialog.AnyFile)
    dlg.setAcceptMode(QFileDialog.AcceptSave)
    if not dlg.exec():
        logger.debug("Why do you bother me then ?")
        return
    # -- save
    # get file name
    filename = dlg.selectedFiles()[0]
    filepath = Path(filename)
    # check if the file exist, so that we don't ask overwrite confirmation twice
    license_to_kill = filepath.is_file()
    # check selected format
    fmt = dlg.selectedNameFilter()
    if fmt not in export_list:
        logger.warning(f"Requested format '{fmt}'' is not implemented")
        return
    # get extension / append default if missing
    export_func, default_suffix = export_list[fmt]
    if not filepath.suffix:
        filepath = filepath.with_suffix(default_suffix)
    # store current folder
    self.current_export_folder = filepath.parent
    # if file exist, ask for confirmation
    # NB : already handled by QFileDialog, but since we might hav
    # changed the suffix we have to check a second time
    if filepath.is_file() and not license_to_kill:
        msg = f"{filepath} exists : overwrite ?"
        title = "This mission is too important..."
        answer = QMessageBox.question(
            self, title, msg, QMessageBox.Yes | QMessageBox.No
        )
        if answer == QMessageBox.No:
            return
    # export
    export_func(self, dic, str(filepath))
    logger.debug(f"Saved as {filepath}")


class Solution:
    def pancakeSort(self, arr: List[int]) -> List[int]:
        currMax = max(arr)
        ans = []
        while currMax > 1:
            maxInd = arr.index(currMax)
            if maxInd + 1 == currMax:
                currMax -= 1
                continue
            else:
                arr[0:maxInd+1]=reversed(arr[:maxInd+1])
                ans.append(maxInd+1)

            arr[:currMax] = reversed(arr[:currMax])
            ans.append(currMax)
            currMax -= 1

        return ans


from flask import Flask;
import importlib;

STATIC_URL_PATH_ATTRIBUTE_NAME = 'STATIC_URL_PATH';

class AppFactory:
    @staticmethod
    def create_app(config_class):
        """Send a email with the latest HED schema.

        Parameters
        ----------
        config_class: string
            The configuration class.

        Returns
        -------
        hedemailer app
            A hedemailer Flask app.
        """
        static_url_path = AppFactory.get_static_url_path(config_class);
        app = Flask(__name__, static_url_path=static_url_path);
        app.config.from_object(config_class);
        return app;

    @staticmethod
    def get_static_url_path(config_class):
        """Gets the static url path of the app.

        Parameters
        ----------
        config_class: string
            The configuration class.

        Returns
        -------
        string
            The static URL path of the hedmailer Flask app.
        """
        config_module_name, config_class_name = config_class.split(".")
        config_module = importlib.import_module(config_module_name);
        config_class = getattr(config_module, config_class_name);
        return getattr(config_class, STATIC_URL_PATH_ATTRIBUTE_NAME, None);


import numpy as np

def Wagner_Whitin(k, h, b, D):
    """
    Wagner-Whitin algorithm for production planning
    :param k: (float) fixed cost
    :param h: (float) unit inventory holding cost
    :param b: (float) production cost
    :param D: (list) demand w.r.t time
    :return:
    """
    time_len = len(D)
    values = list(np.zeros(time_len+1))
    actions = list(np.zeros(time_len))
    for t in range(time_len, 0, -1):
        v_t = float('inf')

        for j in range(time_len-t+1):
            c_tj = k + b*D[t-1]
            for m in range(j, 0, -1):
                c_tj += h*m*D[t+m-1] + b*D[t+m-1]
            if c_tj + values[t+j] < v_t:
                v_t = c_tj + values[t+j]
                a_t = j

        values[t-1] = v_t
        actions[t-1] = a_t

    return values, actions

if __name__ == '__main__':

    print('Another test case for in-class quiz 2 example:')
    values, actions = Wagner_Whitin(k=3, h=0.5, b=1, D=[1, 3, 2, 4])
    print("Values-", values, "Actions-", actions)
    print("We see that it matches the optimal result, when b =! 0.")

    print('Test case for HW 2 Problem 2:')
    values, actions = Wagner_Whitin(k=2, h=0.2, b=0, D=[3, 2, 3, 2])
    print("Values-", values, "Actions-", actions)


import helpers
import unittest
import database as db
import copy

class TestDatabase(unittest.TestCase):

    def setUp(self):
        db.Clientes.lista = [
            db.Cliente("15J", "Marta", "Perez"),
            db.Cliente("48H", "Manolo", "Lopez"),
            db.Cliente("28Z", "Ana", "Garcia")
        ]

    def test_buscar_cliente(self):
        cliente_existente = db.Clientes.buscar("15J")
        cliente_inexistente = db.Clientes.buscar("99X")
        self.assertIsNotNone(cliente_existente)
        self.assertIsNone(cliente_inexistente)

    def test_crear_cliente(self):
        nuevo_cliente = db.Clientes.crear("39X", "Camilo", "Sanabria")
        self.assertEqual(len(db.Clientes.lista),4)
        self.assertEqual(nuevo_cliente.dni, "39X")
        self.assertEqual(nuevo_cliente.nombre, "Camilo")
        self.assertEqual(nuevo_cliente.apellido, "Sanabria")

    def test_modificar_cliente(self):
        cliente_a_modificar = copy.copy(db.Clientes.buscar("28Z"))
        cliente_modificado = db.Clientes.modificar("28Z", "Mariana", "Garcia")
        self.assertEqual(cliente_a_modificar.nombre, "Ana")
        self.assertEqual(cliente_modificado.nombre, "Mariana")

    def test_borrar_cliente(self):
        cliente_borrado = db.Clientes.borrar("48H")
        cliente_rebuscado = db.Clientes.buscar("48H")
        self.assertEqual(cliente_borrado.dni, "48H")
        self.assertIsNone(cliente_rebuscado)

    def test_dni_valido(self):
        self.assertTrue(helpers.dni_valido("00A", db.Clientes.lista))
        self.assertFalse(helpers.dni_valido("123445", db.Clientes.lista))
        self.assertFalse(helpers.dni_valido("F45", db.Clientes.lista))
        self.assertFalse(helpers.dni_valido("48H", db.Clientes.lista))


from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, include
#from rest_framework_swagger.views import get_swagger_view

#schema_view = get_swagger_view(title='Pastebin API')

urlpatterns = [
    #path('', schema_view),
    path('', admin.site.urls),
    path('api/', include('user.urls')),
    path('course/', include('course.urls')),
    path('question/', include('mcquestions.urls')),
    path('progres/', include('progress.urls')),

    path('rest-auth/', include('rest_auth.urls')),

]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

admin.site.site_header = "ANG"
admin.site.site_title = "ANG Admin Portal"
admin.site.index_title = "ANG Portal"


import sys
import math
import copy

n=1; deckList = ['AS', 'AH', 'AD', 'AC']
n=1; deckList = ['2S', '5D', 'QH', '3S', '4S', 'JH', 'JD', '5S', 'KH']
n=10;deckList = ['KS', 'KC', '4S', '5D', '7H', 'KH', 'AH', '9D', 'QH', '8S', '5C', 'JH', 'QS', '3S', 'AS', 'KD', '6D', '5H', '5S', 'JS']

deck1 = []
deck2 = []
ergList = []
erg = ""
split = int(len(deckList) / 2)
if len(deckList) % 2:
    split += 1

for i in range(n):
    deck1.clear();deck2.clear();ergList.clear()
    for j in range(len(deckList)):
        if j < split:
            deck1.append(deckList[j])
        else:
            deck2.append(deckList[j])
    one = True
    for j in range(len(deckList)):
        if one:
            ergList.append(deck1.pop(0));one=False
        else:
            ergList.append(deck2.pop(0));one=True

    deckList.clear();deckList = copy.deepcopy(ergList)

for i in range(len(ergList)):
    erg = erg + ergList[i] + " "
print(erg[:-1])


'''
백준 2812번 크게 만들기
그리디
'''
_, a = map(int, input().split())
N = list(input())

flg = 0
i = 0
ans = []
while i < len(N):
    if ans and \
       ans[-1] < N[i] and \
       flg < a:
        ans.pop()
        flg += 1
    else:
        ans.append(N[i])
        i += 1

if a > flg:
    ans = ans[:-(a-flg)]

print(''.join(ans))


from requests_html import HTMLSession
from bs4 import BeautifulSoup

a_buscar='jamon'
url_base='https://www.amazon.es/s?k='+a_buscar+'&__mk_es_ES=%C3%85M%C3%85%C5%BD%C3%95%C3%91&ref=nb_sb_noss'

s=HTMLSession()

def get_data(url):
	r=s.get(url)
	r.html.render(sleep=1)
	soup=BeautifulSoup(r.html.html,'html.parser')

	return soup

def next_page(soup):
	page=soup.find('ul',{'class':'a-pagination'})
	if not page.find('li',{'class':'a-disabled a-last'}):
		url='https://www.amazon.es/s?k='+str(page.find('li',{'class':'a-last'}).find('a')['href'])

	else:
		url=None

	return url

def pagination(url):
	lista_paginas=[]
	hay_siguiente=True
	while hay_siguiente:
		try:
			soup=get_data(url)
			url_siguiente=next_page(soup)
			url=url_siguiente
			if url!= None:
				lista_paginas.append(url)

		except:
			hay_siguiente=False
			print('Final del programa')

	return lista_paginas

print(pagination(url_base))


# coding: utf-8

import asyncio
import requests

from retrying_async import retry

def request_api_sync():
    print('正在获取')

    response = requests.get(url="https://www.google.com")
    print(response.status_code, response.content)
    raise Exception("异常")

@retry(attempts=3, delay=3)
async def request_api_async():
    print('正在获取')

    response = requests.get(url="https://www.google.com")
    print(response.status_code, response.content)
    raise Exception("异常")

if __name__ == '__main__':

    loop = asyncio.get_event_loop()
    loop.run_until_complete(request_api_async())


import logging
import time as tm

import numpy as np

__author__ = 'frank.ma'

logger = logging.getLogger(__name__)

class Maze(object):
    def print_maze(self):
        logger.info('size: [%i, %i]' % self.size)
        logger.info('start: [%i, %i]' % self.start)
        logger.info('end: [%i, %i]' % self.end)
        logger.info('maze:')
        logger.info(self.maze)
        return None

    def __init__(self, file_path: str):
        tic = tm.clock()
        # read header
        data = open(file_path)
        self.size = self.__read_line(data.readline())
        self.start = self.__read_line(data.readline())
        self.end = self.__read_line(data.readline())
        data.close()
        # read maze values
        self.maze = np.loadtxt(file_path, delimiter=' ', skiprows=3)
        logger.info('Finished data loading, took %r sec.' % round(tm.clock() - tic, 6))

    @staticmethod
    def __read_line(s: str):
        return tuple([int(x) for x in s.strip().split(sep=' ')])


# Competative Programming Question 169 = A. Div. 7 (From CodeForces)

"""
A. Div. 7 |

Get the Problem Statement on CodeForces : https://codeforces.com/problemset/problem/1633/A

And get the solution here, solved in python by me :}

"""

# Author = Abhinav
# Date = 7 February 2022
# Pourpose = Just for practise and imporving skills
# Source =  [CodeForces](https://codeforces.com/problemset/problem/1633/A)

# Solution :

def diff(i, j):
    n = 0
    for h, a in zip(i, j):
        if h != a:
            n += 1
    return n

for _ in range(int(input())):
    n = int(input())
    s1, s2 = str((n//7+1)*7), str((n//7)*7)
    if diff(str(n), s1) > diff(str(n), s2):
        print(s2)
    else:
        print(s1)


import os
#import cv2
import math
import time
import csv
import random
import numpy as np
import scipy.io as scio
import PIL.Image as Image
#from sklearn.metrics import confusion_matrix, roc_curve, average_precision_score, auc, f1_score

import argparse
parse = argparse.ArgumentParser('Train_Unimodal')
parse.add_argument('--gpu',type=str,default='0')
parse.add_argument('--patient_csv',type=str)
parse.add_argument('--path_lib',type=str,default='./weights/features/')
parse.add_argument('--omic_lib',type=str,default='./DATA/OMIC/')
parse.add_argument('--output_file',type=str,default='./weights/Fusion/')
parse.add_argument('--model_type',type=str,default='last')
parse.add_argument('--cross',type=int)  #int, 0-4, select from 5-fold
parse.add_argument('--modality',type=str) #'path'/'omic
parse.add_argument('--max_epoch',type=int)
parse.add_argument('--step_size',type=int)
parse.add_argument('--batch_size',type=int)
parse.add_argument('--lr',type=float)
args = parse.parse_args()

os.environ['CUDA_VISIBLE_DEVICES']=args.gpu

import torch
import torch.nn as nn
import torch.optim as opt
from torch.optim import lr_scheduler
from torch.autograd import Variable
from torchvision import transforms,models
import torch.nn.functional as F
from torch.utils.data import Dataset
from torch_geometric.data import Data

from model.SNN_model import define_net, define_optimizer
from model.GCN import GraphNet
from evaluation import calculate_metrics

cross = args.cross
modality = args.modality

train_cross = [cross%5,(cross+1)%5,(cross+2)%5]
val_cross = [(cross+3)%5]

csv_file = args.patient_csv
path_lib = os.path.join(args.path_lib, 'cross'+str(cross))
omic_lib = args.omic_lib
output_file = os.path.join(args.output_file, 'cross'+str(cross), modality+'_coatt')

path_coatt_feature = os.path.join(args.output_file, 'cross'+str(cross), 'coatt_feature/path')
omic_coatt_feature = os.path.join(args.output_file, 'cross'+str(cross), 'coatt_feature/omic')

load_coatt_path_name = os.path.join(args.output_file, 'cross'+str(cross), 'path/checkpoint_last.pth')
load_coatt_omic_name = os.path.join(args.output_file, 'cross'+str(cross), 'omic/checkpoint_last.pth')
load_model_test = os.path.join(output_file, 'checkpoint_'+args.model_type+'.pth')

lr = args.lr
max_epoch = args.max_epoch
step_size = args.step_size

#-----------------------------------------------------------------------------------------------#
# loss
class CrossEntropyLoss(nn.Module):
    def __init__(self):
        super(CrossEntropyLoss,self).__init__()

    def forward(self,y_pred, target):
        loss_function = nn.CrossEntropyLoss()
        loss = loss_function(y_pred, target)
        return loss

#-----------------------------------------------------------------------------------------------#
# data loader
class DataSet(Dataset):
    def __init__(self, cross_list, pathfile=path_lib, omicfile=omic_lib, pathcoattfile=path_coatt_feature, omiccoattfile=omic_coatt_feature):
        # list patient & label
        self.paths = []
        self.path_paths = []
        self.omics = []
        self.omic_paths = []
        self.targets = []

        csv_names = ['LUAD-', 'LUSC-']
        fold_names = ['TCGA-LUAD', 'TCGA-LUSC']

        for i in range(2):
            for j in cross_list:
                csv_path = os.path.join(csv_file, csv_names[i]+str(j)+'.csv')
                with open(csv_path) as f:
                    rows = csv.reader(f, delimiter = ',')
                    for row in rows:
                        uid = row[0]
                        label = i

                        path_fold = os.path.join(pathfile, fold_names[i], uid)
                        omic_path = os.path.join(omicfile, fold_names[i], uid+'.mat')
                        omic_fea_path = os.path.join(omic_coatt_feature, uid+'.mat')

                        if not os.path.exists(omic_path):
                            print('File ERROR! :', omic_path)
                            continue

                        if not os.path.exists(path_fold):
                            print('File ERROR! :', path_fold)
                            continue

                        imgs = os.listdir(path_fold)
                        for img in imgs:
                            path_path = os.path.join(path_fold, img)
                            path_fea_path = os.path.join(path_coatt_feature, uid, img)

                            if not os.path.exists(path_path):
                                print('File ERROR! :', path_path)
                            else:
                                self.paths.append(path_path)
                                self.path_paths.append(path_fea_path)
                                self.omics.append(omic_path)
                                self.omic_paths.append(omic_fea_path)
                                self.targets.append(int(label))

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

    def __getitem__(self,index):
        path_path = self.paths[index]
        path_fea_path = self.path_paths[index]
        omic_path = self.omics[index]
        omic_fea_path = self.omic_paths[index]

        # open path
        data_mat_path = scio.loadmat(path_path)
        path_features = torch.from_numpy(data_mat_path['feature'])
        #roi_seq = features.unsqueeze(0)
        edge_index = torch.from_numpy(data_mat_path['edge'])
        path_fea = torch.from_numpy(scio.loadmat(path_fea_path)['path_feature'])

        # open omic
        data_mat_omic = scio.loadmat(omic_path)
        omic_raw = torch.from_numpy(data_mat_omic['raw'])
        omic_fea = torch.from_numpy(scio.loadmat(omic_fea_path)['omic_feature'])

        target = np.array([self.targets[index]])

        return path_features, edge_index, omic_raw, torch.from_numpy(target), path_fea, omic_fea

#-----------------------------------------------------------------------------------------------#
# get coatt feature
def inference(model_coattn, modal):
    print('-----------------inference coattention feature-----------------------')
    model_coattn.eval()

    # metrics
    pred_epoch, true_epoch = None, None

    types = ['TCGA-LUAD', 'TCGA-LUSC']

    for i in range(2):
        uids = os.listdir(os.path.join(path_lib, types[i]))
        path_path = os.path.join(path_lib, types[i])
        omic_path = os.path.join(omic_lib, types[i])

        for uid in uids:
            if modal == 'omic':
                mat_path = os.path.join(omic_path, uid+'.mat')
                if not os.path.exists(mat_path):
                    continue
                data_mat_omic = scio.loadmat(mat_path)
                omic_raw = torch.from_numpy(data_mat_omic['raw'])
                omic_raw = omic_raw.to(torch.float32).cuda()
                target = np.array([i])

                att_features, _, out = model_coattn(x = omic_raw)
                att_features = att_features.cpu().detach().numpy()
                if not os.path.exists(omic_coatt_feature):
                    os.makedirs(omic_coatt_feature)
                scio.savemat(os.path.join(omic_coatt_feature,uid+'.mat'), {'omic_feature':att_features})

                out = nn.Softmax(dim=1)(out)
                pred_cpu = out.cpu().detach().numpy()
                true_cpu = target
                pred_epoch = np.concatenate((pred_epoch, pred_cpu), axis=0) if (pred_epoch is not None) else pred_cpu.copy()
                true_epoch = np.concatenate((true_epoch, true_cpu), axis=0) if (true_epoch is not None) else true_cpu.copy()

                acc, AUC, AP, f1score, sen, spe = calculate_metrics(pred_epoch, true_epoch)
                print("\r[omic] acc:{:.4f}, AUC:{:.4f}, AP:{:.4f}, f1:{:.4f}".format(acc, AUC, AP, f1score), end='')

            if modal == 'path':
                if not os.path.exists(os.path.join(path_path, uid)):
                    continue
                imgs = os.listdir(os.path.join(path_path, uid))
                for img in imgs:
                    mat_path = os.path.join(path_path, uid, img)
                    data_mat_path = scio.loadmat(mat_path)
                    path_features = torch.from_numpy(data_mat_path['feature']).cuda()
                    edge_index = torch.from_numpy(data_mat_path['edge']) .cuda()
                    data = Data(x=path_features, edge_index=edge_index)
                    target = np.array([i])

                    att_features, _, out = model_coattn(data=data)
                    att_features = att_features.cpu().detach().numpy()
                    if not os.path.exists(os.path.join(path_coatt_feature, uid)):
                        os.makedirs(os.path.join(path_coatt_feature, uid))
                    scio.savemat(os.path.join(path_coatt_feature, uid, img), {'path_feature':att_features})

                    out = nn.Softmax(dim=1)(out)
                    pred_cpu = out.cpu().detach().numpy()
                    true_cpu = target
                    pred_epoch = np.concatenate((pred_epoch, pred_cpu), axis=0) if (pred_epoch is not None) else pred_cpu.copy()
                    true_epoch = np.concatenate((true_epoch, true_cpu), axis=0) if (true_epoch is not None) else true_cpu.copy()

                    acc, AUC, AP, f1score, sen, spe = calculate_metrics(pred_epoch, true_epoch)
                    print("\r[path] acc:{:.4f}, AUC:{:.4f}, AP:{:.4f}, f1:{:.4f}".format(acc, AUC, AP, f1score), end='')

#-----------------------------------------------------------------------------------------------#
# train
def train_step(data_set, mode, epoch, criterion, net, optim):
    if mode == 'test':
        net.eval()
    else:
        net.train()
        print(30*'-', '\n[epoch', epoch+1,'] Learning Rate:{}'.format(optim.param_groups[0]['lr']))

    running_loss = 0.
    consume_time = 0.

    data_len = data_set.__len__()
    data_shuffle = random.sample(range(data_len),data_len)
    step = 0
    for i in data_shuffle:
        now = time.time()
        path_features, edge_index, omic_raws, targets, path_fea, omic_fea = data_set.__getitem__(i)
        path_features, edge_index = path_features.cuda(), edge_index.cuda()
        omic_raws = omic_raws.to(torch.float32).cuda()
        targets = targets.cuda()
        path_fea, omic_fea = path_fea.cuda(), omic_fea.cuda()

        data = Data(x=path_features, edge_index=edge_index)

        if mode != 'train':
            with torch.no_grad():
                if modality == 'path':
                    _, _, out = net(data, omic_fea, 1)
                    loss = criterion(out, targets)

                elif modality == 'omic':
                    _, _, out = net(path_fea, omic_raws, 1)
                    loss = criterion(out, targets)

        else:
            optim.zero_grad()

            if modality == 'path':
                _, _, out = net(data, omic_fea, 1)
                loss = criterion(out, targets)

            elif modality == 'omic':
                _, _, out = net(path_fea, omic_raws, 1)
                loss = criterion(out, targets)

            loss.backward()
            optim.step()

        # loss
        running_loss = (running_loss*step+loss.item())/(step+1)

        if mode != 'train':
            print("\r[Validation] Step {}/{}, loss:{:.5f}".\
                  format(step, data_len, running_loss), end='')
        else:
            print('\r[Train] Step {}/{}, loss:{:.5f}'.\
                  format(step, data_len, running_loss), end='')
        consume_time += time.time() - now
        step += 1

    print(' ')

    return running_loss, consume_time/step

#-----------------------------------------------------------------------------------------------#
# train main
def pretrain_unimodal_coattention(max_epoch=max_epoch, ModelSet = '', save_csv = True, save_best_model = True, save_last_model = True, \
                                  isload = False, load_model_name=''):
    torch.cuda.manual_seed_all(0)
    torch.manual_seed(0)
    random.seed(0)

    # get coatt feature
    if not os.path.exists(path_coatt_feature):
        model = GraphNet(feature_length=128, nhid=256)
        model.cuda()
        pretrained=torch.load(load_coatt_path_name)
        model.load_state_dict(pretrained['state_dict'])
        print('coattn path model load successfully: ',load_coatt_path_name)
        inference(model, 'path')
        del model
    if not os.path.exists(omic_coatt_feature):
        model = define_net()
        model.cuda()
        pretrained=torch.load(load_coatt_omic_name)
        model.load_state_dict(pretrained['state_dict'])
        print('coattn omic model load successfully: ',load_coatt_omic_name)
        inference(model, 'omic')
        del model

    # define net
    if modality == 'omic':
        model = define_net()
        model.cuda()
        optimizer = define_optimizer(model=model, lr=lr)
        #scheduler = define_scheduler(optimizer)
        scheduler = lr_scheduler.StepLR(optimizer,step_size=args.step_size,gamma=0.5)
    elif modality == 'path':
        model = GraphNet(feature_length=128, nhid=256)
        model.cuda()
        optimizer = opt.Adam(model.parameters(), lr=lr, weight_decay=1e-4)
        scheduler = lr_scheduler.StepLR(optimizer,step_size=args.step_size,gamma=0.5)

    criterion = CrossEntropyLoss().cuda()

    start_epoch = 0
    lowest_loss = float('Inf')  # 寻找最小loss

    train_set = DataSet(train_cross)
    val_set = DataSet(val_cross)

    for epoch in range(start_epoch, max_epoch):
        # train dataset
        running_loss, consume_time = \
            train_step(train_set, 'train', epoch, criterion, model, optimizer)

        scheduler.step()

        # validation dataset
        val_loss, consume_time = \
            train_step(val_set, 'test', epoch, criterion, model, optimizer)

        # save best model
        print('')
        if val_loss < lowest_loss:
            print('Val_loss is lower than previous {:.5f}. The new best model saved. '.format(lowest_loss))
            lowest_loss = val_loss
            #obj = {'state_dict': model.state_dict()}

            #torch.save(obj, os.path.join(ModelSet,'checkpoint_best.pth'))
            #print('Current loss < initial loss, best model save......')
            print('Current loss < initial loss......')
        else:
            print('Val_loss_all is not improved from {:.5f}. '.format(lowest_loss))

    # save model
    obj = {'state_dict': model.state_dict()}

    torch.save(obj, os.path.join(ModelSet,'checkpoint_last.pth'))
    print('Last model saved. ')

if __name__ == "__main__":
    if not os.path.exists(output_file):
        os.makedirs(output_file)
    print('-----------------start pretrain unimodal-----------------------')
    print('cross: ', cross)
    print('pretrain modality: ', modality)

    pretrain_unimodal_coattention(ModelSet = output_file)


import numpy as np
import math
from nn import NeuralNet
from typing import List, Dict, Tuple

class AimAssistant:
    """
    Wrapper around the neural net for data preprocessing / postprocessing
    """
    sides_crop = 0.3
    top_crop = 0.35

    def __init__(self, crop: bool = False):
        self.to_crop = crop
        try:
            self.net = NeuralNet()
        except Exception as e:
            print(f"Failed while NN initialization. Error: {e}")
            raise e
        print("Aim assistant successfully initialized")

    def aim(self, frame: np.ndarray) -> dict:
        """

        :param frame:
        :return:
        """
        # Режем кадр, чтобы оставить только центр картинки где располагается опора.
        if self.to_crop:
            relative_coord, frame = AimAssistant.crop_frame(frame, self.sides_crop, self.top_crop)

        # Detect components on the frame
        components = self.net.predict(frame)

        # If components, calculate angles relatively to the frame centre
        output = dict()
        if components:
            # Пересчитаем координаты коробок относительно целого кадра. Сейчас они относительно
            # вырезанного np.ndarray если стоял флаг self.to_crop
            if self.to_crop:
                components = AimAssistant.recalculate_boxes(components, relative_coord)
            output = AimAssistant.calculate_angles(components=components, frame=frame)

        return output

    @staticmethod
    def recalculate_boxes(predictions:List[list], sliced_image_coord: List[int]) -> List[list]:
        """
        Пересчитывает координаты коробки относительно оригинального кадра, а не вырезанной подкартинки
        :param predictions:
        :param sliced_image_coord:
        :return:
        """
        output = list()
        for prediction in predictions:
            class_id = prediction[0]
            conf = prediction[1]
            left = prediction[2] + sliced_image_coord[0]
            top = prediction[3] + sliced_image_coord[1]
            right = prediction[4] + sliced_image_coord[0]
            bot = prediction[5] + sliced_image_coord[1]
            assert all(e > 0 for e in [left, top, right, bot]), "Coordinates recalculated wrong"
            assert all((left < right, top < bot)), "Coordinates recalculated wrong"
            output.append([class_id, conf, left, top, right, bot])

        return output

    @staticmethod
    def crop_frame(frame: np.ndarray, sides: float = 0.3, top: float = 0.35) -> Tuple[list, np.ndarray]:
        """
        Вырезает картинки из кадра где находится опора. Отрезает края и верхушку кадра. Они нам не интеренсты
        если снимаем с курсовой камеры, которая смотрит перед собой.
        :param frame:
        :param sides:
        :param top:
        :return:
        """
        assert 0 < sides < 0.5, "Sides crop needs to be between 0 and 50%"
        assert 0 < top < 0.5, "Top crop needs to be between 0 and 50%"

        frame_height, frame_width = frame.shape[0], frame.shape[1]
        new_left = int(frame_width * sides)
        new_right = int(frame_width - (frame_width * sides))
        new_top = int(frame_height * top)
        new_bot = frame_height
        assert all((new_top < new_bot, new_left < new_right)), "Wrong cropped coordinates"

        #cv2.rectangle(frame, (new_left, new_top), (new_right, new_bot), (0, 255, 255), 2)
        try:
            cropped_image = np.array(frame[new_top:new_bot, new_left:new_right, :])
        except Exception as e:
            print("Failed while cropping the frame. Error: {e}")
            raise e

        return [new_left, new_top, new_right, new_bot], cropped_image

    @staticmethod
    def calculate_angles(components: List[list], frame: np.ndarray) -> Dict[int, dict]:
        """
        :param components: detected components
        :param frame: frame
        :return:
        """
        frame_centre = (frame.shape[1] // 2, frame.shape[0] // 2)  # x,y
        output = dict()
        output_schema = {
            "obj_class": int,
            "bb_centre": tuple,
            "bb_coord": list,
            "aim_angle": tuple,
            "bb_size": float
        }

        for i, component in enumerate(components):
            obj_class, conf = component[0], component[1]
            # Skip concrete pillars, we're interested in only insulators and dumpers
            if obj_class == 2:
                continue
            left, top = component[2], component[3]
            right, bot = component[4], component[5]

            # Calculate element's BB centre relatively to the whole image
            element_x_centre = (left + right) // 2
            element_y_centre = (top + bot) // 2

            # Calculate delta (image centre vs element centre)
            delta_x = abs(frame_centre[0] - element_x_centre)
            delta_y = abs(frame_centre[1] - element_y_centre)

            # Calculate angles
            angle_1 = round(np.rad2deg(np.arctan2(delta_x, delta_y)), 2)
            angle_2 = round(90 - angle_1, 2)
            assert all((0 <= angle_1 <= 90, 0 <= angle_2 <= 90)), "Wrong angles calculated. Expected: [0, 90]"

            # Estimate object's relative diameter
            element_BB_diagonal = math.sqrt((top - bot)**2 +(right - left)**2)
            frame_diagonal = math.sqrt((frame.shape[0])**2 + (frame.shape[1])**2)
            diagonal = round(element_BB_diagonal / frame_diagonal, 3)

            schema_instance = output_schema.copy()
            try:
                schema_instance["obj_class"] = obj_class
                schema_instance["bb_centre"] = (int(element_x_centre), int(element_y_centre))
                schema_instance["bb_coord"] = (left, top, right, bot)
                schema_instance["aim_angle"] = (angle_1, angle_2)
                schema_instance["bb_size"] = diagonal
            except Exception as e:
                print(f"Failed while filling the output schema instance. Error: {e}")
                raise e

            output[i] = schema_instance

        return output


from typing import Dict

from rlcard3.games.mocsar.action import Action
from rlcard3.model_agents.agent import Agent
from rlcard3.games.mocsar.utils import get_action_ids, action_to_ret, decode_obs
import numpy as np

class MocsarRandomAgent(Agent):
    """ Mocsar Rule agent version 1, take a random action
    """
    name: str  # Name of the agent
    id: str  # ID of the Agent

    def __init__(self):
        self.name = 'RandomAgent'
        self.id = "R"
        self.use_raw = True

    def __str__(self):
        return f"Agent:{self.name}"

    def step(self, state: Dict) -> str:
        """ Predict the action given raw state. A naive rule.
        Choose a random action.

        Args:
            state (dict): Raw state from the game

        Returns:
            action (str): Predicted action
        """
        is_extract = state['is_extract']
        action_ids = get_action_ids(legal_actions=state['legal_actions'],
                                    is_extracted=is_extract)
        if is_extract:
            state_to = decode_obs(obs=state['obs'])

            nr_cards = state_to['nr_cards_round']
        else:
            nr_cards = state['nr_cards_round']
        # DEBUG print(f"**Random Agent: ActionId:{action_ids}")
        if len(action_ids) == 1:
            # Ha nincs miből választani
            ret = action_ids[0]
        elif action_ids[0] == 0:
            # ha lehet választani, akor nem passzol
            ret = int(np.random.choice(action_ids[1:]))
        else:
            # Elvileg a pass nincs az actionök között, ha van több. Ennek ellenéra a random agentet hagyom passzolni
            # Úgy lehet detektálni, hogy ha van O/J action mód, akkor 10% valószínűséggel passzol.
            if (nr_cards >0) and (np.random.random() < 0.1):
                # Most paszol 10% valséggel.
                ret = 0
            else:
                ret = int(np.random.choice(action_ids))
        # DEBUG print(f"**Random Agent: ActionIds:{action_ids}, Ret: {ret}")
        return action_to_ret(action=ret, is_extracted=is_extract)

    def eval_step(self, state: Dict):
        """ Step for evaluation. The same to step
                """
        return self.step(state), []


# 약어 생성(create abbreviation)
# 사람 이름이 영어로 나열되면서 콤마(,)로 구분되어 있을 때, 약어를 자동으로
# 생성하는 프로그램을 만드시오. 사람 이름의 첫글자는 반드시 대문자로 입력.
# 예를 들어, Changwon,Science,High,School 이 입력되면 CSHS 를 출력한다.
# 입력은 한 줄로 이루어져 있고, 최대 100글자의 영어 알파벳 대문자, 소문자,
# 그리고 콤마(,)로만 이루어져 있다. 첫 글자는 반드시 대문자이고, 콤마 뒤에도
# 반드시 대문자이다. 그 외의 모든 문자는 소문자이다. 입력에 공백은 존재하지
# 않는다. | 약어를 출력한다.
#  method 1
d = list(input().split(','))
ab = []
for i in range(len(d)):
    ab.append(d[i][0])
for i in range(len(ab)):
    print(ab[i], end='')


import numpy as np
import pandas as pd

# Get top GDX component stock based on greatest market value but excluding exclude_stock
def get_top_gdx(gdx_components, quote_manager, exclude_stock=None, count=10):

    # Grab date from exclude_stock for checking quote data exists
    date = exclude_stock.name

    # Remove and symbols that don't have quote data available for current date
    gdx_refined = gdx_components.copy()
    for i in gdx_refined.index:
        if quote_manager.get_quote(gdx_refined[i], date.replace('-', '_')) == 'nan':
            gdx_refined = gdx_refined.drop(i)

    assert exclude_stock is not None, 'Error in get_top_gdx(): exclude_stock is None'
    diff = gdx_refined[~gdx_refined.isin(exclude_stock.index)]

    if len(diff) > count:
        return diff[:count]
    else:
        if len(diff) == 0:
            print("NO VALID GDX COMPONENT STOCK FOUND FOR DATE: %s" % date)
        return diff

# Get undervalued stock based on lowest signal value for a given date
def get_undervalued(signals, date, quote_manager, count=10):
    # Grab the signals for the date in question and order them
    day_signals = signals.loc[date.replace('_', '-')].order()
    day_signals_no_nans = day_signals[:day_signals.last_valid_index()]

    # Remove and symbols that don't have quote data available for current date
    for symbol in day_signals_no_nans.index:
        if quote_manager.get_quote(symbol, date) == 'nan':
            day_signals_no_nans = day_signals_no_nans.drop(symbol)

    # TODO: Return top 10 even if not negative? Currently yes.
    if len(day_signals_no_nans) > count:
        return day_signals_no_nans[:count]
    else:
        if len(day_signals_no_nans) == 0:
            print("NO VALID UNDERVALUED STOCK FOUND FOR DATE: %s" % date)
        return day_signals_no_nans

# Get next rebalance day without affecting whats_left list
def get_next_rebal_day(whats_left, period):

    # This loop iterates through signal days until the close of month is reached
    #   and iterates through months until the period is reached
    for _ in range(period):

        # Iterate through days until end of month is reached
        i = 0
        while True:

            # Grab the next day of signal values
            whats_next = whats_left[i]
            year, month = whats_next[:4], whats_next[5:7]

            # Get month close values by making sure the following day is a new month or year
            if year != whats_left[i+1][:4] or month != whats_left[i+1][5:7]:
                # Then break from intra-month loop
                break

            i += 1

    return whats_next

# Find rebalance days at a monthly frequency set by period
def get_rebal_days(whats_left, period):
    rebalance_days = []
    while whats_left:

        # This loop iterates through signal days until the close of month is reached
        #   and iterates through months until the period is reached
        for _ in range(period):

            # Iterate through days until end of month is reached
            while True:

                # Grab the next day of signal values
                whats_now = whats_left.pop(0)
                year, month = whats_now[:4], whats_now[5:7]

                # Get month close values by making sure the following day is a new month or year
                if len(whats_left) <= 0 or year != whats_left[0][:4] or month != whats_left[0][5:7]:
                    # Then break from intra-month loop
                    break

        # Add to rebalance days
        rebalance_days.append(whats_now)

    return rebalance_days

# Get change in value
def get_return(new_value, old_value):
    return new_value / old_value - 1


# http://codeforces.com/group/P8UZg7UOT5/contest/225111/problem/E

def AmrAndMusic():

    n, k = map(int, input().strip().split())
    learned = []

    inst = [ *map(int, input().strip().split()) ]

    if min(inst) > k:

        return 0

    else:

        inst = [ (inst[i], i) for i in range(len(inst)) ]

        inst.sort(key = lambda x: x[0] )

        print(inst)

    return learned

if __name__ == '__main__':

    a = AmrAndMusic()
    print(a)


from django.urls import path
from . import views

urlpatterns = [
    path("", views.dashboard, name='dashboard'),
    path("cotacao/", views.cotacao, name='cotacao'),
    path("entregas/", views.lista_entregas, name='entregas' ),
    path("formulario/", views.formulario, name='formulario')

    # Outras URLs relacionadas à cotação de entregas podem ser adicionadas aqui
]


# Once contacts are imported, we will create relationships
# Since Meetings are hierarchical along with Wagtail Pages,
# we need to move the existing pages to the correct parent.
# https://stackoverflow.com/a/57057466/1191545
import re

from django.core.exceptions import ObjectDoesNotExist
from contact.models import Meeting, MeetingPresidingClerk, Person, PersonIndexPage
from content_migration.management.shared import parse_csv_file

def extract_contact_id_from(contact_name: str) -> int:
    # Contact names contain contact ID in parenthesis
    regex = r"([0-9]+)"

    match = re.search(regex, contact_name).group(0)  # type: ignore

    return int(match)

def extract_given_name(given_name_with_contact_id: str) -> str:
    # name is first part before empty space
    return given_name_with_contact_id.split(" ")[0]

def extract_given_and_family_name(contact_name: str) -> list[str]:
    """Extract given and family names from a CiviCRM contact name string.

    CiviCRM contact export contains name in the following format.

    "family_name, given_name (contact_id)"
    """

    try:
        family_name, given_name_with_contact_id = contact_name.split(", ")
    except ValueError:
        family_name = ""
        given_name_with_contact_id = contact_name

    given_name = extract_given_name(given_name_with_contact_id)

    return [family_name, given_name]

def extract_contact_ids_from(relationship: dict) -> dict[str, int]:
    meeting_name = relationship["Contact B"]
    clerk_name = relationship["Contact A"]

    meeting_id = extract_contact_id_from(meeting_name)
    clerk_id = extract_contact_id_from(clerk_name)

    return {"meeting_id": meeting_id, "clerk_id": clerk_id}

def handle_import_civicrm_clerk_relationships(file_name: str) -> None:
    relationships = parse_csv_file(file_name)

    for relationship in relationships:
        contact_ids = extract_contact_ids_from(relationship)

        Meeting.objects.filter(
            civicrm_id=contact_ids["meeting_id"],
        ).exists()

        try:
            meeting = Meeting.objects.get(civicrm_id=contact_ids["meeting_id"])
        except ObjectDoesNotExist:
            print(
                f"Could not find meeting with CiviCRM ID { contact_ids['meeting_id'] }",  # noqa: E501
            )
            pass

        # try:
        #     clerk = Person.objects.get(civicrm_id=contact_ids["clerk_id"])
        # except ObjectDoesNotExist:
        #     print(
        #         f"Could not find person with CiviCRM ID { contact_ids['clerk_id'] }"  # noqa: E501
        #     )
        #     pass

        family_name, given_name = extract_given_and_family_name(
            relationship["Contact A"],
        )

        person_exists = Person.objects.filter(
            given_name=given_name,
            family_name=family_name,
        ).exists()

        if person_exists:
            person = Person.objects.get(
                given_name=given_name,
                family_name=family_name,
            )
        else:
            person = Person(
                given_name=given_name,
                family_name=family_name,
            )

            # Get the only instance of Person Index Page
            person_index_page = PersonIndexPage.objects.get()

            # Add person to site page hiererchy
            person_index_page.add_child(instance=person)
            person_index_page.save()

        meeting_presiding_clerk = MeetingPresidingClerk(
            meeting=meeting,
            person=person,
        )

        meeting_presiding_clerk.save()


nums = [10, 15, 3, 7, 9, 16]

def nums_that_equal(num, k):
    if [True for i in num for j in num if i + j == k]:
        return True
    else:
        return False

test_k = [5, 8, 9, 12, 50, 20, 25]

for test_num in test_k:
    value = nums_that_equal(nums, test_num)
    print(f"k = {test_num} and test is {value}")


out_base_folder = "/home/dany/Dropbox/Projects/deskydoo/desky/deskydoo/fe/articles";

# Languages for text, must be set up in format ("ISO2CODE", "FULL")
LAN_LIST = [
	# ('it','italian'),
	('en','english'),
	('es','spanish'),
]

# *************************
# TEXT GENERATION -- Chose between: (as 202310, the 3.5 works better to me)
# chatgpt_api8					https://rapidapi.com/haxednet/api/chatgpt-api8/								chatgpt 3.5
# chatgpt_gpt4_ai_chatbot		https://rapidapi.com/nextbaseapp/api/chatgpt-gpt4-ai-chatbot				chatgpt 4
TEXT_GEN = 'chatgpt_api8'

# *************************
# IMAGE GENERATION -- Choose between (as 202310, the api5 is the best to me)
# text_to_image7 				https://rapidapi.com/haxednet/api/text-to-image7
# midjourney_api5 				https://rapidapi.com/yourdevmail/api/midjourney-api5
# midjourney_best_experience 	https://rapidapi.com/liuzhaolong765481/api/midjourney-best-experience
IMAGE_GEN = 'text_to_image7'


import requests
from flask import render_template, Flask, request, url_for
from flask_bootstrap import Bootstrap
from flask_wtf import FlaskForm

from werkzeug.utils import redirect
from wtforms import StringField, SelectField, SubmitField
from wtforms.validators import DataRequired, URL

from cafeApiManager import ApiManager

app = Flask(__name__)

# Connect to Database
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///cafes.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SECRET_KEY'] = '8BYkEfBA6O6donzWlSihBXox7C0sKR6b'
Bootstrap(app)

class CafeForm(FlaskForm):
    cafe_name = StringField('Cafe name', validators=[DataRequired()])
    location = StringField('Cafe city location ', validators=[DataRequired()])
    country = StringField('Cafe country location ', validators=[DataRequired()])
    map_url = StringField('Cafe map link', validators=[DataRequired(), URL(message='Must be a valid URL')])
    img_url = StringField('Cafe image link', validators=[DataRequired(), URL(message='Must be a valid URL')])
    seats = StringField('Cafe number of seats e.g. +20', validators=[DataRequired()])
    has_toilet = SelectField("has toilet", choices=["true", "false"], validators=[DataRequired()])
    has_wifi = SelectField("has wifi", choices=["true", "false"], validators=[DataRequired()])
    has_sockets = SelectField("has sockets", choices=["true", "false"], validators=[DataRequired()])
    can_take_calls = SelectField("can take calls", choices=["true", "false"], validators=[DataRequired()])
    coffee_price = StringField('coffee price e.g. 7$', validators=[DataRequired()])
    open = StringField("Opening Time e.g. 8AM", validators=[DataRequired()])
    close = StringField("Closing Time e.g. 5:30PM", validators=[DataRequired()])
    coffee_rating = SelectField("Coffee Rating",
                                choices=["☕", "☕☕", "☕☕☕", "☕☕☕☕", "☕☕☕☕☕"],
                                validators=[DataRequired()])
    wifi_rating = SelectField("Wifi Strength Rating",
                              choices=["✘", "💪", "💪💪", "💪💪💪", "💪💪💪💪", "💪💪💪💪💪"],
                              validators=[DataRequired()])
    power_rating = SelectField("Power Socket Availability",
                               choices=["✘", "🔌", "🔌🔌", "🔌🔌🔌", "🔌🔌🔌🔌", "🔌🔌🔌🔌🔌"],
                               validators=[DataRequired()])

    submit = SubmitField('Submit')

@app.route("/", methods=["GET", "POST"])
def home():
    api_manager = ApiManager()
    all_data = api_manager.get_all()
    country_unique_vals = []
    for item in all_data["cafes"]:
        country_unique_vals.append(item["country"])
    country_unique_set = list(set(country_unique_vals))
    if request.method == 'POST':
        response = request.form.to_dict()
        if response:
            if len(response) == 1 and response["country"] == 'All':
                return render_template("index.html", cafees=all_data["cafes"], countries=country_unique_set)
            if response["country"] == 'All':
                response.pop("country")
            for k, v in response.items():
                if k != "country":
                    response[k] = 1
            filtered_data = api_manager.get_filtered_data(response)
            return render_template("index.html", cafees=filtered_data["cafes"], countries=country_unique_set)
    return render_template("index.html", cafees=all_data["cafes"], countries=country_unique_set)

@app.route("/cafe", methods=["GET", "POST"])
def cafe():
    cafe_id = request.args.get("id")
    api_manager = ApiManager()
    cafe_data = api_manager.get_cafe_by_id(cafe_id)
    full_map_link = unshorten_url(cafe_data["cafe"]["map_url"])
    name_location_map = full_map_link.split("/")[5:7]
    try:
        loc_xy = name_location_map[1].split(",")[:2]
        name_location_map[1] = f"{loc_xy[0]},{loc_xy[1]}"
    except IndexError:
        pass
    cafe_data["cafe"]["name_location_map"] = name_location_map
    if cafe_data:
        return render_template("cafe.html", cafe=cafe_data["cafe"])

@app.route("/add_cafe", methods=["GET", "POST"])
def add_cafe():
    form = CafeForm()
    api_manager = ApiManager()
    if form.validate_on_submit():
        response = api_manager.add_cafe(name=form.cafe_name.data,
                                        map_url=form.map_url.data,
                                        img_url=form.img_url.data,
                                        loc=form.location.data,
                                        country=form.country.data,
                                        sockets=form.has_sockets.data,
                                        toilet=form.has_toilet.data,
                                        wifi=form.has_wifi.data,
                                        calls=form.can_take_calls.data,
                                        seats=form.seats.data,
                                        coffee_price=form.coffee_price.data)

        return render_template("add_cafe.html", form=form, api_response=response)
    return render_template("add_cafe.html", form=form)

def unshorten_url(url):
    req = requests.head(url, allow_redirects=True).url
    return requests.head(req, allow_redirects=True).url

if __name__ == '__main__':
    app.run(debug=True)


import requests

from utility.conversions import number_to_ranks

class LobbySetup:
    '''
    Retrieve lobby details. Must be in game.
    '''

    def __init__(self, headers):
        self.headers = headers

    def get_latest_season_id(self, region):
        try:
            response = requests.get(
                f"https://shared.{region}.a.pvp.net/content-service/v3/content", headers=self.headers, verify=False)
            content = response.json()
            for season in content["Seasons"]:
                if season["IsActive"]:
                    return season["ID"]
        except:
            return -1

    def get_matchmaking_history(self, region, puuid) -> list:
        '''
        Returns last 10 comp matches
        '''
        try:
            response = requests.get(
                f"https://pd.{region}.a.pvp.net/match-history/v1/history/{puuid}?queue=competitive", headers=self.headers, verify=False
            )

            content = response.json()
            match_list:list = []
            for match in content["History"]:
                match_list.append(match)
            return match_list
        except:
            return -1

    def get_match_id(self, region, puuid) -> str:
        '''
        Get match ID of current match.
        '''
        try:
            response = requests.get(
                f"https://glz-{region}-1.{region}.a.pvp.net/core-game/v1/players/{puuid}", headers=self.headers, verify=False)
            content = response.json()
            match_id: str = content["MatchID"]
            return match_id
        except:
            return -1

    def get_ongoing_match(self, region, match_id):
        '''
        Get ongoing match details
        '''
        try:
            response = requests.get(
                f"https://glz-{region}-1.{region}.a.pvp.net/core-game/v1/matches/{match_id}", headers=self.headers, verify=False)
            content = response.json()
            players = content["Players"]
            # Get all PUUIDs in lobby
            player_dict = {"puuid": [], "agent": [], "team": [], "incognito": bool}
            for player in players:
                # Do not look up streamer mode players.
                if player["PlayerIdentity"]["Incognito"] == False:
                    player_dict["incognito"].append(False)
                    player_dict["puuid"].append(player["Subject"])
                    player_dict["agent"].append(player["CharacterID"])
                    player_dict["team"].append(player["TeamID"])
                else:
                    player_dict["incognito"].append(True)
                    player_dict["agent"].append(player["CharacterID"])
                    player_dict["team"].append(player["TeamID"])

            map = str(content["MapID"]).rsplit("/", 1)[1]
            if content["ProvisioningFlow"] == "CustomGame":
                game_mode_in_ongoing_match = "Custom".upper()
            else:
                game_mode_in_ongoing_match = str(
                    content["MatchmakingData"]["QueueID"]).upper()
            return player_dict, map, game_mode_in_ongoing_match

        except:
            print('Error retrieving ongoing match.')
            return -1

    def get_player_mmr(self, region, player_id, seasonId):
        response = requests.get(
            f"https://pd.{region}.a.pvp.net/mmr/v1/players/{player_id}", headers=self.headers, verify=False)
        keys = ['CurrentRank', 'RankRating', 'Leaderboard']
        try:
            if response.ok:
                r = response.json()
                if r["QueueSkills"]["competitive"]["SeasonalInfoBySeasonID"][seasonId] or r["QueueSkills"]["competitive"]["SeasonalInfoBySeasonID"][seasonId]["NumberOfWinsWithPlacements"] != 0:
                    numberOfWins = r["QueueSkills"]["competitive"]["SeasonalInfoBySeasonID"][seasonId]["NumberOfWinsWithPlacements"]
                    numberOfGames = r["QueueSkills"]["competitive"]["SeasonalInfoBySeasonID"][seasonId]["NumberOfGames"]
                    winPercent = round(int(numberOfWins) /
                                       int(numberOfGames), 3) * 100
                else:
                    winPercent = 0
                rankTIER = r["QueueSkills"]["competitive"]["SeasonalInfoBySeasonID"][seasonId]["CompetitiveTier"]
                if int(rankTIER) >= 24:
                    rank = [rankTIER,
                            r["QueueSkills"]["competitive"]["SeasonalInfoBySeasonID"][seasonId]["RankedRating"],
                            r["QueueSkills"]["competitive"]["SeasonalInfoBySeasonID"][seasonId]["LeaderboardRank"],
                            ]
                elif int(rankTIER) not in (0, 1, 2):
                    rank = [rankTIER,
                            r["QueueSkills"]["competitive"]["SeasonalInfoBySeasonID"][seasonId]["RankedRating"],
                            'N/A',
                            ]
                else:
                    rank = [0, 0, 'N/A']
            else:
                print("Failed retrieving rank.")
                rank = [0, 0, 'N/A']
                winPercent = 0
        except TypeError:
            rank = [0, 0, 'N/A']
            winPercent = 0
        except KeyError:
            rank = [0, 0, 'N/A']
            winPercent = 0

        # Convert tier to rank name.
        rank[0] = number_to_ranks[rank[0]]
        return dict(zip(keys, rank)), winPercent


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Apr 10 17:43:35 2019

@author: stef

This script is to analyse and produce some summary statistics for (a subset of)
all the NOS dictionaries extracted using the function scrape_nos.py.
Which dictionaries to analyse can be set using the ``which_files'' list.

"""

import os
import pickle
from collections import defaultdict
#import copy
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

####### Definitions
def unique(list1):
    '''
    # this functions takes a list of reference numbers for NOS and returns a list
    '''
    # without repetitions and a list with the repeated ref. numbers.
    # intilize a null list
    unique_list = []
    repeated_elems = []
    repeated_indices = []
    # traverse for all elements
    for ix, x in enumerate(list1):
        # check if exists in unique_list or not
        if x not in unique_list:
            # this list contains all unique refs, including the ones that are repeated
            unique_list.append(x)
        else:
            if x not in repeated_elems:
                repeated_elems.append(x)
                # get where the repeated indices are to then get the file names
                tmp = [i for i,y in enumerate(list1) if y==x]
                repeated_indices.append(tmp)
    repeated_counts = np.zeros(len(repeated_elems))
    for ii,x in enumerate(repeated_elems):
        repeated_counts[ii]= len([jj for jj in list1 if jj == x])
    return unique_list, repeated_elems, repeated_counts, repeated_indices

######## Main code

data_dir = '../../results/NOS/extracted'
summary_dir = '../../results/NOS/summary'
#set which NOS dictionaries to analyse
which_files = ['extracted_standards_New NOS 1.pickle', 'extracted_standards_New NOS 2.pickle']
for ii in range(1,23):
    which_files.append('extracted_standards_Old NOS {}.pickle'.format(ii))
#which_file = 'extracted_standards_Old NOS 22.pickle'

# Write the whole summary to file if WRITEFILE is True
version_load = 'new_' #'v2_'
WRITEFILE = True
if WRITEFILE:
    fsave  =open(os.path.join(summary_dir, version_load + 'summary1.txt'), 'w')

dict_len = []
sections_list = []
sections_count = {}

total_doc_extracted = 0
total_doc_failed = 0
total_doc_unique = 0

# collect all standards that failed, the repeated ones and those with missing urn
all_standard_failed = []
all_repeated_ref = []
all_repeated_counts = np.zeros(0)
all_repeated_files = defaultdict()
all_urnmissing_files = []
all_urnmissing_names = []

texts = []
for which_file in which_files:
    texts.append('Working on: ' + which_file + '\n')

    # load the file
    # choose the prefix of the version to load
    #version_load = 'new_' #'v2_'
    with open(os.path.join(data_dir, version_load + which_file),'rb') as f:
        standard_info, standard_ref, standard_failed, standard_files = pickle.load(f)

    # OBS1: Some standard refs are the same!
    # Get the unique and repeated ones
    unique_ref, repeated_ref, repeated_counts, repeated_indices = unique(standard_ref)
    all_repeated_ref += repeated_ref
    all_repeated_counts = np.concatenate((all_repeated_counts, repeated_counts))
    for irep, rep in enumerate(repeated_ref):
        all_repeated_files[rep] = {}
        for iind1,iind2 in enumerate(repeated_indices[irep]):
            all_repeated_files[rep]['file{}'.format(iind1+1)] = which_file[
                    20:30].replace('.','') + '/' + standard_files[iind2]
    total_doc_unique += len(unique_ref)

    # for all the repeated urns also collect the NOS name and the file name (?)

    # total number of files in this folder:
    Ntot = len(standard_failed)+len(standard_ref)
    Nfailed = len(standard_failed)

    all_standard_failed+= standard_failed
    total_doc_extracted += len(standard_ref)
    total_doc_failed += len(standard_failed)
    # print number of actually failed extractions
    texts.append('Correct extractions: {:4f}% \n'.format(len(standard_info)/Ntot*100))
    texts.append('That is, {} files over {} failed the extraction\n'.format(Nfailed, Ntot))

    #%%
    # Collect some info on the extracted dictionaries
    for idct, key_dct in enumerate(standard_info):
        dct = standard_info[key_dct]
        dict_len.append(len(dct))
        for key_sec in dct:
            if key_sec in sections_list:
                sections_count[key_sec] += 1
            else:
                sections_list.append(key_sec)
                sections_count[key_sec] = 1
            # if the section notes is present, get the filename because this was
            # a standard with missing URN (had the string '[URN]' instead)
            if key_sec == 'notes':
                all_urnmissing_files.append(which_file[20:30].replace(
                        '.','') + '/' + standard_files[idct])
                all_urnmissing_names.append(dct['Title'])

    texts.append('-'*60)

texts.append('Total numbers of extracted and failed files are {} and {}, respectively'.format(
        total_doc_extracted, total_doc_failed))

# now something about duplicates NOS
texts.append('Total numbers of unique and repeated URNs are {} and {}, respectively'.format(
        total_doc_unique - len(all_repeated_ref), len(all_repeated_ref)))

texts.append('Average number of repetitions for non-unique RNs is {}'.format(
        all_repeated_counts.mean()))
if all_repeated_counts.std()>0:
    high_rep_ref = np.where(all_repeated_counts>2)[0]
    texts.append('The number of RNs repeated more than two times is {}'.format(
            len(high_rep_ref)))
    texts.append('And these standards are: \n')
    for ii in high_rep_ref:
        texts.append(all_repeated_ref[ii])

# ADD example of extracted standard
texts.append('#'*80 + '\n')
texts.append('Example of extracted standard \n')

for key in dct:
    texts.append('\n Section name: {}. '.format(key))
    texts.append('Section content:')
    if isinstance(dct[key],list):
        for elem in dct[key]:
            texts.append(elem)
    else:
        texts.append(dct[key])

# finally, print a list of all failed NOS
# save everything on file and possibly print on screen too
if WRITEFILE:
    for text in texts:
        #print(text)
        fsave.write(text + '\n')

#plot histograms with count of section appearances across document
# (as a proportion of documents)
section_props = np.zeros((len(sections_count.keys())))
for ii,ikey in enumerate(sections_count):
    section_props[ii] = sections_count[ikey]/total_doc_extracted*100
    x = np.arange(ii+1) # this is a lazy and inefficient trick, yes

# sort them in descending order
IX = np.argsort(section_props)[::-1]
section_props = section_props[IX]
ticks = list(sections_count.keys())
ticks= [ticks[ii] for ii in IX]
fig, ax = plt.subplots(figsize = (8,4))
plt.bar(x, section_props)
plt.xticks(x, ticks, rotation = 'vertical')
plt.ylabel('% of NOS')
plt.xlabel('section')
plt.tight_layout()
plt.savefig(os.path.join(summary_dir, version_load + 'sections_counts.png'))
#plt.show()

# print the numbers too:
if WRITEFILE:
    fsave.write('\n')
    fsave.write('#'*80 + '\n')
    fsave.write('Counting how many times each section (i.e. performance criteria or glossary) appears in all the extracted NOS\n')
    fsave.write('\n')
    for ii,perc in enumerate(section_props):
        fsave.write('Section \'{}\' was extracted for {:.4f}% of the documents'.format(ticks[ii],perc))
        fsave.write('\n')

    fsave.write('\n')
    fsave.write('NOTE: The percentage of NOS with a \'note\' field (added during the \n'
                + 'extraction process) corresponds to those NOS that had \'[URN]\' \n'
            + 'or \'[Unique Reference Number]\' in the header instead of a proper \n' +
            'reference number. For these files I used the original URN field as their \n'
            + 'reference number.')
    fsave.write('\n')
    fsave.write('\n')

    fsave.write('#'*80 + '\n')
    fsave.write('All the standards that failed are: \n')
    for ifile in all_standard_failed:
        fsave.write(ifile)
        fsave.write('\n')

    fsave.close()

    # save the dictionary with the repeated URNs
    pd.DataFrame.from_dict(all_repeated_files, orient = 'index').to_csv(
            summary_dir + '/' + version_load + 'repeated_NOS.csv')

    # save the dictionary of files with missing URNs in their header
    #pd.DataFrame(all_urnmissing_files).to_csv(summary_dir + '/missing_urn_NOS.csv')
    pd.DataFrame({'filename of missing URN': all_urnmissing_files,
                  'standard name': all_urnmissing_names}).to_csv(
                        summary_dir + '/' + version_load + 'missing_urn_NOS.csv')


from src.simulator import Simulator
from sys import argv

def main():

	woman = 500
	man = 500
	years = 20
	if len(argv) == 4:
		woman = int(argv[1])
		man = int(argv[2])
		years = int(argv[3])
	s = Simulator()
	s.build(woman, man, 12*years)
	collector = s.sim()

	if argv.count('graph'):
		from app import app
		app.data = collector
		app.run(host='0.0.0.0', port=8000, debug=False)

if __name__ == '__main__':
	main()


from setuptools import find_packages, setup

with open("README.md", encoding="utf8") as f:
    readme = f.read()

setup(
    name="jupyterhub-tmpauthenticator",
    version="1.0.0",
    description="JupyterHub authenticator that hands out temporary accounts for everyone",
    url="https://github.com/jupyterhub/tmpauthenticator",
    author="Project Jupyter Contributors",  # founded by Yuvi Panda
    author_email="jupyter@googlegroups.com",
    license="3 Clause BSD",
    long_description=readme,
    long_description_content_type="text/markdown",
    entry_points={
        # Thanks to this, user are able to do:
        #
        #     c.JupyterHub.authenticator_class = "tmp"
        #
        # ref: https://jupyterhub.readthedocs.io/en/4.0.0/reference/authenticators.html#registering-custom-authenticators-via-entry-points
        #
        "jupyterhub.authenticators": [
            "tmp = tmpauthenticator:TmpAuthenticator",
        ],
    },
    packages=find_packages(),
    python_requires=">=3.8",
    install_require={
        "jupyterhub>=2.3.0",
        "traitlets",
    },
    extras_require={
        "test": [
            "aiohttp",
            "pytest",
            "pytest-asyncio",
            "pytest-cov",
            "pytest-jupyterhub",
        ],
    },
)


import unittest
import training
from convertToYOLOcsv import convertToYOLO
import torch
import utils
from metrics import PredictionStats, AveragePrecision, TRUE_POSITIVE, FALSE_POSITIVE

class TestMethods(unittest.TestCase):

    def test_loss(self):
        outputs = torch.rand((64, 7*7*(5+4)))
        truth = torch.rand((64, 7*7*(5+4)))
        for i in range(64):
            for j in range(0, 7*7*(5+4), 9):
                truth[i, j] = 1
        training.no_of_classes = 4
        training.objects_in_grid = 1
        result = training.loss_calc(outputs, truth)
        # check that loss can't take very large values
        self.assertTrue(result.item() < 500)

    def test_iou(self):
        # no overlap
        bbox1 = (0.5, 0.5, 0.1, 0.1)
        bbox2 = (0.1, 0.1, 0.01, 0.01)
        expected_iou = 0
        actual_iou = utils.get_iou(bbox1, bbox2)
        self.assertEqual(expected_iou, actual_iou)

        # full overlap
        bbox1 = (0.5, 0.5, 0.1, 0.1)
        bbox2 = (0.5, 0.5, 0.1, 0.1)
        expected_iou = 1
        actual_iou = utils.get_iou(bbox1, bbox2)
        self.assertEqual(expected_iou, round(actual_iou))

        # partial overlap
        bbox1 = (0.5, 0.5, 0.2, 0.1)
        bbox2 = (0.4, 0.4, 0.2, 0.2)
        expected_iou = 0.2
        actual_iou = round(utils.get_iou(bbox1, bbox2), 1)
        self.assertEqual(expected_iou, actual_iou)

    def test_plot(self):
        # TODO Test plotting class
        pass

    def test_yolo_conversion(self):
        bbox_initial_points = [100, 100, 400, 100, 400, 400, 100, 400]
        bbox_yolo = convertToYOLO(bbox_initial_points)
        bbox_reverse_conversion = utils.conv_yolo_2_dota(bbox_yolo)
        self.assertEqual(bbox_reverse_conversion, bbox_initial_points)

    def test_average_precision(self):
        image_predictions = [
            PredictionStats(0.9, TRUE_POSITIVE),
            PredictionStats(0.8, FALSE_POSITIVE),
            PredictionStats(0.7, TRUE_POSITIVE),
            PredictionStats(0.6, FALSE_POSITIVE),
            PredictionStats(0.5, TRUE_POSITIVE),
            PredictionStats(0.3, FALSE_POSITIVE),
            PredictionStats(0.2, FALSE_POSITIVE)
        ]
        avg = AveragePrecision(image_predictions, 4)
        self.assertEqual(0.533, round(avg.get_average_precision(), 3))

        image_predictions[0] = PredictionStats(0.9, FALSE_POSITIVE)
        avg = AveragePrecision(image_predictions, 4)
        self.assertEqual(0.123, round(avg.get_average_precision(), 3))

    def test_detection_list(self):
        outputs = torch.zeros((49*9), dtype=torch.float16)
        outputs[0] = 0.78
        outputs[1] = 0.7
        outputs[2] = 0.5
        outputs[3] = 0.5
        outputs[4] = 0.6
        outputs[5] = 0.1
        outputs[6] = 0.6
        outputs[7] = 0.2
        outputs[8] = 0.1

        truth = torch.zeros((49 * 9), dtype=torch.float16)
        truth[0] = 1
        truth[1] = 0.7
        truth[2] = 0.5
        truth[3] = 0.6
        truth[4] = 0.5
        truth[5] = 0
        truth[6] = 1
        truth[7] = 0
        truth[8] = 0

        iou = utils.get_iou_new(utils.convert_to_yolo_full_scale(torch.tensor([0.7, 0.5, 0.5, 0.6]), 0),
                                utils.convert_to_yolo_full_scale(torch.tensor([0.7, 0.5, 0.6, 0.5]), 0))
        self.assertTrue(iou > 0.5)

        utils.FinalPredictions(outputs, truth)

        outputs = torch.zeros((49*9), dtype=torch.float16)
        outputs[0] = 0.67
        outputs[1] = 0.1
        outputs[2] = 0.5
        outputs[3] = 0.05
        outputs[4] = 0.06
        outputs[5] = 0.1
        outputs[6] = 0.6
        outputs[7] = 0.2
        outputs[8] = 0.1

        truth = torch.zeros((49 * 9), dtype=torch.float16)
        truth[0] = 1
        truth[1] = 0.9
        truth[2] = 0.5
        truth[3] = 0.06
        truth[4] = 0.05
        truth[5] = 0
        truth[6] = 1
        truth[7] = 0
        truth[8] = 0

        iou = utils.get_iou_new(utils.convert_to_yolo_full_scale(torch.tensor([0.1, 0.5, 0.05, 0.06]), 0),
                                utils.convert_to_yolo_full_scale(torch.tensor([0.9, 0.5, 0.06, 0.05]), 0))
        self.assertTrue(iou < 0.5)

        utils.FinalPredictions(outputs, truth)

        self.assertTrue(
            utils.all_detections['ship'][0].get_confusion() == utils.TRUE_POSITIVE and
            utils.all_detections['ship'][1].get_confusion() == utils.FALSE_POSITIVE and
            utils.positives['ship'] == 2
        )

        ap = AveragePrecision(utils.all_detections['ship'], utils.positives['ship'])
        self.assertTrue(ap.get_average_precision() == 0.5)

    def test_crop_img(self):
        dic = utils.crop_img('/home/campus/Desktop/avioane.jpg', 448)
        self.assertEqual(36, len(dic.keys()))


import requests
import os
url = 'http://ubmcmm.baidustatic.com/media/v1/0f000ZjaV0Hbb1uWirPKsf.jpg'
root = 'D://pics//'
path = root + url.split('/')[-1]#保留原来文件名

try:
    if not os.path.exists(root):
        os.mkdir(root)
    if not os.path.exists(path):
        r = requests.get(url)
        with open(path,'wb') as f:
            f.write(r.content)
            print('success')
    else:
        print('It already exists')
except:
    print('fail')


from canvasapi import Canvas

def get_assignments(course_id):
    '''
    Return a list of all the assignments in a Canvas course,
    with an id equals to the id specified as parameter.
    '''
    url = 'https://canvas.instructure.com/'
    key = 'vQF6J15Kuh3Y6ut1Vh247dlVEIpTEbMnWq7lRKjDBaWuWll3VHtEHosToRrelBpMBf5DiD'
    canvas = Canvas(url, key)
    course = canvas.get_course(course_id)
    return [x for x in course.get_assignments()]

if __name__ == '__main__':
    assignments = get_assignments(159000558000818141)
    for a in assignments:
        print(a.name, a.points_possible)


"""Tutor shared region nav bar."""

import re
from time import sleep

from pypom import Region
from selenium.common.exceptions import WebDriverException
from selenium.webdriver.common.by import By

from utils.tutor import TutorException
from utils.utilities import Utility, go_to_, go_to_external_

class Menu(Region):
    """A Tutor nav bar menu."""

    _toggle_locator = (By.CSS_SELECTOR, 'button')

    def toggle(self):
        """Open or close a nav menu."""
        Utility.scroll_top(self.driver)
        menu = self.find_element(*self._toggle_locator)
        Utility.click_option(self.driver, element=menu)
        sleep(0.15)
        return self

    @property
    def is_open(self):
        """Return True if the menu is open."""
        return 'show' in self.root.get_attribute('class')

    def _select(self, locator, destination=None, external=False, file=False):
        """Select a menu option."""
        # Open the menu if it isn't already
        if not self.is_open:
            self.toggle()
        target = self.find_element(*locator)
        url = target.get_attribute('href')
        if external:
            # Go to the external site and wait for load;
            # pass the destination URL in case the external
            # site fails to load
            Utility.switch_to(self.driver, element=target)
            if file:
                # The target is a file for download so skip
                # the wait for page load
                return
            return go_to_external_(destination(self.driver), url)
        # Go to the internal site and wait for load; pass
        # the Page base URL (attached to the Page, not the
        # parent Region) so Page.open() can work
        Utility.click_option(self.driver, element=target)
        if destination:
            return go_to_(destination(self.driver, self.page.page.base_url))

class TutorNav(Region):
    """Tutor nav bar region for logged in users."""

    _root_locator = (By.CSS_SELECTOR, '.tutor-navbar')

    # Main buttons on the nav
    _openstax_logo_locator = (By.CSS_SELECTOR, '.ui-brand-logo')
    _help_menu_locator = (By.CSS_SELECTOR, '.support-menu')
    _student_payment_locator = (By.CSS_SELECTOR, '.student-pay-now')
    _action_menu_locator = (By.CSS_SELECTOR, '.actions-menu')
    _account_menu_locator = (By.CSS_SELECTOR, '.user-menu')

    @property
    def logo(self):
        """Return the OpenStax Tutor Beta logo."""
        return self.find_element(*self._openstax_logo_locator)

    def go_to_dashboard(self):
        """Click on the OpenStax Tutor Beta logo."""
        Utility.click_option(self.driver, element=self.logo)
        sleep(0.5)
        if 'dashboard' in self.driver.current_url:
            # The user has multiple courses and ends up at
            # the course picker page
            from pages.tutor.dashboard import Dashboard
            return go_to_(Dashboard(self.driver, self.page.base_url))
        # The student has a single course and ends up on
        # their This Week course view
        from pages.tutor.course import Course
        return go_to_(Course(self.driver, self.page.base_url))

    @property
    def help(self):
        """Access the 'Help' menu."""
        root = self.find_element(*self._help_dropdown_locator)
        return self.Help(self, root)

    @property
    def student_access(self):
        """Access the student payment information."""
        try:
            root = self.find_element(*self._student_payment_locator)
            return self.Payment(self, root)
        except WebDriverException:
            raise TutorException('No active trial')

    @property
    def menu(self):
        """Access the action menu."""
        root = self.find_element(*self._action_menu_locator)
        return self.Action(self, root)

    @property
    def user(self):
        """Access the user menu."""
        root = self.find_element(*self._account_menu_locator)
        return self.User(self, root)

    class Help(Menu):
        """The Help options."""

        _page_tips_locator = (
            By.CSS_SELECTOR, '.page-tips')
        _help_articles_locator = (
            By.CSS_SELECTOR, '.-help-link:first-child')
        _getting_started_locator = (
            By.CSS_SELECTOR, '.support-document-link')
        _best_practices_locator = (
            By.CSS_SELECTOR, '.best-practices-guide')
        _accessibility_statement_locator = (
            By.CSS_SELECTOR, '[href*=accessibility]')
        _chat_support_enabled_locator = (
            By.CSS_SELECTOR, '.chat.enabled')
        _chat_support_disabled_locator = (
            By.CSS_SELECTOR, '.chat.disabled span')

        def view_page_tips(self):
            """Trigger the current page's user tips."""
            self._select(locator=self._page_tips_locator)
            return self.page.page.page_tips()

        def view_help_articles(self):
            """Select the Help Articles menu option."""
            from pages.salesforce.home import Salesforce
            return self._select(locator=self._page_tips_locator,
                                destination=Salesforce,
                                external=True)

        @property
        def guide_url(self):
            """Return the Getting Started guide URL."""
            return (self.find_element(*self._getting_started_locator)
                    .get_attribute('href'))

        def view_getting_started_guide(self):
            """Download the Getting Started guide."""
            return self._select(locator=self._getting_started_locator,
                                external=True,
                                file=True)

        def verify_getting_started_guide(self, user_type='student'):
            """Test the guide URL."""
            url = self.guide_url
            filename = url.split('/')[-1]
            assert(user_type in filename), (
                'Wrong user guide (expected {user} to be in {filename})'
                .format(user=user_type, filename=filename))
            return Utility.test_url_and_warn(url=url,
                                             message='Getting Started guide',
                                             driver=self.driver)

        @property
        def best_practices_url(self):
            """Return the Best Practices guide URL."""
            return (self.find_element(*self._best_practices_locator)
                    .get_attribute('href'))

        def view_best_practices_guide(self):
            """Download the Best Practices guide."""
            return self._select(locator=self._best_practices_locator,
                                external=True,
                                file=True)

        def verify_best_practices_guide(self):
            """Test the guide URL."""
            return Utility.test_url_and_warn(url=self.best_practices_url,
                                             message='Best Practices guide',
                                             driver=self.driver)

        def view_accessibility_statement(self):
            """View the Accessibility Statement."""
            from pages.tutor.accessibility import Accessibility
            return self._select(locator=self._accessibility_statement_locator,
                                destination=Accessibility)

        @property
        def chat_available(self):
            """Return True if the customer support chat is available."""
            chat_enabled = self.find_element(
                *self._chat_support_enabled_locator)
            return self.driver.execute_script(
                'return arguments[0].style.display != "none";', chat_enabled)

        @property
        def chat_unavailable(self):
            """Return the chat offline message."""
            if not self.chat_available:
                return (self.find_element(*self._chat_support_disabled_locator)
                        .text)
            raise TutorException('Chat is currently available')

        def chat_with_support(self):
            """Begin a customer support chat session."""
            if self.chat_available:
                from pages.tutor.chat import Chat
                self._select(locator=self._chat_support_enabled_locator,
                             destination=Chat,
                             external=True)
            raise TutorException('Chat is not currently available')

    class Payment(Region):
        """Student trial and payment messaging."""

        _pay_now_locator = (By.CSS_SELECTOR, '.btn-primary')

        @property
        def status(self):
            """Return the trial status message."""
            return self.root.text

        @property
        def days_remaining(self):
            """Return the number of days remaining in the student trial."""
            status = self.status
            days = re.findall(r"\d+", status)
            assert(days), 'No number found ({0})'.format(status)
            return int(days[0])

        def pay_now(self):
            """Click the 'Pay now' button."""
            button = self.find_element(*self._pay_now_locator)
            Utility.click_option(self.driver, element=button)
            from regions.tutor.purchase import Purchase
            return Purchase(self.page.page)

    class Action(Menu):
        """User action options."""

        _my_courses_locator = (
            By.CSS_SELECTOR, '[data-item=myCourses]')
        _dashboard_locator = (
            By.CSS_SELECTOR, '[data-item=dashboard]')
        _browse_the_book_locator = (
            By.CSS_SELECTOR, '[name=browseBook]')
        _scores_locator = (
            By.CSS_SELECTOR, '[data-item=viewScores]')
        _performance_forecast_locator = (
            By.CSS_SELECTOR, '[data-item=viewPerformanceGuide]')
        _change_student_id_locator = (
            By.CSS_SELECTOR, 'data-item=changeStudentId]')
        _question_library_locator = (
            By.CSS_SELECTOR, '[data-item=viewQuestionsLibrary]')
        _course_settings_locator = (
            By.CSS_SELECTOR, '[data-item=courseSettings]')
        _course_roster_locator = (
            By.CSS_SELECTOR, '[data-item=courseRoster]')
        _create_a_course_locator = (
            By.CSS_SELECTOR, '[data-item=createNewCourse]')
        _copy_this_course_locator = (
            By.CSS_SELECTOR, '[data-item=cloneCourse]')
        _manage_payments_locator = (
            By.CSS_SELECTOR, '[data-item=managePayments]')
        _customer_service_locator = (
            By.CSS_SELECTOR, '[data-item=customer_service]')
        _admin_console_locator = (
            By.CSS_SELECTOR, '[data-item=admin]')
        _qa_dashboard_locator = (
            By.CSS_SELECTOR, '[data-item=QADashboard]')
        _content_analyst_locator = (
            By.CSS_SELECTOR, '[data-item=qaHome]')

        def view_my_courses(self):
            """Go to My Courses.

            See TutorNav.go_to_dashboard()
            Most users will be taken to the course picker.
            Students with one course will be taken to their course page.
            """
            self._select(locator=self._my_courses_locator)
            sleep(0.5)
            if 'dashboard' in self.driver.current_url:
                from pages.tutor.dashboard import Dashboard
                return go_to_(Dashboard(self.driver, self.page.page.base_url))
            from pages.tutor.course import Course
            return go_to_(Course(self.driver, self.page.page.base_url))

        def view_dashboard(self):
            """Go to the Dashboard.

            Instructors will be taken to the calendar.
            Students will be taken to their course page.
            """
            self._select(locator=self._dashboard_locator)
            sleep(0.5)
            if 'month' in self.driver.current_url:
                from pages.tutor.course import Calendar as Course
            else:
                from pages.tutor.course import Course
            return go_to_(Course(self.driver, self.page.page.base_url))

        def browse_the_book(self):
            """Open the book's reference view."""
            from pages.tutor.reference import Reference
            return self._select(locator=self._browse_the_book_locator,
                                destination=Reference,
                                external=True)

        def view_student_scores(self):
            """View the scores table."""
            from pages.tutor.scores import Scores
            return self._select(locator=self._scores_locator,
                                destination=Scores)

        def view_the_performance_forecast(self):
            """View the performance forecast."""
            from pages.tutor.performance import PerformanceForecast
            return self._select(locator=self._performance_forecast_locator,
                                destination=PerformanceForecast)

        def change_student_id(self):
            """Go to the ID change page."""
            from pages.tutor.student_id import ChangeID
            return self._select(locator=self._change_student_id_locator,
                                destination=ChangeID)

        def view_the_question_library(self):
            """Go to the ."""
            from pages.tutor.question_library import QuestionLibrary
            return self._select(locator=self._question_library_locator,
                                destination=QuestionLibrary)

        def view_the_course_settings(self):
            """Go to the course settings."""
            from pages.tutor.settings import CourseSettings
            return self._select(locator=self._course_settings_locator,
                                destination=CourseSettings)

        def view_the_course_roster(self):
            """Go to the course roster."""
            from pages.tutor.roster import CourseRoster
            return self._select(locator=self._course_roster_locator,
                                destination=CourseRoster)

        def create_a_course(self):
            """Go to course creation."""
            from pages.tutor.course_creation import CreateCourse
            return self._select(locator=self._create_a_course_locator,
                                destination=CreateCourse)

        def copy_this_course(self):
            """Clone the current course."""
            from pages.tutor.course_creation import CloneCourse
            return self._select(locator=self.self._create_a_course_locator,
                                destination=CloneCourse)

        def manage_payments(self):
            """Manage payments."""
            from pages.tutor.payments import PaymentManagement
            return self._select(locator=self._manage_payments_locator,
                                destination=PaymentManagement)

        def view_the_customer_service_board(self):
            """Open the customer service console."""
            from pages.tutor.admin import CustomerService
            return self._select(locator=self._customer_service_locator,
                                destination=CustomerService)

        def view_the_admin_console(self):
            """Go to the administrator's console."""
            from pages.tutor.admin import AdminConsole
            return self._select(locator=self._admin_console_locator,
                                destination=AdminConsole)

        def view_the_qa_dashboard(self):
            """Go to the QA dashboard."""
            from pages.tutor.qa import QAConsole
            return self._select(locator=self._qa_dashboard_locator,
                                destination=QAConsole)

        def view_the_content_analyst_board(self):
            """Go to the content analyst console."""
            from pages.tutor.content import ContentAnalystConsole
            return self._select(locator=self._content_analyst_locator,
                                destination=ContentAnalystConsole)

    class User(Menu):
        """User account information."""

        _initials_locator = (By.CSS_SELECTOR, '.initials')
        _my_account_locator = (By.CSS_SELECTOR, '[href$=profile]')
        _log_out_locator = (By.CSS_SELECTOR, '.logout')

        @property
        def initials(self):
            """Return the user's initials displayed in the user menu dot.

            Initials are case sensitive matching Accounts.
            """
            return self.find_element(*self._initials_locator).text.strip()

        def view_my_account(self):
            """View the user's profile on Accounts."""
            from pages.accounts.profile import Profile
            return self._select(locator=self._my_account_locator,
                                destination=Profile,
                                external=True)

        def log_out(self):
            """Log the current user out of Tutor."""
            from pages.tutor.home import TutorHome
            return self._select(locator=self._log_out_locator,
                                destination=TutorHome)


import unittest
from xml.etree import ElementTree as ET
from xmlcomparer import transformer

import logging
#logging.basicConfig(level=logging.DEBUG)

class TestTransformer(unittest.TestCase):
    def test_can_ignore_order(self):
        xml_incorrect_order = ET.parse("../../demo/sort_only2.xml")
        t = transformer.Transformer(xml_incorrect_order)
        t.ignore_tag_order(".*")
        xml_incorrect_order_transformed = t.transform()
        xml_correct_order = ET.parse("../../demo/sort_only1.xml")

        print("--- correct")
        print(ET.tostring(xml_correct_order.getroot(), encoding="unicode"))
        print("--- incorrect")
        print(ET.tostring(xml_incorrect_order.getroot(), encoding="unicode"))
        print("--- transformed")
        print(ET.tostring(xml_incorrect_order_transformed.getroot(), encoding="unicode"))


# snail coordinate function
def snail_coordinate(num):
    # required numbers up to x and y
    req_num_up_x = num // 2
    req_num_up_y = (num-1) // 2
    # coordinate function
    def coord(n):
        # output
        coord = (((2*n)+1) * ((n%2)-((n-1)%2)) + 1) // 4
        # return
        return coord
    # output
    coord_x, coord_y = coord(req_num_up_x), coord(req_num_up_y)
    # return
    return coord_x, coord_y
# user input
usr_num = int(input())
# unpack
usr_coord_x, usr_coord_y = snail_coordinate(usr_num)
# print
print(usr_coord_x, usr_coord_y)


import pandas as pd
import json
import time
import os
import re
import random
import requests
from urllib import parse

class DuckSearch:

    def __init__(self, settings):
        self.domain = 'https://duckduckgo.com'
        self.language = settings.get('DDGlanguage', 'en-us')
        self.headers = {
            'User-Agent': settings.get('DDGuser-agent', ''),
            'Cache-Control': 'no-cache'
        }

    def search(self, searchItem):
        self.message = ''
        self.term = searchItem.get('term')
        self._blacklist = searchItem.get('blacklist', [])
        return self._processQuery(), self.message

    def _get_response(self):
        query = parse.quote(self.term)
        url = f'{self.domain}/local.js?q={query}&cb=DDG.duckbar.add_local&tg=maps_places&l={self.language}&sf=low'
        req =requests.get(url, headers=self.headers)
        m = re.search(r'DDG.duckbar.add_local\((.*)\)', req.text)
        if m:
            vqd = list(json.loads(m.group(1))['vqd'].values())[0]
            if vqd:
                url = f'{self.domain}/d.js?q={query}&t=D&l=wt-wt&s=0&a=hk&ss_mkt=us&vqd={vqd}&p_ent=&ex=-1&sp=0'
                time.sleep(random.uniform(1,3))
                self.response = requests.get(url, headers=self.headers).text
            else:
                self.response = ''
        else:
            self.response = ''
        time.sleep(6)

    def _parse_response(self):
        columns = ['date', 'seqno', 'query', 'title', 'snippet', 'url_se', 'pagemap']
        m = re.search(r"DDG\.pageLayout\.load\('d',(\[.*\])\)", self.response)
        if m:
            result = pd.DataFrame(json.loads(m.group(1)))[['u', 't', 'a']]
            if 'l' in result.columns:
                res0 = pd.DataFrame()
                for r in result.loc[result[['l']].any(axis=1), 'l']:
                    resnew = pd.DataFrame([{'u': x['targetUrl'], 't': x['text'], 'a': x['snippet']} for x in r])
                    res0 = pd.concat([res0, resnew])
                result = pd.concat([res0, result]).reset_index(drop=True)
            result.columns = ['url_se', 'title', 'snippet']
            result['seqno'] = result.index + 1
            result['date'] = time.strftime('%Y%m%d')
            result['query'] = self.term
            result['pagemap'] = '' # return this column because of compatibility with googlsearch.py
            return result[pd.notnull(result.url_se)][columns]
        else:
            self.message = 'Expected javascript file (d.js) not found.'
            return pd.DataFrame(columns=columns)

    def excludedSites(self):
        exclude = ' '.join(['-site:' + url for url in self._blacklist])
        return exclude

    def _processQuery(self):
        exclude = self.excludedSites()
        if exclude:
            self.term = self.term.replace(' ', '+') + ' ' + exclude
        self._get_response()
        return self._parse_response()