import tensorflow as tf
import os
import numpy as np
import logging
import io
import PIL.Image
import hashlib
import random

from object_detection.utils import dataset_util
import cv2 as cv
from utils.utils import read_config
from object_detection.dataset_tools import tf_record_creation_util
from object_detection.utils import label_map_util
import hashlib

config = read_config()
save_dir = config['TFRecord']['save_dir']
IMAGE_DIR = config['TFRecord']['IMAGE_DIR']
TF_REC_DIR = config['TFRecord']['TF_REC_DIR']
data_dir = config['TFRecord']['data_dir']

flags = tf.app.flags
flags.DEFINE_string('output_dir', TF_REC_DIR, 'Path to output TFRecord')
FLAGS = flags.FLAGS

def create_tf_example(data):
  img_path = os.path.join(IMAGE_DIR, data['filename'])
  with tf.gfile.GFile(img_path, 'rb') as fid:
    encoded_jpg = fid.read()
  encoded_jpg_io = io.BytesIO(encoded_jpg)

  image = PIL.Image.open(encoded_jpg_io)
  if image.format != 'JPEG':
    raise ValueError('Image format not JPEG')

  key = hashlib.sha256(encoded_jpg).hexdigest()

  width = int(data['size']['width'])
  height = int(data['size']['height'])

  xmins = []
  ymins = []
  xmaxs = []
  ymaxs = []
  classes = []
  classes_text = []

  if 'object' in data:
    for obj in data['object']:
      xmins.append(obj[0] / width)
      ymins.append(obj[1] / height)
      xmaxs.append(obj[2] / width)
      ymaxs.append(obj[3] / height)
      class_name = 'PCB'
      classes_text.append(class_name.encode('utf8'))
      classes.append(1)

  feature_dict = {
      'image/height': dataset_util.int64_feature(height),
      'image/width': dataset_util.int64_feature(width),
      'image/filename': dataset_util.bytes_feature(
          data['filename'].encode('utf8')),
      'image/source_id': dataset_util.bytes_feature(
          data['filename'].encode('utf8')),
      'image/key/sha256': dataset_util.bytes_feature(key.encode('utf8')),
      'image/encoded': dataset_util.bytes_feature(encoded_jpg),
      'image/format': dataset_util.bytes_feature('jpeg'.encode('utf8')),
      'image/object/bbox/xmin': dataset_util.float_list_feature(xmins),
      'image/object/bbox/xmax': dataset_util.float_list_feature(xmaxs),
      'image/object/bbox/ymin': dataset_util.float_list_feature(ymins),
      'image/object/bbox/ymax': dataset_util.float_list_feature(ymaxs),
      'image/object/class/text': dataset_util.bytes_list_feature(classes_text),
      'image/object/class/label': dataset_util.int64_list_feature(classes),
  }
  example = tf.train.Example(features=tf.train.Features(feature=feature_dict))
  return example

def main()->None:
    #writer = tf.python_io.TFRecordWriter(FLAGS.output_path)
  if not(os.path.exists(IMAGE_DIR)):
    os.mkdir(IMAGE_DIR)
  if not(os.path.exists(TF_REC_DIR)):
    os.mkdir(TF_REC_DIR)

  # TODO(user): Write code to read in your dataset to examples variable
  count=0
  examples = []
  for file in os.listdir(save_dir):
    example = {}
    file_path = (os.path.join(save_dir, file))
    data = np.load(file_path,allow_pickle=True)
    # print(data.keys())
    image = np.array(data['image'],dtype=np.float32)
    filename = (os.path.join(str(count)+'.jpg'))
    cv.imwrite(os.path.join(IMAGE_DIR,str(count)+'.jpg'),image*255)
    count+=1
    example['filename'] = filename
    example['size'] = {}
    example['size']['width'] = 512
    example['size']['height'] = 512
    example['object'] = data['boxes']
    examples.append(example)
      # tf_example = create_tf_example(example)
      # writer.write(tf_example.SerializeToString())

      # writer.close()
  image_dir = os.path.join(data_dir, 'images')
  annotations_dir = os.path.join(data_dir, 'annotations')
  examples_list = list(range(1,len(examples)))
  random.shuffle(examples_list)

  # Test images are not included in the downloaded data set, so we shall perform
  # our own split.

  num_examples = len(examples_list)
  num_train = int(0.9 * num_examples)
  train_examples = examples_list[:num_train]
  val_examples = examples_list[num_train:]
  logging.info('%d training and %d validation examples.',
               len(train_examples), len(val_examples))

  train_output_path = os.path.join(FLAGS.output_dir, 'pcb_train.record')
  val_output_path = os.path.join(FLAGS.output_dir, 'pcb_val.record')

  writer = tf.python_io.TFRecordWriter(train_output_path)
  for idx in train_examples:
      example = examples[idx]
      tf_example = create_tf_example(example)
      writer.write(tf_example.SerializeToString())

  writer.close()

  writer = tf.python_io.TFRecordWriter(val_output_path)
  for idx in val_examples:
      example = examples[idx]
      tf_example = create_tf_example(example)
      writer.write(tf_example.SerializeToString())

if __name__ == '__main__':
  tf.app.run()


from dataloader import preprocess
from sklearn.svm import SVR
from sklearn.model_selection import GridSearchCV
import torch.nn as nn
import torch
import numpy as np

def anomaly_score(z, x):
    """
    Compute the anomaly score of a given data point.
    :param logvar: the log variance of the data point.
    :param sigma: the standard deviation of the data point.
    :param x: the data point.
    :return: the anomaly score of the data point.
    """
    fc = nn.Softmax(dim=0)
    z = torch.Tensor(z).unsqueeze(1)
    x = torch.Tensor(x).unsqueeze(1)
    score = torch.abs(fc(z) - fc(x))
    score = preprocess(score)
    return score

def anomaly_detection(x,recon_x,score,SVR_predicter):
    #train a SVM to detect anomaly
    #return the anomaly score
    x = np.array(x).reshape(-1,1)
    recon_x = np.array(recon_x).reshape(-1,1)
    recon_x = preprocess(recon_x)
    print('=> using an SVR as anomaly score predictor')
    threshold = SVR_predicter.predict(recon_x).reshape(-1,1)
    results = []
    eps = np.linspace(-0.1,0.1,100)
    for epsilon in eps:
        thre = threshold + epsilon
        result = score>thre
        results.append(result)
    return results , threshold

def get_range_proba(predict, label, delay=100):
    splits = np.where(label[1:] != label[:-1])[0] + 1
    is_anomaly = label[0] == 1
    new_predict = np.array(predict)
    pos = 0

    for sp in splits:
        if is_anomaly:
            if 1 in predict[pos:min(pos + delay + 1, sp)]:
                new_predict[pos: sp] = 1
            else:
                new_predict[pos: sp] = 0
        is_anomaly = not is_anomaly
        pos = sp
    sp = len(label)

    if is_anomaly:  # anomaly in the end
        if 1 in predict[pos: min(pos + delay + 1, sp)]:
            new_predict[pos: sp] = 1
        else:
            new_predict[pos: sp] = 0

    return new_predict


import cv2
import numpy as np

"""
 Manual filter parameters defination
 Images on Notion
 Hue -> pure spectrum colors ("cores do arco-iris") being red, orange, yellow, blue, green and violet, it goes from 0 to 360 (or 0 to 179)
 Saturation -> Intensity of the color (0 to 100%, or 0 to 255)
 Value -> Brightness (0 to 100% or 0 to 255)
"""

lowerFilters = np.array([0, 0, 0]) # hue min, saturation min, value min
upperFilters = np.array([360, 255, 255])

def onChange(value): # On change function (not used here, but can be used)
    pass

cv2.namedWindow("Trackbars")
cv2.resizeWindow("Trackbars", 600, 300)
cv2.createTrackbar("Hue min", "Trackbars", 0, 360, onChange)
cv2.createTrackbar("Hue max", "Trackbars", 360, 360, onChange)
cv2.createTrackbar("Sat min", "Trackbars", 0, 255, onChange)
cv2.createTrackbar("Sat max", "Trackbars", 255, 255, onChange)
cv2.createTrackbar("Val min", "Trackbars", 0, 255, onChange)
cv2.createTrackbar("Val max", "Trackbars", 255, 255, onChange)

while True:
    img = cv2.imread("test-resources/eraser.png")

    img = cv2.resize(img, (300, 300)) # (width, height)

    # Getting only the (defined range) Color
    # We're going to use Trackbars (scroll bars), to set the minimum and maximum values of the blue color (optimizing it with trackbars)

    lowerFilters[0] = cv2.getTrackbarPos("Hue min", "Trackbars") # scroll name, window of trackbar name
    lowerFilters[1] = cv2.getTrackbarPos("Sat min", "Trackbars")
    lowerFilters[2] = cv2.getTrackbarPos("Val min", "Trackbars")
    upperFilters[0] = cv2.getTrackbarPos("Hue max", "Trackbars")
    upperFilters[1] = cv2.getTrackbarPos("Sat max", "Trackbars")
    upperFilters[2] = cv2.getTrackbarPos("Val max", "Trackbars")

    mask = cv2.inRange(img, lowerFilters, upperFilters) # Filter being applied (0 = Black, 1 = White, 1 to match the range defined)
    imgResults = cv2.bitwise_and(img, img, mask=mask) # Put the colors in the 1 (positive binaries) places

    cv2.imshow("Eraser Image", img)
    cv2.imshow("Mask", mask)
    cv2.imshow("Filter Image", imgResults)

    cv2.waitKey(1) # Delay

Basics/chapter 7 - Color Detection and Trackbars.py


import os
import shutil
from collections import namedtuple

from autohdl import PREDEFINED_DIRS, FILE_USER_CFG, IGNORE_REPO_DIRS
from autohdl import verilog
import logging

alog = logging.getLogger(__name__)

def generate(path=''):
    # create dir structure
    # copy config file
    # return printable tree structure
    root = os.path.abspath(path)
    if not os.path.exists(root):
        os.makedirs(root)
    alog.info('Design root: ' + root)
    for i in PREDEFINED_DIRS:
        path = os.path.join(root, i)
        if not os.path.exists(path):
            os.mkdir(path)
    autohdl_cfg = FILE_USER_CFG
    Copy = namedtuple('Copy', ['src', 'dst'])
    list_to_copy = (
        Copy(autohdl_cfg, os.path.join(root, 'script', 'kungfu.py')),
    )
    for i in list_to_copy:
        if not os.path.exists(i.dst):
            shutil.copy(i.src, i.dst)
    return get(root)

def get(path='', ignore=IGNORE_REPO_DIRS):
    root = os.path.abspath(path)
    return tree(directory=root, ignore=ignore)

def tree(directory, padding=' ', _res=[], ignore=[]):
    _res.append(padding[:-1] + '+-' + os.path.basename(os.path.abspath(directory)) + os.path.sep)
    padding += ' '
    files = os.listdir(directory)
    count = 0
    for f in files:
        if f in ignore:
            continue
        count += 1
        _res.append(padding + '|')
        path = directory + os.path.sep + f
        if os.path.isdir(path):
            if count == len(files):
                tree(directory=path, padding=padding + ' ')
            else:
                tree(directory=path, padding=padding + '|')
        else:
            _res.append(padding + '+-' + f)
    return '\n'.join(_res)

def _convert_to_set(arg):
    arg = arg or set()
    if type(arg) is str:
        arg = [arg]
    return set(arg)

def search(directory='.',
           ignore_dir=None, ignore_ext=None, only_ext=None):
    """
      Recursively search files by pattern.
      Input: directory - start point to search,
             ignore and only - filter patterns for directory and files (should be lists)
      Returns list of files.
    """
    ignore_dir = _convert_to_set(ignore_dir)
    ignore_ext = _convert_to_set(ignore_ext)
    only_ext = _convert_to_set(only_ext)

    res_files = []
    for root, dirs, files in os.walk(os.path.abspath(directory)):
        for i in set(dirs) & ignore_dir:
            alog.debug('ignore directory: ' + i)
            dirs.remove(i)
        for f in files[:]:
            alog.debug('file: ' + f)
            # splitext(".file") will return an empty ext
            ext = os.path.splitext(f)[1]
            if ext in ignore_ext:
                files.remove(f)
                alog.debug('ignore file (ignore list) ' + f)
            elif only_ext and (ext not in only_ext):
                files.remove(f)
                alog.debug('ignore file (only list) ' + f)
            else:
                alog.debug('add file ' + f)
                res_files.append(os.path.join(root, f))
    return res_files  # [i.replace('\\', '/') for i in res_files]

def parse(src_files):
    # input: list of source files
    # output: dict
    # {abs_file_path:
    #   tuple(module_name0: set(inst1, inst2, ...),
    #         module_name1: set(inst1, inst2, ...),
    #        ...
    #        )
    #  abs_file_path2:
    #   ...
    # }
    d = {}
    for afile in src_files:
        with open(afile) as f:
            d.update(verilog.parse(f.read()))
    return d

if __name__ == '__main__':
    pass


### Homemade code
from classes_arduino import tryexceptArduino
from classes_colther import homingZabersConcu, moveAxisTo
from classes_text import printme, scale_reponse, binary_response
from classes_speech import say
from rand_scaling import choosing_next_pos
from local_functions import (
    panicButton,
    iti_zaber_dance_in,
    iti_zaber_dance_away,
    closeEnvelope,
)
from failing import (
    getNames,
    recoverData,
    rewriteRecoveredData,
)
from saving_data import (
    apendAll,
    tempSaving,
    buildDict,
    appendDataDict,
    csvToDictGridIndv,
    apendAll,
    create_temp_name,
)
from scaling import Scaling, Anchoring
import globals

from globals import lowest_height, highest_height, scaling_magnitudes

### Ready-made code
import threading
import keyboard

import simpleaudio as sa
import os
import csv
import random
import numpy as np
from datetime import date

def showing(
    positions_list,
    limit,
    path_videos,
    cam,
    arduino_syringe,
    arduino_pantilt,
    arduino_dimmer,
    zabers,
    beep,
    speaker,
    beep_speech_success,
    platform,
    path_data,
    ROIs,
    PanTilts,
    grid,
    first_time,
):
    showing_counter = 0
    showing_stimulation = False
    showing_mags = [0, 1]
    random.shuffle(showing_mags)

    homingZabersConcu(zabers, {"tactile": ["y", "x", "z"]})
    moveAxisTo(zabers, "camera", "y", 482604)

    while not showing_stimulation:
        while showing_counter < 2:
            if keyboard.is_pressed("q"):
                iti_zaber_dance_away(zabers)
                break

            # Prepare position ZABERS
            p = choosing_next_pos(globals.PanTilts, positions_list, limit)
            cROI = ROIs[p]

            # Feedback closure + TONE
            ev = threading.Event()
            beep_trial = threading.Thread(target=beep.play, args=[ev])
            beep_trial.name = "Beep thread"
            beep_trial.daemon = True
            beep_trial.start()

            # STIMULATION
            random_chosen_showing_mag = showing_mags.pop(0)

            if random_chosen_showing_mag == 0:
                stimulus = 3
                delta_target = 0
                time_out = np.random.randint(1, 5, size=1) + np.random.random_sample(1)
                sentence = "That was how 0 feels like"
                globals.grid["colther"] = csvToDictGridIndv(path_data, highest_height)

            elif random_chosen_showing_mag == 1:
                stimulus = 2
                delta_target = scaling_magnitudes[-1]
                time_out = globals.time_out_ex
                sentence = "That was how 100 feels like"
                globals.grid["colther"] = csvToDictGridIndv(path_data, lowest_height)

            iti_zaber_dance_in(zabers, arduino_pantilt, p, PanTilts, grid)

            tryexceptArduino(arduino_syringe, 6)

            file_path = (
                path_videos
                + "/"
                + f"showing_trial{showing_counter+1}_delta{str(round(delta_target*10))}_pos{p}"
            )

            printme(f"Showing trial: {showing_counter}")
            printme(f"Grid Position: {p}")
            printme(f"Delta: {delta_target}")

            cam.targetTempAutoDiffDelta(
                file_path,
                delta_target,
                cROI,
                globals.size_ROI,
                arduino_syringe,
                stimulus,
                time_out,
                ev,
            )
            globals.delta = 0

            sa.stop_all()

            if cam.shutter_open_time < 0.4:
                cam.failed_trial = True

            if not cam.failed_trial:

                say(sentence)

                beep_speech_success.play()
                globals.stimulus = 4

                showing_counter += 1

            if cam.failed_trial:
                showing_mags.append(random_chosen_showing_mag)

            iti_zaber_dance_away(zabers)

            panicButton()

        os.system("clear")

        # Move to ANCHORING?
        if first_time:
            printme("\nARE WE HAPPY WITH SHOWING? (y/n)  ")
            while True:
                if keyboard.is_pressed("y"):
                    showing_stimulation = True
                    break
                elif keyboard.is_pressed("n"):
                    break
        elif keyboard.is_pressed("r"):
            continue
        else:
            showing_stimulation = True
            break

def anchoring(
    scaling,
    anchoring_trials_per_mag,
    subject_n,
    positions_list,
    limit,
    path_data,
    path_videos,
    path_day_bit,
    path_day,
    path_anal,
    path_figs,
    path_audios,
    cam,
    arduino_syringe,
    arduino_pantilt,
    arduino_dimmer,
    zabers,
    beep,
    speaker,
    beep_speech_success,
    platform,
    ROIs,
    PanTilts,
    grid,
    first_time,
):
    ### DATA ANCHORING
    # Data stuff
    data_anchoring = buildDict(
        "subject",
        "trial",
        "delta_stimulation",
        "response",
        "stimulus_time",
        "position",
        "failed",
        "n_block",
    )
    failed_name = "data_failedanchoring"
    names_data_failed = getNames(path_data, f"{failed_name}.*\.csv")
    name_temp_file = create_temp_name(failed_name)

    anch_temp_data_writer, anch_temp_file, anch_temp_file_name = tempSaving(
        path_data, list(data_anchoring.keys()), temp_file_name=name_temp_file
    )
    printme(names_data_failed)

    data_anchoring = recoverData(names_data_failed, path_data, data_anchoring)

    rewriteRecoveredData(data_anchoring, path_data, anch_temp_file_name)

    ### Anchoring
    anchoring_stimulation = False
    homingZabersConcu(zabers, {"tactile": ["y", "x", "z"]})
    moveAxisTo(zabers, "camera", "y", 482604)
    while not anchoring_stimulation:
        anchoring_trial_counter = 0
        anchoring_mags = [0, 0, 1, 1]
        random.shuffle(anchoring_mags)
        while anchoring_trial_counter < anchoring_trials_per_mag:
            if keyboard.is_pressed("q"):
                iti_zaber_dance_away(zabers)
                break

            # Prepare position ZABERS
            p = choosing_next_pos(PanTilts, positions_list, limit)
            cROI = ROIs[p]

            ev = threading.Event()
            beep_trial = threading.Thread(target=beep.play, args=[ev])
            beep_trial.name = "Beep thread"
            beep_trial.daemon = True
            beep_trial.start()

            # STIMULATION
            stimulus = 2

            randomly_chosen_anchoring_mag = anchoring_mags.pop(0)

            if randomly_chosen_anchoring_mag == 0:
                stimulus = 3
                delta_target = 0
                time_out = np.random.randint(1, 5, size=1) + np.random.random_sample(1)
                globals.grid["colther"] = csvToDictGridIndv(path_data, highest_height)

            elif randomly_chosen_anchoring_mag == 1:
                stimulus = 2
                delta_target = scaling_magnitudes[-1]
                time_out = globals.time_out_ex
                globals.grid["colther"] = csvToDictGridIndv(path_data, lowest_height)

            iti_zaber_dance_in(zabers, arduino_pantilt, p, PanTilts, grid)

            tryexceptArduino(arduino_syringe, 6)

            file_path = (
                path_videos
                + "/"
                + f"anchoring_block{scaling.block}_trial{anchoring_trial_counter+1}_delta{str(round(delta_target*10))}_pos{p}"
            )

            printme(f"Anchoring trial: {anchoring_trial_counter}")
            printme(f"Grid Position: {p}")
            printme(f"Delta: {delta_target}")

            cam.targetTempAutoDiffDelta(
                file_path,
                delta_target,
                cROI,
                globals.size_ROI,
                arduino_syringe,
                stimulus,
                time_out,
                ev,
            )
            globals.delta = 0

            sa.stop_all()

            if cam.shutter_open_time < 0.4:
                cam.failed_trial = True

            if not cam.failed_trial:
                sentence = globals.question_anchoring
                # speak(speaker, qs)
                say(globals.question_anchoring)

                beep_speech_success.play()

                anchoring_response, time_response_end = binary_response(
                    sentence, values={"0": "0", "100": "100"}
                )

                beep_speech_success.play()
                globals.stimulus = 4
                iti_zaber_dance_away(zabers)

                anchoring_trial_counter += 1

            elif cam.failed_trial:
                anchoring_response = 3
                time_response_end = 0
                anchoring_mags.append(randomly_chosen_anchoring_mag)

            ### SAVE RESPONSES
            anchTempRowToWrite = [
                subject_n,
                anchoring_trial_counter,
                delta_target,
                int(anchoring_response),
                cam.shutter_open_time,
                p,
                cam.failed_trial,
                scaling.block,
            ]
            data_anchoring = appendDataDict(data_anchoring, anchTempRowToWrite)
            # print(data_anchoring)

            anch_temp_file = open(f"{path_data}/{anch_temp_file_name}.csv", "a")
            anch_temp_data_writer = csv.writer(anch_temp_file)
            anch_temp_data_writer.writerow(anchTempRowToWrite)
            anch_temp_file.close()

            iti_zaber_dance_away(zabers)

            panicButton()

        apendAll(path_data, 1, data_anchoring, file="data_anchoring")

        closeEnvelope(
            zabers, platform, arduino_syringe, arduino_pantilt, arduino_dimmer
        )

        os.system("clear")
        if first_time:
            printme("\nARE WE HAPPY WITH ANCHORING? (y/n)  ")
            while True:
                if keyboard.is_pressed("y"):
                    anchoring_stimulation = True
                    break
                elif keyboard.is_pressed("n"):
                    break
        elif keyboard.is_pressed("r"):
            continue
        else:
            anchoring_stimulation = True
            break


from django.shortcuts import render
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated, IsAdminUser
from rest_framework.response import Response
#from .grupos import grupos
from base.models import Resource
from base.serializer import ResourceSerializer

# Create your views here.
from rest_framework import status

@api_view(['GET'])
def getResources(request):
    query = request.query_params.get('keyword')
    if query == None:
        query = ''
    resources = Resource.objects.filter(name__icontains=query)
    serializer = ResourceSerializer(resources, many=True)
    return Response(serializer.data)

@api_view(['GET'])
def getResource(request, pk):
    resource = Resource.objects.get(_id=pk)
    serializer = ResourceSerializer(resource, many=False)
    return Response(serializer.data)

@api_view(['POST'])
@permission_classes([IsAuthenticated])
def createResource(request):
    user = request.user
    resource = Resource.objects.create(
        user = user,
        name = 'Sample Name',
        author = 'Sample Author',
        comment = '',
        time_proj = 0,
    )
    serializer = ResourceSerializer(resource, many=False)
    return Response(serializer.data)

@api_view(['PUT'])
@permission_classes([IsAuthenticated])
def updateResource(request, pk):
    data = request.data
    resource = Resource.objects.get(_id=pk)

    resource.name = data['name']
    resource.author = data['author']
    resource.comment = data['comment']
    resource.time_proj = data['time_proj']

    resource.save()

    serializer = ResourceSerializer(resource, many=False)
    return Response(serializer.data)

@api_view(['DELETE'])
@permission_classes([IsAuthenticated])
def deleteResource(request, pk):
    resource = Resource.objects.get(_id=pk)
    resource.delete()
    return Response('Resource was deleted')

@api_view(['POST'])
def uploadFile(request):
    data = request.data

    resource_id = data['resource_id']
    resource = Resource.objects.get(_id=resource_id)

    resource.video_file = request.FILES.get('video_file')
    resource.save()

    return Response('File was uploaded')


from __future__ import print_function

import sys
import os
import string
import re
import time
import subprocess
import logging
import libvirt
from libvirt import libvirtError
from xml.etree import ElementTree as ET

from fuelbench import config_manager
from fuelbench import utils
from fuelbench.settings import *
from fuelbench.error import *

NAT_NETWORK_XML = """\
<network>
  <name>${name}</name>
  <forward mode='nat'/>
  <bridge stp='on' delay='0' />
  <ip address='${ipaddr}' netmask='${netmask}'>
  </ip>
</network>
"""

ISO_NETWORK_XML = """\
<network ipv6='yes'>
  <name>${name}</name>
  <bridge stp='on' delay='0' />
</network>
"""

logger = logging.getLogger(__name__)

class KvmProvider(object):

    def __init__(self, uri='qemu:///system', config=config_manager.defaults()):
        self.uri = uri
        self.config = config

    def __list_site_domains(self, conn, site):
        prefix = 'site' + str(site) + '-'
        domains = list()

        for dom in conn.listAllDomains(0x0):
            name = dom.name()
            if name.startswith(prefix):
                domains.append(dom)

        return domains

    def __list_all_domains(self, conn):
        pattern = re.compile(r'^site(\d+)-(.+)$')
        domains = list()

        for dom in conn.listAllDomains(0x0):
            name = dom.name()
            if pattern.match(name):
                domains.append(dom)

        return domains

    def __undefine_domain(self, name):
        cmdline = 'virsh --connect {uri} undefine {domain} --managed-save --snapshots-metadata --remove-all-storage'.format(uri=self.uri, domain=name)

        retcode = subprocess.call(cmdline + '>>{0} 2>&1'.format(CONSOLE_LOG), shell=True)

        if retcode != 0:
            raise RuntimeError('Command failed with exit code {0}'.format(retcode))

    def __delete_volume(self, name, pool):
        cmdline = 'virsh --connect {uri} vol-delete {vol} --pool {pool}'.format(uri=self.uri, vol=name, pool=pool)

        retcode = subprocess.call(cmdline + '>>{0} 2>&1'.format(CONSOLE_LOG), shell=True)

        if retcode != 0:
            raise RuntimeError('Command failed with exit code {0}'.format(retcode))

    def __snapshot_create_as(self, domain, name, desc=''):
        cmdline = 'virsh --connect {uri} snapshot-create-as {domain} {name} --description "{desc}"'.format(uri=self.uri,
                                                                                domain=domain,
                                                                                name=name,
                                                                                desc=desc)
        logger.info('Execute: %s', cmdline)
        retcode = subprocess.call(cmdline + '>>{0} 2>&1'.format(CONSOLE_LOG), shell=True)
        logger.info('Return code: %d', retcode)

        if retcode != 0:
            raise CommandLineError(cmdline, retcode)

    def __snapshot_revert(self, domain, name):
        cmdline = 'virsh --connect {uri} snapshot-revert {domain} {name}'.format(uri=self.uri,
                                                                                domain=domain,
                                                                                name=name)
        logger.info('Execute: %s', cmdline)
        retcode = subprocess.call(cmdline + '>>{0} 2>&1'.format(CONSOLE_LOG), shell=True)
        logger.info('Return code: %d', retcode)

        if retcode != 0:
            raise CommandLineError(cmdline, retcode)

    def __keep_pxe_boot(self, vm_name):
        conn = libvirt.open(self.uri)

        dom = conn.lookupByName(vm_name)
        xml_root = ET.fromstring(dom.XMLDesc())

        xml_os = xml_root.find('os')
        for item in xml_os.findall('boot'):
            xml_os.remove(item)

        ET.SubElement(xml_os, 'boot', {'dev': 'network'})
        ET.SubElement(xml_os, 'boot', {'dev': 'hd'})

        xml_desc = ET.tostring(xml_root)
        conn.defineXML(xml_desc)

        conn.close()

    def get_storage_pool_path(self):
        pool_name = self.config['storage_pool']

        conn = libvirt.openReadOnly(self.uri)

        pool = conn.storagePoolLookupByName(pool_name)
        pool_info_root = ET.fromstring(pool.XMLDesc())

        conn.close()

        return pool_info_root.find("./target/path").text

    def get_vm_nodes(self, site):
        conn = libvirt.openReadOnly(self.uri)

        domains = self.__list_site_domains(conn, site)
        name_list = [dom.name() for dom in domains]

        conn.close()

        return name_list

    def get_max_node_id(self, site):
        vm_nodes = self.get_vm_nodes(site)
        pattern = re.compile(r'^site(\d+)-node-(\d+)$')

        max_id = 0

        for vm in vm_nodes:
            match = pattern.match(vm)
            if match:
                id = int(match.group(2))
                if (id > max_id):
                    max_id = id

        return max_id

    def clean_vm_nodes(self, site):
        conn = libvirt.open(self.uri)

        domains = self.__list_site_domains(conn, site)

        for dom in domains:
            if dom.isActive():
                dom.destroy()

            name = dom.name()
            self.__undefine_domain(name)

        conn.close()

    def clean_slave_nodes(self, site):
        conn = libvirt.open(self.uri)

        domains = self.__list_site_domains(conn, site)

        for dom in domains:
            name = dom.name()
            if name.endswith('-master'):
                continue

            if dom.isActive():
                dom.destroy()

            self.__undefine_domain(name)

        conn.close()

    def clean_all_vm_nodes(self):
        conn = libvirt.open(self.uri)

        domains = self.__list_all_domains(conn)

        for dom in domains:
            if dom.isActive():
                dom.destroy()

            name = dom.name()
            self.__undefine_domain(name)

        conn.close()

    def install_vm_node(self, site, name,
                        vcpus=1, ram=2048,
                        boot='cdrom', iso_image='',
                        disk_format='qcow2', disk_size=40, disk_io='threads',
                        networks=[],
                        os_variant='centos6.5',
                        wait=0,
                        delete_media=False,
                        persistent_boot=False):

        vm_name = "site{0}-{1}".format(site, name)

        install_cmd = 'virt-install --connect {uri} --virt-type kvm --name {name} --vcpus {vcpus} --ram {ram}'.format(uri=self.uri, name=vm_name, vcpus=vcpus, ram=ram)

        pool_path = self.get_storage_pool_path()
        disk_opt = '--disk path={pool_path}/{disk_name}.img,format={disk_format},size={disk_size},bus=virtio,cache=writeback,io={disk_io}'.format(pool_path=pool_path, disk_name=vm_name, disk_format=disk_format, disk_size=disk_size, disk_io=disk_io)

        net_opt = ''
        for net in networks:
            if len(net_opt) > 0:
                net_opt += ' '
            net_opt += '--network network={network},model=virtio'.format(network=net)

        graphics_opt = '--graphics vnc --noautoconsole'

        if boot == 'cdrom':
            if iso_image:
                boot_opt = '--cdrom {iso}'.format(iso=iso_image)
            else:
                raise ValueError('A valid ISO file is required')
        elif boot == 'pxe':
            boot_opt = '--pxe'
        else:
            raise NotImplementedError('Unsupported boot mode: ' + boot)

        os_opt = '--os-variant {0}'.format(os_variant)

        misc_opt = '--wait={wait}'.format(wait=wait)

        cmdline = ' '.join([install_cmd,
                            disk_opt, net_opt,
                            graphics_opt, boot_opt,
                            os_opt, misc_opt])

        try:
            with open(CONSOLE_LOG, 'a') as log:
                print(cmdline, file=log)

            retcode = subprocess.call(cmdline + '>>{0} 2>&1'.format(CONSOLE_LOG), shell=True)

            if retcode != 0:
                raise RuntimeError('Command failed with exit code {0}'.format(retcode))

        finally:
            if delete_media and iso_image:
                self.__delete_volume(os.path.basename(iso_image), 'tmp')

        if persistent_boot:
            self.destroy_vm_node(site, name)

            if boot == 'pxe':
                self.__keep_pxe_boot(vm_name)

            time.sleep(1)
            self.start_vm_node(site, name)

        return vm_name

    def start_vm_node(self, site, name):
        conn = libvirt.open(self.uri)

        vm_name = "site{0}-{1}".format(site, name)

        dom = conn.lookupByName(vm_name)
        ret = dom.create()

        conn.close()

        return ret == 0

    def destroy_vm_node(self, site, name):
        conn = libvirt.open(self.uri)

        vm_name = "site{0}-{1}".format(site, name)

        dom = conn.lookupByName(vm_name)
        ret = dom.destroy()

        conn.close()

        return ret == 0

    def restart_vm_node(self, site, name):
        conn = libvirt.open(self.uri)

        vm_name = "site{0}-{1}".format(site, name)

        dom = conn.lookupByName(vm_name)
        ret = dom.reset()

        conn.close()

        return ret == 0

    def delete_vm_node(self, site, name):

        vm_name = "site{0}-{1}".format(site, name)

        self.__undefine_domain(vm_name)

    def check_vm_node_active(self, site, name):
        conn = libvirt.openReadOnly(self.uri)

        vm_name = "site{0}-{1}".format(site, name)

        dom = conn.lookupByName(vm_name)
        is_active = dom.isActive()

        conn.close()

        return is_active

    def create_vm_snapshot(self, site, name, snapshot, description=''):
        vm_name = "site{0}-{1}".format(site, name)
        success = False

        try:
            self.__snapshot_create_as(vm_name, snapshot, description)
            success = True
        except CommandError as e:
            logger.error(e)
            success = False

        return success

    def revert_vm_snapshot(self, site, name, snapshot):
        vm_name = "site{0}-{1}".format(site, name)
        success = False

        try:
            self.__snapshot_revert(vm_name, snapshot)
            success = True
        except CommandError as e:
            logger.error(e)
            success = False

        return success

    def __list_site_networks(self, conn, site):
        prefix = 'site' + str(site) + 'net'
        networks = list()

        for net in conn.listAllNetworks(0x0):
            name = net.name()
            if name.startswith(prefix):
                networks.append(net)

        return networks

    def __list_all_networks(self, conn):
        pattern = re.compile(r'^site(\d+)net(\d+)$')
        networks = list()

        for net in conn.listAllNetworks(0x0):
            name = net.name()
            if pattern.match(name):
                networks.append(net)

        return networks

    def __create_nat_network(self, conn, name, ipaddr, netmask):

        template = string.Template(NAT_NETWORK_XML)
        xml = template.substitute(name=name,
                                  ipaddr=ipaddr,
                                  netmask=netmask)

        net = conn.networkDefineXML(xml)
        net.setAutostart(1)
        net.create()

        return net

    def __create_isolated_network(self, conn, name):

        template = string.Template(ISO_NETWORK_XML)
        xml = template.substitute(name=name)

        net = conn.networkDefineXML(xml)
        net.setAutostart(1)
        net.create()

        return net

    def get_networks(self, site):
        conn = libvirt.openReadOnly(self.uri)

        networks = self.__list_site_networks(conn, site)
        name_list = [net.name() for net in networks]

        conn.close()

        return name_list

    def clean_networks(self, site):
        conn = libvirt.open(self.uri)

        networks = self.__list_site_networks(conn, site)

        for net in networks:
            if net.isActive():
                net.destroy()

            net.undefine()

        conn.close()

    def clean_all_networks(self):
        conn = libvirt.open(self.uri)

        networks = self.__list_all_networks(conn)

        for net in networks:
            if net.isActive():
                net.destroy()

            net.undefine()

        conn.close()

    def create_networks(self, site, networks):
        conn = libvirt.open(self.uri)
        name_list = list()

        for idx, info in enumerate(networks, start=1):
            name = 'site{0}net{1}'.format(site, idx)
            if info['type'] == NETWORK_NAT:
                ipaddr = info['gateway']
                netmask = info['netmask']
                self.__create_nat_network(conn, name, ipaddr, netmask)
            elif info['type'] == NETWORK_ISOLATED:
                self.__create_isolated_network(conn, name)
            else:
                raise NotImplementedError("Unsupported network type: '{0}'".format(info.type))

            name_list.append(name)

        conn.close()
        return name_list


from typing import List, Tuple, Optional

from collections import defaultdict,deque
from functools import cache
import heapq
from sortedcontainers import SortedDict,SortedList

class Solution:
    def sumOfPower(self, nums: List[int]) -> int:
        nums.sort()
        ret = 0
        b = 0
        mod = 10**9+7
        for i, a in enumerate(nums):
            ret += a*a *(b+a)
            b = b*2+a
            b,ret = b%mod,ret %mod
        return ret

re =Solution().sumOfPower([2,1,4])
print(re)


################################################################################
#Michael Guerzhoy, 2016
#AlexNet implementation in TensorFlow, with weights
#Details:
#http://www.cs.toronto.edu/~guerzhoy/tf_alexnet/
#
#With code from https://github.com/ethereon/caffe-tensorflow
#Model from  https://github.com/BVLC/caffe/tree/master/models/bvlc_alexnet
#Weights from Caffe converted using https://github.com/ethereon/caffe-tensorflow
#
#
################################################################################

from numpy import *
import os
from pylab import *
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cbook as cbook
import time
from scipy.misc import imread
from scipy.misc import imresize
import matplotlib.image as mpimg
from scipy.ndimage import filters
import urllib
from numpy import random
from numpy import genfromtxt
from PIL import Image

import tensorflow as tf

from caffe_classes import class_names

batch_size = 100
learning_rate = 0.5
training_epochs = 5
logs_path = '/home/javier/tensorflowGPU/lib/python3.5/site-packages/tensorflow/models/image/tf_weights-master'

train_x = zeros((1, 227,227,3)).astype(float32)
train_y = zeros((1, 1000))
xdim = train_x.shape[1:]
ydim = train_y.shape[1]

################################################################################
#Read Image

x_dummy = (random.random((1,)+ xdim)/255.).astype(float32)
i = x_dummy.copy()
i[0,:,:,:] = (imread("laska.png")[:,:,:3]).astype(float32)
i = i-mean(i)

################################################################################

# (self.feed('data')
#         .conv(11, 11, 96, 4, 4, padding='VALID', name='conv1')
#         .lrn(2, 2e-05, 0.75, name='norm1')
#         .max_pool(3, 3, 2, 2, padding='VALID', name='pool1')
#         .conv(5, 5, 256, 1, 1, group=2, name='conv2')
#         .lrn(2, 2e-05, 0.75, name='norm2')
#         .max_pool(3, 3, 2, 2, padding='VALID', name='pool2')
#         .conv(3, 3, 384, 1, 1, name='conv3')
#         .conv(3, 3, 384, 1, 1, group=2, name='conv4')
#         .conv(3, 3, 256, 1, 1, group=2, name='conv5')
#         .fc(4096, name='fc6')
#         .fc(4096, name='fc7')
#         .fc(1000, relu=False, name='fc8')
#         .softmax(name='prob'))

def put_kernels_on_grid (kernel, grid_Y, grid_X, pad=1):
    '''Visualize conv. features as an image (mostly for the 1st layer).
    Place kernel into a grid, with some paddings between adjacent filters.
    Args:
      kernel:            tensor of shape [Y, X, NumChannels, NumKernels]
      (grid_Y, grid_X):  shape of the grid. Require: NumKernels == grid_Y * grid_X
                           User is responsible of how to break into two multiples.
      pad:               number of black pixels around each filter (between them)

    Return:
      Tensor of shape [(Y+pad)*grid_Y, (X+pad)*grid_X, NumChannels, 1].
    '''
    # pad X and Y
    x1 = tf.pad(kernel, tf.constant( [[pad,0],[pad,0],[0,0],[0,0]] ))

    # X and Y dimensions, w.r.t. padding
    Y = kernel.get_shape()[0] + pad
    X = kernel.get_shape()[1] + pad

    # put NumKernels to the 1st dimension
    x2 = tf.transpose(x1, (3, 0, 1, 2))
    # organize grid on Y axis
    x3 = tf.reshape(x2, tf.pack([grid_X, Y * grid_Y, X, 3]))

    # switch X and Y axes
    x4 = tf.transpose(x3, (0, 2, 1, 3))
    # organize grid on X axis
    x5 = tf.reshape(x4, tf.pack([1, X * grid_X, Y * grid_Y, 3]))

    # back to normal order (not combining with the next step for clarity)
    x6 = tf.transpose(x5, (2, 1, 3, 0))

    # to tf.image_summary order [batch_size, height, width, channels],
    #   where in this case batch_size == 1
    x7 = tf.transpose(x6, (3, 0, 1, 2))

    # scale to [0, 1]
    x_min = tf.reduce_min(x7)
    x_max = tf.reduce_max(x7)
    x8 = (x7 - x_min) / (x_max - x_min)

    return x8

#
# ... and somewhere inside "def train():" after calling "inference()"
#

net_data = np.load('bvlc_alexnet.npy',encoding='latin1').item()

def conv(input, kernel, biases, k_h, k_w, c_o, s_h, s_w,  padding="VALID", group=1):
    '''From https://github.com/ethereon/caffe-tensorflow
    '''
    c_i = input.get_shape()[-1]
    assert c_i%group==0
    assert c_o%group==0
    convolve = lambda i, k: tf.nn.conv2d(i, k, [1, s_h, s_w, 1], padding=padding)

    if group==1:
    	conv = convolve(input, kernel)
    else:
        input_groups = tf.split(3, group, input)
        kernel_groups = tf.split(3, group, kernel)
        output_groups = [convolve(i, k) for i,k in zip(input_groups, kernel_groups)]
        conv = tf.concat(3, output_groups)
    return  tf.reshape(tf.nn.bias_add(conv, biases), conv.get_shape().as_list())

x = tf.Variable(i)

with tf.name_scope('Conv1') as scope:
#conv1
#conv(11, 11, 96, 4, 4, padding='VALID', name='conv1')
	k_h = 11; k_w = 11; c_o = 96; s_h = 4; s_w = 4
	conv1W = tf.Variable(net_data["conv1"][0])
	conv1b = tf.Variable(net_data["conv1"][1])
	conv1_in = conv(x, conv1W, conv1b, k_h, k_w, c_o, s_h, s_w, padding="SAME", group=1)
	conv1 = tf.nn.relu(conv1_in)

#lrn1
#lrn(2, 2e-05, 0.75, name='norm1')
radius = 2; alpha = 2e-05; beta = 0.75; bias = 1.0
lrn1 = tf.nn.local_response_normalization(conv1,
                                                  depth_radius=radius,
                                                  alpha=alpha,
                                                  beta=beta,
                                                  bias=bias)

#maxpool12
#max_pool(3, 3, 2, 2, padding='VALID', name='pool1')
k_h = 3; k_w = 3; s_h = 2; s_w = 2; padding = 'VALID'
maxpool1 = tf.nn.max_pool(lrn1, ksize=[1, k_h, k_w, 1], strides=[1, s_h, s_w, 1], padding=padding)

with tf.name_scope('Conv2') as scope:
#conv2
#conv(5, 5, 256, 1, 1, group=2, name='conv2')
	k_h = 5; k_w = 5; c_o = 256; s_h = 1; s_w = 1; group = 2
	conv2W = tf.Variable(net_data["conv2"][0])
	conv2b = tf.Variable(net_data["conv2"][1])
	conv2_in = conv(maxpool1, conv2W, conv2b, k_h, k_w, c_o, s_h, s_w, padding="SAME", group=group)
	conv2 = tf.nn.relu(conv2_in)

#lrn2
#lrn(2, 2e-05, 0.75, name='norm2')
radius = 2; alpha = 2e-05; beta = 0.75; bias = 1.0
lrn2 = tf.nn.local_response_normalization(conv2,
                                                  depth_radius=radius,
                                                  alpha=alpha,
                                                  beta=beta,
                                                  bias=bias)

#maxpool2
#max_pool(3, 3, 2, 2, padding='VALID', name='pool2')
k_h = 3; k_w = 3; s_h = 2; s_w = 2; padding = 'VALID'
maxpool2 = tf.nn.max_pool(lrn2, ksize=[1, k_h, k_w, 1], strides=[1, s_h, s_w, 1], padding=padding)

with tf.name_scope('Conv3') as scope:
#conv3
#conv(3, 3, 384, 1, 1, name='conv3')
	k_h = 3; k_w = 3; c_o = 384; s_h = 1; s_w = 1; group = 1
	conv3W = tf.Variable(net_data["conv3"][0])
	conv3b = tf.Variable(net_data["conv3"][1])
	conv3_in = conv(maxpool2, conv3W, conv3b, k_h, k_w, c_o, s_h, s_w, padding="SAME", group=group)
	conv3 = tf.nn.relu(conv3_in)

with tf.name_scope('Conv4') as scope:
#conv4
#conv(3, 3, 384, 1, 1, group=2, name='conv4')
	k_h = 3; k_w = 3; c_o = 384; s_h = 1; s_w = 1; group = 2
	conv4W = tf.Variable(net_data["conv4"][0])
	conv4b = tf.Variable(net_data["conv4"][1])
	conv4_in = conv(conv3, conv4W, conv4b, k_h, k_w, c_o, s_h, s_w, padding="SAME", group=group)
	conv4 = tf.nn.relu(conv4_in)

with tf.name_scope('Conv5') as scope:
#conv5
#conv(3, 3, 256, 1, 1, group=2, name='conv5')
	k_h = 3; k_w = 3; c_o = 256; s_h = 1; s_w = 1; group = 2
	conv5W = tf.Variable(net_data["conv5"][0])
	conv5b = tf.Variable(net_data["conv5"][1])
	conv5_in = conv(conv4, conv5W, conv5b, k_h, k_w, c_o, s_h, s_w, padding="SAME", group=group)
	conv5 = tf.nn.relu(conv5_in)

#maxpool5
#max_pool(3, 3, 2, 2, padding='VALID', name='pool5')
k_h = 3; k_w = 3; s_h = 2; s_w = 2; padding = 'VALID'
maxpool5 = tf.nn.max_pool(conv5, ksize=[1, k_h, k_w, 1], strides=[1, s_h, s_w, 1], padding=padding)

#fc6
#fc(4096, name='fc6')
fc6W = tf.Variable(net_data["fc6"][0])
fc6b = tf.Variable(net_data["fc6"][1])
fc6 = tf.nn.relu_layer(tf.reshape(maxpool5, [1, int(prod(maxpool5.get_shape()[1:]))]), fc6W, fc6b)

#fc7
#fc(4096, name='fc7')
fc7W = tf.Variable(net_data["fc7"][0])
fc7b = tf.Variable(net_data["fc7"][1])
fc7 = tf.nn.relu_layer(fc6, fc7W, fc7b)

#fc8
#fc(1000, relu=False, name='fc8')
fc8W = tf.Variable(net_data["fc8"][0])
fc8b = tf.Variable(net_data["fc8"][1])
fc8 = tf.nn.xw_plus_b(fc7, fc8W, fc8b)

#prob
#softmax(name='prob'))

prob = tf.nn.softmax(fc8)

with tf.Session() as sess:

	bar = tf.get_default_graph().get_tensor_by_name('Conv5/Relu:0')
	print(bar)

	# Visualize conv1 features
	with tf.variable_scope('conv5') as scope_conv:
		tf.get_variable_scope().reuse_variables()
		weights = conv5W
		grid_x = grid_y = 128   # to get a square grid for 64 conv1 features
		grid = put_kernels_on_grid (weights, grid_y, grid_x)
		tf.image_summary('conv5', grid, max_images=1)

	#with tf.name_scope('Reshaping_data') as scope:
	#	x_image = tf.reshape(conv5, [-1, 13, 13,1])
	#	image_summ = tf.image_summary("Example_images", x_image, max_images=3)

	summary_op = tf.merge_all_summaries()

	sess.run(tf.initialize_all_variables())

	output = sess.run(prob)
	################################################################################

	#Output:

	inds = argsort(output)[0,:]
	for i in range(5):
    		print (class_names[inds[-1-i]], output[0, inds[-1-i]])

	writer = tf.train.SummaryWriter(logs_path, graph=tf.get_default_graph())
	summary = sess.run(summary_op)
	writer.add_summary(summary, 1)

sess.close()


import requests
from json import dump
from json import loads
import time
import csv
import datetime
import os

# Variaveis globais:
qtd_dados = 1000
qtd_page = qtd_dados/10
qtd_max_buscas = 20

api_url_base = 'https://api.github.com/graphql'

headers = {
    'Content-Type': 'application/json',
    'Authorization': 'bearer xxxxxxxxxxxxxxxxxxxxxxxxxx',
}

query = """
    {
        search(query: "stars:>100 language:Python", type: REPOSITORY, first:10{AFTER}) {
                pageInfo{
                    hasNextPage
                    endCursor
                }
                  nodes {
                    ... on Repository {

                        nameWithOwner
                        url
                        createdAt
                        updatedAt
                        releases {
                            totalCount
                        }
                        primaryLanguage {
                            name
                        }
                        forks {
                            totalCount
                        }

                    }
                  }
                }
    }
"""
json = {
    "query":query, "variables":{}
}

def request(json, n_consulta = 0):
    time_start = time.time()

    print("consulta numero: "+str(n_consulta)+"/"+str(qtd_page))
    response = requests.post(api_url_base, headers=headers, json=json)

    qtd_tentativas = 1
    while response.status_code != 200 and qtd_tentativas < qtd_max_buscas:
        print("Erro "+str(response.status_code)+" na busca "+str(qtd_tentativas)+"/"+str(qtd_max_buscas)+", iniciando proxima tentativa ")
        qtd_tentativas = qtd_tentativas+1
        response = requests.post(api_url_base, headers=headers, json=json)

    time_finish = time.time()
    delta = time_finish-time_start
    print("tempo da consulta: ")
    print(delta)
    return response

def start():
    respo = initialaze()
    result = search(respo)
    return  result#respo.json()

def initialaze():

    next_query = query.replace("{AFTER}", "")
    json["query"] = next_query
    response = request(json)
    return response

def search(result):
    if result.status_code == 200 :
        result = result.json()
        have_next_page = result["data"]["search"]["pageInfo"]["hasNextPage"]
        nodes = result['data']['search']['nodes']
        current_page = 1
        while have_next_page and current_page < qtd_page:
            cursor = result["data"]["search"]["pageInfo"]["endCursor"]
            next_query = query.replace("{AFTER}", ", after: \"%s\"" % cursor)
            json["query"] = next_query
            result = request(json, current_page)
            if result.status_code == 200:
                result = result.json()
                nodes += result['data']['search']['nodes']
                have_next_page  = result["data"]["search"]["pageInfo"]["hasNextPage"]
            else:
                print("reiniciando a consulta!")
                return result
            current_page+=1
        result['data']['search']['nodes'] = nodes
    return result

def save_file(json):
    nodes = json['data']['search']['nodes']

    file = open("arquivo.csv", 'w')
    fieldnames = ["Nome","url","Data Criacao","Data de Atualizacao","Total de releases","Linguagem","Idade","Tempo de Atualizacao em dias"]
    writer = csv.DictWriter(file, fieldnames=fieldnames)
    writer.writeheader()

    for node in nodes:
        data = node['createdAt']
        data_atual = datetime.datetime.now().date()
        parametros = (data.split('T')[0]).split('-')
        date = datetime.datetime(int(parametros[0]), int(parametros[1]), int(parametros[2])).date()
        idade = int(int(abs((data_atual - date).days))/365)

        data = node['updatedAt']
        parametros_a = (data.split('T')[0]).split('-')
        date = datetime.datetime(int(parametros_a[0]), int(parametros_a[1]), int(parametros_a[2])).date()
        tempo_atualizacao = int(int(abs((data_atual - date).days)))

        linguagem = 'Não informado'
        if node['primaryLanguage'] is not None:
            linguagem = str(node['primaryLanguage']['name'])

        if linguagem == "Python":
	        writer.writerow({"Nome": node['nameWithOwner'],
	                         "url":node['url'],
	                         "Data Criacao":date,
	                         "Data de Atualizacao":node['updatedAt'],
	                         "Linguagem":linguagem,
	                         "Total de releases":node['releases']['totalCount'],
	                         "Idade": idade,
	                         "Tempo de Atualizacao em dias": tempo_atualizacao
	                        })
    file.close()

# save_repository()
result = start()
save_file(result)


import tiktoken

def estimate_input_cost_optimized(model_name, token_count):
    model_cost_dict = {
        "gpt-3.5-turbo": 0.0015,
        "gpt-3.5-turbo-16k": 0.003,
        "gpt-4": 0.03,
    }

    try:
        cost_per_1000_tokens = model_cost_dict[model_name]
    except KeyError:
        raise ValueError(f"The model '{model_name}' is not recognized.")

    estimated_cost = (token_count / 1000) * cost_per_1000_tokens

    return estimated_cost

def count_tokens(text, selected_model):
    encoding = tiktoken.encoding_for_model(selected_model)
    num_tokens = encoding.encode(text)
    return len(num_tokens)


from django.shortcuts import render
from django.http import HttpResponsePermanentRedirect
from django.views.generic import View
from cmdb.forms.DomainNameForm import DomainNameSearchForm,DomainNameAddForm
from cmdb.models.DomainName import DomainName
from django.forms.models import model_to_dict
from django.core.urlresolvers import reverse
from cmdb.models.ProjectModule import ProjectModule
from cmdb.models.IpPool import IpPool
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required
from common.append_dns import append_domainname
from common.append_dns import sed_domainname
from common.append_dns import comment_domainname
from django.contrib.auth.decorators import permission_required

class DomainNameSearchView(View):
    def __init__(self):
        self.context = {}
    @method_decorator(login_required)
    @method_decorator(permission_required("cmdb.scan_domainname",raise_exception=True))
    def get(self,request,*args,**kwargs):
        domainname_search_form = DomainNameSearchForm()
        domainname = DomainName.objects.all()
        self.context = {"domainname_search_form":domainname_search_form,"domainname":domainname}
        return render(request, "cmdb/domainname/domainname_list.html", self.context)
    @method_decorator(login_required)
    @method_decorator(permission_required("cmdb.scan_domainname",raise_exception=True))
    def post(self,request,*args,**kwargs):
        domainname_search_form = DomainNameSearchForm(request.POST)
        if domainname_search_form.is_valid():
            search_dns = request.POST["search_dns"]
            search_ip_address = request.POST["search_ip_address"]
            if search_dns == "":
                domainname = DomainName.objects.filter(ip=search_ip_address)
            else:
                domainname = DomainName.objects.filter(dns__contains = search_dns).filter(ip=search_ip_address)
            self.context = {"domainname":domainname,"domainname_search_form":domainname_search_form}
            return render(request,"cmdb/domainname/domainname_detail.html",self.context)
        else:
            self.context = {"domainname_search_form":domainname_search_form,"errors":domainname_search_form.errors}
            return render(request,"cmdb/domainname/domainname_list.html",self.context)

class DomainNameAddView(View):
    def __init__(self):
        self.context = {}
    @method_decorator(login_required)
    @method_decorator(permission_required("cmdb.add_domainname",raise_exception=True))
    def get(self,request,*args,**kwargs):
        domainname_add_form = DomainNameAddForm()
        self.context = {"domainname_add_form":domainname_add_form}
        return render(request,"cmdb/domainname/domainname_add.html",self.context)
    @method_decorator(login_required)
    @method_decorator(permission_required("cmdb.add_domainname",raise_exception=True))
    def post(self,request,*args,**kwargs):
        domainname_add_form = DomainNameAddForm(request.POST)
        if domainname_add_form.is_valid():
            dns = request.POST["dns"]
            domain_type = request.POST["domain_type"]
            ip_id = request.POST["ip"]
            project_module_id = request.POST["project_module"]
            project_module_url = request.POST["project_module_url"]
            environment = request.POST["environment"]
            if project_module_id == "":
                project_module = None
            else:
                project_module = ProjectModule.objects.get(pk=project_module_id)
            ippool = IpPool.objects.get(pk=ip_id)
            domainname = DomainName.objects.filter(dns=dns).filter(project_module=project_module)
            if domainname.exists():
                self.context = {"domainname_add_form":domainname_add_form,"repeat_errors":"true"}
                return render(request,"cmdb/domainname/domainname_add.html",self.context)
            else:
                domainname = DomainName(dns=dns,domain_type=domain_type,ip=ippool,project_module=project_module,environment=environment,project_module_url=project_module_url)
                domainname.save()
                append_domainname(dns.split(".")[0],domain_type,ippool.ip_address)
                return HttpResponsePermanentRedirect(reverse("domainname"))
        else:
            self.context = {"domainname_add_form":domainname_add_form,"domainname_add_errors":domainname_add_form.errors}
            return render(request,"cmdb/domainname/domainname_add.html",self.context)

class DomainNameUpdateView(View):
    def __init__(self):
        self.context = {}
    @method_decorator(login_required)
    @method_decorator(permission_required("cmdb.change_domainname",raise_exception=True))
    def get(self,request,*args,**kwargs):
        id = kwargs.get("id")
        domainname = DomainName.objects.get(pk=id)
        domainname_dict = model_to_dict(domainname)
        domainname_update_form = DomainNameAddForm(domainname_dict)
        self.context = {"domainname_update_form":domainname_update_form}
        return render(request,"cmdb/domainname/domainname_update.html",self.context)
    @method_decorator(login_required)
    @method_decorator(permission_required("cmdb.change_domainname",raise_exception=True))
    def post(self,request,*args,**kwargs):
        id = kwargs.get("id")
        domainname_update_form = DomainNameAddForm(request.POST)
        if domainname_update_form.is_valid():
            domainname = DomainName.objects.get(pk=id)
            srcstr = "{}     IN     {}     {}".format(domainname.dns.split(".")[0], domainname.domain_type,domainname.ip.ip_address)
            domainname.dns = request.POST["dns"]
            domainname.domain_type = request.POST["domain_type"]
            ip_id = request.POST["ip"]
            domainname.ip = IpPool.objects.get(pk=ip_id)
            project_module_id = request.POST["project_module"]
            if project_module_id == "":
                domainname.project_module = None
            else:
                domainname.project_module = ProjectModule.objects.get(pk=project_module_id)
            domainname.project_module_url = request.POST["project_module_url"]
            domainname.environment = request.POST["environment"]
            domainname.save()
            deststr = "{}     IN     {}     {}".format(domainname.dns.split(".")[0],domainname.domain_type,domainname.ip.ip_address)
            sed_domainname(srcstr,deststr)
            return HttpResponsePermanentRedirect(reverse("domainname"))
        else:
            self.context = {"domainname_update_form":domainname_update_form,"domainname_update_errors":domainname_update_form.errors}
            print(self.context)
            return render(request,"cmdb/domainname/domainname_update.html",self.context)

class DomainNameDeleteView(View):
    def __init__(self):
        self.context = {}
    @method_decorator(login_required)
    @method_decorator(permission_required("cmdb.delete_domainname",raise_exception=True))
    def get(self,request,*args,**kwargs):
        id = kwargs.get("id")
        domainname = DomainName.objects.get(pk=id)
        domainname.delete()
        res = comment_domainname(domainname.dns.split(".")[0])
        print(res)
        return HttpResponsePermanentRedirect(reverse("domainname"))


import torch.nn as nn
from torch.nn import init
import torch.nn.functional as F
import torch.nn.utils.spectral_norm as spectral_norm
from .normalization import SPADE

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

    def print_network(self):
        if isinstance(self, list):
            self = self[0]
        num_params = 0
        for param in self.parameters():
            num_params += param.numel()
        print('Network [%s] was created. Total number of parameters: %.1f million. '
              'To see the architecture, do print(network).'
              % (type(self).__name__, num_params / 1000000))

    def init_weights(self, init_type='normal', gain=0.02):
        def init_func(m):
            classname = m.__class__.__name__
            if classname.find('BatchNorm2d') != -1:
                if hasattr(m, 'weight') and m.weight is not None:
                    init.normal_(m.weight.data, 1.0, gain)
                if hasattr(m, 'bias') and m.bias is not None:
                    init.constant_(m.bias.data, 0.0)
            elif hasattr(m, 'weight') and (classname.find('Conv') != -1 or classname.find('Linear') != -1):
                if init_type == 'normal':
                    init.normal_(m.weight.data, 0.0, gain)
                elif init_type == 'xavier':
                    init.xavier_normal_(m.weight.data, gain=gain)
                elif init_type == 'xavier_uniform':
                    init.xavier_uniform_(m.weight.data, gain=1.0)
                elif init_type == 'kaiming':
                    init.kaiming_normal_(m.weight.data, a=0, mode='fan_in')
                elif init_type == 'orthogonal':
                    init.orthogonal_(m.weight.data, gain=gain)
                elif init_type == 'none':  # uses pytorch's default init method
                    m.reset_parameters()
                else:
                    raise NotImplementedError('initialization method [%s] is not implemented' % init_type)
                if hasattr(m, 'bias') and m.bias is not None:
                    init.constant_(m.bias.data, 0.0)

        self.apply(init_func)

        # propagate to children
        for m in self.children():
            if hasattr(m, 'init_weights'):
                m.init_weights(init_type, gain)

# Using a stripped down version compared to the version found in
# https://github.com/NVlabs/SPADE/blob/master/models/networks/generator.py
class SPADEGenerator(BaseNetwork):
    def __init__(self, opt, sw, sh):
        super().__init__()
        self.opt = opt
        nf = opt.ngf
        # Hard coded here
        self.sw = sw // 16
        self.sh = sh // 16

        # Make the network deterministic by starting with
        # downsampled feature map and segmentation map
        # VAE option removed
        self.fc = nn.Conv2d(self.opt.appearance_nc, 4 * nf, 3, padding=1)

        self.head_0 = SPADEResnetBlock(4 * nf, 4 * nf, opt)

        self.G_middle_0 = SPADEResnetBlock(4 * nf, 4 * nf, opt)
        self.G_middle_1 = SPADEResnetBlock(4 * nf, 4 * nf, opt)

        self.up_0 = SPADEResnetBlock(4 * nf, 2 * nf, opt)
        self.up_1 = SPADEResnetBlock(2 * nf, 1 * nf, opt)

        final_nc = nf

        self.up_4 = SPADEResnetBlock(1 * nf, nf // 2, opt)
        final_nc = nf // 2

        self.conv_img = nn.Conv2d(final_nc, 3, 3, padding=1)

        self.up = nn.Upsample(scale_factor=2, mode='bilinear')

    def forward(self, seg, appearance):
        """
        Args:
            seg (torch.tensor): segmentation map info. In the case of this work,
                                we use landmark heatmaps (projected gaussians)
            appearance (torch.tensor): appearance information. This tensor holds the appearance
                                       information for each part (ie the style information)
        Returns:
            x (torch.tensor): Rendered output image
        """
        # First downsample the style information
        x_0 = F.interpolate(appearance, size=(self.sh, self.sw))
        x_1 = F.interpolate(appearance, size=(self.sh * 2, self.sw * 2))
        # apply first layers on two scales, 1/16 and 1/8
        # this is a modification made for this work, as the 1/16 scale tends to be too small
        x_0 = self.fc(x_0)
        x_0 = self.head_0(x_0, seg)
        x_1 = self.fc(x_1)
        x_1 = self.head_0(x_1, seg)

        x = 0.5*self.up(x_0) + 0.5*x_1
        x = self.G_middle_0(x, seg)
        x = self.G_middle_1(x, seg)

        x = self.up(x)
        x = self.up_0(x, seg)
        x = self.up(x)
        x = self.up_1(x, seg)
        x = self.up(x)
        x = self.up_4(x, seg)

        x = self.conv_img(F.leaky_relu(x, 2e-1))

        # there used to be a tanh here but we're going to make do without it
        return x

# ResNet block that uses SPADE.
# It differs from the ResNet block of pix2pixHD in that
# it takes in the segmentation map as input, learns the skip connection if necessary,
# and applies normalization first and then convolution.
# This architecture seemed like a standard architecture for unconditional or
# class-conditional GAN architecture using residual block.
# The code was inspired from https://github.com/LMescheder/GAN_stability.
class SPADEResnetBlock(nn.Module):
    def __init__(self, fin, fout, opt):
        super().__init__()
        # Attributes
        self.learned_shortcut = (fin != fout)
        fmiddle = min(fin, fout)

        # create conv layers
        self.conv_0 = nn.Conv2d(fin, fmiddle, kernel_size=3, padding=1)
        self.conv_1 = nn.Conv2d(fmiddle, fout, kernel_size=3, padding=1)
        if self.learned_shortcut:
            self.conv_s = nn.Conv2d(fin, fout, kernel_size=1, bias=False)

        # apply spectral norm if specified
        if 'spectral' in opt.norm_G:
            self.conv_0 = spectral_norm(self.conv_0)
            self.conv_1 = spectral_norm(self.conv_1)
            if self.learned_shortcut:
                self.conv_s = spectral_norm(self.conv_s)

        # define normalization layers
        spade_config_str = opt.norm_G.replace('spectral', '')
        self.norm_0 = SPADE(spade_config_str, fin, opt.semantic_nc)
        self.norm_1 = SPADE(spade_config_str, fmiddle, opt.semantic_nc)
        if self.learned_shortcut:
            self.norm_s = SPADE(spade_config_str, fin, opt.semantic_nc)

    # note the resnet block with SPADE also takes in |seg|,
    # the semantic segmentation map as input
    def forward(self, x, seg):
        x_s = self.shortcut(x, seg)

        dx = self.conv_0(self.actvn(self.norm_0(x, seg)))
        dx = self.conv_1(self.actvn(self.norm_1(dx, seg)))

        out = x_s + dx

        return out

    def shortcut(self, x, seg):
        if self.learned_shortcut:
            x_s = self.conv_s(self.norm_s(x, seg))
        else:
            x_s = x
        return x_s

    def actvn(self, x):
        return F.leaky_relu(x, 2e-1)


# -*- coding: utf-8 -*-
import logging

from apscheduler.job import Job as APJob
from apscheduler.jobstores.base import BaseJobStore
from apscheduler.triggers.base import BaseTrigger
from apscheduler.triggers.cron import CronTrigger
from apscheduler.triggers.date import DateTrigger
from apscheduler.triggers.interval import IntervalTrigger as APInterval
from brewtils.models import Job
from pytz import utc

from beer_garden.db.mongo.api import delete, query, query_unique, update
from beer_garden.db.mongo.models import Job as MongoJob

logger = logging.getLogger(__name__)

class IntervalTrigger(APInterval):
    """Beergarden implementation of an apscheduler IntervalTrigger"""

    def __init__(self, *args, **kwargs):
        self.reschedule_on_finish = kwargs.pop("reschedule_on_finish", False)
        super(IntervalTrigger, self).__init__(*args, **kwargs)

def construct_trigger(trigger_type: str, bg_trigger) -> BaseTrigger:
    """Convert a Beergarden trigger to an APScheduler one."""
    if trigger_type == "date":
        return DateTrigger(**bg_trigger.scheduler_kwargs)
    elif trigger_type == "interval":
        return IntervalTrigger(**bg_trigger.scheduler_kwargs)
    elif trigger_type == "cron":
        return CronTrigger(**bg_trigger.scheduler_kwargs)
    else:
        raise ValueError("Trigger type %s not supported by APScheduler" % trigger_type)

def construct_job(job: Job, scheduler, alias="beer_garden"):
    """Convert a Beergarden job to an APScheduler one."""
    if job is None:
        return None

    trigger = construct_trigger(job.trigger_type, job.trigger)
    next_run_time = utc.localize(job.next_run_time) if job.next_run_time else None

    ap_job = APJob.__new__(APJob)
    ap_job._scheduler = scheduler
    ap_job._jobstore_alias = alias
    ap_job.__setstate__(
        {
            "id": job.id,
            "func": "beer_garden.scheduler:run_job",
            "trigger": trigger,
            "executor": "default",
            "args": (),
            "kwargs": {"request_template": job.request_template, "job_id": job.id},
            "name": job.name,
            "misfire_grace_time": job.misfire_grace_time,
            "coalesce": job.coalesce,
            "max_instances": job.max_instances,
            "next_run_time": next_run_time,
        }
    )

    return ap_job

class MongoJobStore(BaseJobStore):
    def lookup_job(self, job_id):
        """Get job from mongo, convert it to an apscheduler Job.

        Args:
            job_id: The ID of the job to get.

        Returns:
            An apscheduler job or None.
        """
        return construct_job(query_unique(Job, id=job_id), self._scheduler, self._alias)

    def get_due_jobs(self, now):
        """Find due jobs and convert them to apscheduler jobs."""
        return self._get_jobs({"next_run_time__lte": now})

    def get_next_run_time(self):
        """Get the next run time as a localized datetime."""
        jobs = query(
            Job,
            filter_params={"next_run_time__ne": None},
            include_fields=["next_run_time"],
            order_by="next_run_time",
        )

        return None if not jobs else utc.localize(jobs[0].next_run_time)

    def get_all_jobs(self):
        """Get all jobs in apscheduler speak."""
        return self._get_jobs()

    def add_job(self, job: APJob) -> None:
        """Just updates the next_run_time.

        Notes:
            The jobstore only needs to update the object that has already been saved to
            the database. It is slightly tricky to generate the ``next_run_time`` on the
             apscheduler job, so we just let the scheduler do it for us. After that, we
             update our job's next_run_time to be whatever the scheduler set.

        Args:
            job: The job from the scheduler
        """
        db_job = query_unique(Job, id=job.kwargs["job_id"])
        db_job.next_run_time = job.next_run_time
        update(db_job)

    def update_job(self, job: APJob) -> None:
        """Update the next_run_time for the job."""
        db_job = query_unique(Job, id=job.id)
        db_job.next_run_time = job.next_run_time
        update(db_job)

    def remove_job(self, job_id):
        """Remove job with the given ID."""
        delete(query_unique(Job, id=job_id))

    def remove_all_jobs(self):
        """Remove all jobs."""
        MongoJob.objects.delete()

    def _get_jobs(self, conditions=None):
        jobs = []
        failed_jobs = []

        for job in query(Job, filter_params=conditions, order_by="next_run_time"):
            try:
                jobs.append(construct_job(job, self._scheduler, self._alias))
            except Exception as ex:
                failed_jobs.append(job)
                logger.exception(
                    f"Exception while restoring job {job.id}, about to remove: {ex}"
                )

        # Remove all the jobs we failed to restore
        for job in failed_jobs:
            delete(job)

        return jobs


import sisl
import sisl.viz
import numpy as np
from scipy import optimize
import matplotlib.pyplot as plt
from rotating_dnbp2 import torsion_angle

'''
Creation of dp_pp structure functionalized with two nitro groups, replacing the biphenyl bridges with
2,2'-dinitrobiphenyl, with different twist angles of the phenyl groups (while keeping nitro groups planar wrt the
corresponding ring.
Based off of the relaxed planar structure.
'''

def plotter():
    sisl.plot(dn_dppp, s=10, atom_indices=True)
    ax = plt.gca(); ax.set_aspect('equal', adjustable='box')
    # ax.set_xlim(right=12); ax.set_ylim(top=10)
    plt.show()

def plotlier():
    plot = dn_dppp.plot()
    # plot.update_settings(backend='plotly')
    plot.show()

def torsion_root_left(beta, geom):
    """
    Returns the torsion angle b/n ats 105, 103, 102 and 104 (phenyl 2), depending on the rotation of one nitrophenyl
    (rot_atoms_left) by an angle beta. (This is to find the initial configuration)
    :param geom: geometry of the DN_DPPP (only this specific one works)
    :param beta: angle of rotation of phenyl (in degrees (º))
    :return: rotated geometry
    """
    geom_coords = geom.axyz()
    rot_geom = geom.rotate(beta, geom_coords[102] - geom_coords[117], atoms=rot_atoms_left, origin=geom_coords[117],
                           only='xyz')
    rot_coords = rot_geom.axyz()
    return torsion_angle(rot_coords[105], rot_coords[103], rot_coords[102], rot_coords[104])

def torsion_root_right(beta, geom):
    """
    Returns the torsion angle b/n ats 129, 127, 126 and 128 (phenyl 4), depending on the rotation of one nitrophenyl
    (rot_atoms_left) by an angle beta. (This is to find the initial configuration)
    :param geom: geometry of the DN_DPPP (only this specific one works)
    :param beta: angle of rotation of phenyl (in degrees (º))
    :return: rotated geometry
    """
    geom_coords = geom.axyz()
    rot_geom = geom.rotate(beta, geom_coords[126] - geom_coords[141], atoms=rot_atoms_right, origin=geom_coords[141],
                           only='xyz')
    rot_coords = rot_geom.axyz()
    return torsion_angle(rot_coords[129], rot_coords[127], rot_coords[126], rot_coords[128])

def half_torsion_left1(alpha, geom):
    """
    Returns the torsion angle b/n ats 5, 3, 2 and a point above 2 in the z direction, depending on rotation angle alpha
    about the axis defined by coords[17]-coords[16].
    :param geom: geometry of the DNBP (only this specific one works)
    :param alpha: angle of rotation (in degrees (º))
    :return: rotated geometry
    """
    geom_coords = geom.axyz()
    rot_geom = geom.rotate(alpha, geom_coords[77] - geom_coords[53], atoms=left_bridge, origin=geom_coords[53],
                           only='xyz')
    rot_coords = rot_geom.axyz()
    return torsion_angle(rot_coords[105], rot_coords[103], rot_coords[102], rot_coords[102] + [0., 0., 1.])

def half_torsion_left2(alpha, geom):
    """
    Returns the torsion angle b/n ats 5, 3, 2 and a point above 2 in the z direction, depending on rotation angle alpha
    about the axis defined by coords[17]-coords[16].
    :param geom: geometry of the DNBP (only this specific one works)
    :param alpha: angle of rotation (in degrees (º))
    :return: rotated geometry
    """
    geom_coords = geom.axyz()
    rot_geom = geom.rotate(alpha, geom_coords[77] - geom_coords[53], atoms=left_bridge, origin=geom_coords[53], only='xyz')
    rot_coords = rot_geom.axyz()
    return torsion_angle(rot_coords[103] + [0., 0., 1.], rot_coords[103], rot_coords[102], rot_coords[104])

def torsion_diff_left(alpha, geom):
    return half_torsion_left2(alpha, geom) - half_torsion_left1(alpha, geom)

def symmetrize_left(geom):
    """
    Rotate the DNBP geometry wrt axis defined by outer carbons, st the nitro groups lie symmetrically wrt E field (z
    axis). For that we try to find the angle of rotation at which halftorsion1=halftorsion2.
    :param geom: DNBP geometry (specifically this one)
    :return: symmetrized DNBP geometry
    """
    geom_coords = geom.axyz()

    root_results = optimize.root_scalar(torsion_diff_left, args=(geom,), x0=0., x1=10., xtol=0.1)
    if not root_results.converged:
        raise Exception("Root finder for symmetrization did not converge")
    sol = root_results.root

    return geom.rotate(sol, geom_coords[77] - geom_coords[53], atoms=left_bridge, origin=geom_coords[53], only='xyz')

def half_torsion_right1(alpha, geom):
    """
    Returns the torsion angle b/n ats 5, 3, 2 and a point above 2 in the z direction, depending on rotation angle alpha
    about the axis defined by coords[17]-coords[16].
    :param geom: geometry of the DNBP (only this specific one works)
    :param alpha: angle of rotation (in degrees (º))
    :return: rotated geometry
    """
    geom_coords = geom.axyz()
    rot_geom = geom.rotate(alpha, geom_coords[55] - geom_coords[85], atoms=right_bridge, origin=geom_coords[85],
                           only='xyz')
    rot_coords = rot_geom.axyz()
    return torsion_angle(rot_coords[129], rot_coords[127], rot_coords[126], rot_coords[126] + [0., 0., 1.])

def half_torsion_right2(alpha, geom):
    """
    Returns the torsion angle b/n ats 5, 3, 2 and a point above 2 in the z direction, depending on rotation angle alpha
    about the axis defined by coords[17]-coords[16].
    :param geom: geometry of the DNBP (only this specific one works)
    :param alpha: angle of rotation (in degrees (º))
    :return: rotated geometry
    """
    geom_coords = geom.axyz()
    rot_geom = geom.rotate(alpha, geom_coords[55] - geom_coords[85], atoms=right_bridge, origin=geom_coords[85], only='xyz')
    rot_coords = rot_geom.axyz()
    return torsion_angle(rot_coords[127] + [0., 0., 1.], rot_coords[127], rot_coords[126], rot_coords[128])

def torsion_diff_right(alpha, geom):
    return half_torsion_right2(alpha, geom) - half_torsion_right1(alpha, geom)

def symmetrize_right(geom):
    """
    Rotate the DNBP geometry wrt axis defined by outer carbons, st the nitro groups lie symmetrically wrt E field (z
    axis). For that we try to find the angle of rotation at which halftorsion1=halftorsion2.
    :param geom: DNBP geometry (specifically this one)
    :return: symmetrized DNBP geometry
    """
    geom_coords = geom.axyz()

    root_results = optimize.root_scalar(torsion_diff_right, args=(geom,), x0=0., x1=10., xtol=0.1)
    if not root_results.converged:
        raise Exception("Root finder for symmetrization did not converge")
    sol = root_results.root

    # Add 180 so it is upside down wrt the left bridge
    return geom.rotate(sol+180, geom_coords[55] - geom_coords[85], atoms=right_bridge, origin=geom_coords[85], only='xyz')

def too_close(coordinates):
    for i in nitro1:
        for j in nitro2:
            if np.linalg.norm(coordinates[i] - coordinates[j]) < 1.4:  # Nitro groups too close
                return True
    for i in nitro3:
        for j in nitro4:
            if np.linalg.norm(coordinates[i] - coordinates[j]) < 1.4:  # Nitro groups too close
                return True
    if np.linalg.norm(coordinates[109] - coordinates[118]) < 1.1 or \
       np.linalg.norm(coordinates[108] - coordinates[119]) < 1.1 or \
       np.linalg.norm(coordinates[133] - coordinates[142]) < 1.1 or \
       np.linalg.norm(coordinates[132] - coordinates[143]) < 1.1:  # oxygen too close to hydrogen atom
        return True
    return False

XV_sile = sisl.get_sile('/home/asier/Documents/master/tfm/siesta/dn_dppp/DN_DPPP.XV')
dn_dppp = sisl.Geometry.read(XV_sile)
coords = dn_dppp.axyz()

# torsion_atoms_left = [105, 103, 102, 104]
# torsion_atoms_right = [129, 127, 126, 128]
left_bridge = [116, 113, 114, 105, 103, 111,
               119, 122, 121, 100, 107, 109,
               102, 104, 110, 112, 115, 117,
               118, 123, 120, 101, 108, 106]
right_bridge = [127, 129, 135, 137, 138, 140,
                145, 146, 143, 124, 131, 133,
                126, 128, 134, 136, 139, 141,
                144, 147, 142, 125, 132, 130]

rot_atoms_left = [110, 115, 104, 112,
                  118, 123, 120,
                  101, 108, 106]
rot_atoms_right = [128, 136, 139, 134,
                   142, 147, 144,
                   125, 132, 130]
nitro1 = [100, 107, 109]; nitro2 = [101, 108, 106]
nitro3 = [124, 131, 133]; nitro4 = [125, 132, 130]

# Rotate phenyl 2 st the initial configuration in the left bridge
# has the two nitros lined up (this way, a rotation of 180º will be
# enough to cover all possible configurations
left_root_results = optimize.root_scalar(torsion_root_left, args=(dn_dppp,), x0=-90., x1=-100., xtol=0.1)
beta_left = left_root_results.root
dn_dppp = dn_dppp.rotate(beta_left, coords[102] - coords[117], atoms=rot_atoms_left, origin=coords[117], only='xyz')

coords = dn_dppp.axyz()

right_root_results = optimize.root_scalar(torsion_root_right, args=(dn_dppp,), x0=-90., x1=-100., xtol=0.1)
beta_right = right_root_results.root
dn_dppp = dn_dppp.rotate(beta_right, coords[126] - coords[141], atoms=rot_atoms_right, origin=coords[141], only='xyz')

dn_dppp = symmetrize_left(dn_dppp)
dn_dppp = symmetrize_right(dn_dppp)

coords = dn_dppp.axyz()

for ang in range(0, 190, 10):
    rotated = dn_dppp.rotate(ang, coords[102] - coords[117], atoms=rot_atoms_left, origin=coords[117], only='xyz')
    rotated = symmetrize_left(rotated)
    rotated = symmetrize_left(rotated)
    rotated = rotated.rotate(ang, coords[126] - coords[141], atoms=rot_atoms_right, origin=coords[141], only='xyz')
    rotated = symmetrize_right(rotated)
    rotated = symmetrize_right(rotated)

    new_coords = rotated.axyz()
    if too_close(new_coords):
        # print('Too close!')
        continue
    print(str(ang) + ' ', torsion_angle(new_coords[105], new_coords[103], new_coords[102], new_coords[104]), ' ',
          torsion_angle(new_coords[129], new_coords[127], new_coords[126], new_coords[128]))

    # rotated.write('structures/STRUCT_{0:03d}.fdf'.format(ang))


import os
from typing import Dict, List

import numpy as np
import scipy.sparse as sps

from recsys_framework.Data_manager.Utility import print_stat_datareader
from conferences.cikm.cfgan.our_implementation.constants import CFGANDatasetMode, CFGANBenchmarks
from conferences.cikm.cfgan.our_implementation.original.data import \
    loadTestData as OriginalTestDataReader
from conferences.cikm.cfgan.our_implementation.original.data import \
    loadTrainingData as OriginalTrainingDataReader
from recsys_framework.Data_manager.data_consistency_check import assert_implicit_data, assert_disjoint_matrices
from recsys_framework.Data_manager.load_and_save_data import save_data_dict_zip, load_data_dict_zip
from recsys_framework.Data_manager.split_functions.split_train_validation import \
    split_train_validation_percentage_random_holdout, split_train_validation_cold_start_user_wise
from recsys_framework.Utils.conf_logging import get_logger

logger = get_logger(__name__)

def dict_to_sparse_csr(data: Dict[int, List[int]], num_users: int, num_items: int) -> \
        sps.csr_matrix:
    mat = sps.dok_matrix((num_users, num_items), dtype=np.int32)
    for user_id, item_ids in data.items():
        for item_id in item_ids:
            mat[user_id, item_id] = 1

    mat = mat.tocsr()
    new_num_users, new_num_items = mat.shape
    if new_num_users != num_users or new_num_items != num_items:
        raise ValueError(
            f"New dimensions do not match. "
            f"Previous #Users: {num_users} - Actual #Users: {new_num_users}. "
            f"Previous #Items: {num_items} - Actual #Items: {new_num_items}."
        )

    return mat

class CFGANDatasetReader:
    CONFERENCE = "CIKM"
    MODEL = "CFGAN"
    ORIGINAL_DATA_PATH = os.path.join("", "conferences", "cikm", "cfgan", "original_source_code", "datasets")

    NAME_URM_TRAIN = "URM_train"
    NAME_URM_VALIDATION = "URM_validation"
    NAME_URM_VALIDATION_CONDITION = "URM_validation_condition"
    NAME_URM_VALIDATION_PROFILE = "URM_validation_profile"
    NAME_URM_TEST = "URM_test"
    NAME_URM_TEST_CONDITION = "URM_test_condition"
    NAME_URM_TEST_PROFILE = "URM_test_profile"

    def __init__(
        self,
        dataset: CFGANBenchmarks,
        mode: CFGANDatasetMode
    ):
        if not isinstance(dataset, CFGANBenchmarks):
            raise ValueError("Variable <dataset_name> must be an instance of <CFGANBenchmarks>.")

        if not isinstance(mode, CFGANDatasetMode):
            raise ValueError("Variable <mode> must be an instance of <CFGANDatasetMode>.")

        self.mode = mode
        self.dataset_name: str = dataset.value
        self.URM_DICT: dict[str, sps.csr_matrix] = {}
        self.ICM_DICT: dict[str, sps.csr_matrix] = {}

    def load_data(self) -> None:
        if self.mode != CFGANDatasetMode.ORIGINAL:
            raise ValueError(f"Dataset can only be loaded if it's the original split.")

        pre_split_path: str = os.path.join(
            ".",
            "data_split",
            f"{self.dataset_name}/"
        )
        pre_split_filename = f"{self.mode.value}_split_data_"

        # If directory does not exist, create
        os.makedirs(pre_split_path, exist_ok=True)

        try:
            logger.info(f"Dataset_{self.dataset_name}: Attempting to load pre-split data")

            for attrib_name, attrib_object in load_data_dict_zip(pre_split_path, pre_split_filename).items():
                self.__setattr__(attrib_name, attrib_object)

        except FileNotFoundError:

            logger.info(f"Dataset_{self.dataset_name}: Pre-split data not found, building new one")

            train_split: Dict[int, List[int]]
            test_split: Dict[int, List[int]]
            num_users: int
            num_items: int

            train_split, num_users, num_items = OriginalTrainingDataReader(
                benchmark=self.dataset_name,
                path=self.ORIGINAL_DATA_PATH
            )

            test_split, _ = OriginalTestDataReader(
                benchmark=self.dataset_name,
                path=self.ORIGINAL_DATA_PATH
            )

            urm_train = dict_to_sparse_csr(train_split, num_users, num_items)
            urm_test = dict_to_sparse_csr(test_split, num_users, num_items)

            original_urm_train = urm_train.copy()

            logger.info(
                "Loading dataset using the original splits. Still need to create a validation set."
            )
            urm_test = urm_test.copy()

            urm_train, urm_validation = split_train_validation_percentage_random_holdout(
                URM_train=urm_train.copy(),
                train_percentage=0.8
            )

            urm_validation_condition, urm_validation_profile = split_train_validation_percentage_random_holdout(
                URM_train=urm_validation.copy(),
                train_percentage=0.8,
            )
            urm_test_condition, urm_test_profile = split_train_validation_percentage_random_holdout(
                URM_train=urm_test.copy(),
                train_percentage=0.8,
            )

            assert_implicit_data([
                urm_train,
                urm_validation_condition, urm_validation_profile, urm_validation,
                urm_test_condition, urm_test_profile, urm_test,
            ])
            assert_disjoint_matrices([
                urm_train,
                urm_validation_condition, urm_validation_profile,
                urm_test_condition, urm_test_profile,
            ])
            assert_disjoint_matrices([
                urm_train,
                urm_validation,
                urm_test,
            ])

            assert np.array_equal(
                urm_validation.toarray(),
                (urm_validation_profile + urm_validation_condition).toarray()
            )
            assert np.array_equal(
                urm_test.toarray(),
                (urm_test_profile + urm_test_condition).toarray()
            )
            assert np.array_equal(
                original_urm_train.toarray(),
                (urm_train + urm_validation).toarray(),
            )

            self.URM_DICT = {
                self.NAME_URM_TRAIN: urm_train,
                self.NAME_URM_VALIDATION: urm_validation,
                self.NAME_URM_VALIDATION_CONDITION: urm_validation_condition,
                self.NAME_URM_VALIDATION_PROFILE: urm_validation_profile,
                self.NAME_URM_TEST: urm_test,
                self.NAME_URM_TEST_CONDITION: urm_test_condition,
                self.NAME_URM_TEST_PROFILE: urm_test_profile,
            }

            self.ICM_DICT = {}

            save_data_dict_zip(self.URM_DICT, self.ICM_DICT, pre_split_path, pre_split_filename)

        logger.info(f"{self.dataset_name}: Dataset loaded")

        print_stat_datareader(self)

    def load_data_cold_users(self) -> None:
        if self.mode != CFGANDatasetMode.COLD_USERS:
            raise ValueError(
                f"Cold users split can only be generated using mode={CFGANDatasetMode.COLD_USERS}"
            )

        pre_split_path: str = os.path.join(
            ".",
            "data_split",
            f"{self.dataset_name}/"
        )
        pre_split_filename = f"{self.mode.value}_cold_user_split_data_"

        # If directory does not exist, create
        os.makedirs(pre_split_path, exist_ok=True)

        try:
            logger.info(
                f"Dataset_{self.dataset_name}: Attempting to load cold-users pre-split data"
            )

            for attrib_name, attrib_object in load_data_dict_zip(pre_split_path, pre_split_filename).items():
                self.__setattr__(attrib_name, attrib_object)

        except FileNotFoundError:
            logger.info(
                f"Dataset_{self.dataset_name}: Pre-split data not found, building new one"
            )

            train_split: Dict[int, List[int]]
            test_split: Dict[int, List[int]]
            num_users: int
            num_items: int

            train_split, num_users, num_items = OriginalTrainingDataReader(
                benchmark=self.dataset_name,
                path=self.ORIGINAL_DATA_PATH
            )

            test_split, _ = OriginalTestDataReader(
                benchmark=self.dataset_name,
                path=self.ORIGINAL_DATA_PATH
            )

            urm_train = dict_to_sparse_csr(train_split, num_users, num_items)
            urm_test = dict_to_sparse_csr(test_split, num_users, num_items)

            urm_full: sps.csr_matrix = urm_train + urm_test
            urm_train, urm_test = split_train_validation_cold_start_user_wise(
                URM_train=urm_full.copy(),
                full_train_percentage=0.8,
                cold_items=0,
                verbose=True,
            )
            urm_train, urm_validation = split_train_validation_cold_start_user_wise(
                URM_train=urm_train.copy(),
                full_train_percentage=0.8,
                cold_items=0,
                verbose=True,
            )
            urm_validation_condition, urm_validation_profile = split_train_validation_percentage_random_holdout(
                URM_train=urm_validation.copy(),
                train_percentage=0.8,
            )
            urm_test_condition, urm_test_profile = split_train_validation_percentage_random_holdout(
                URM_train=urm_test.copy(),
                train_percentage=0.8,
            )

            self.URM_DICT = {
                "URM_train": urm_train,
                "URM_validation": urm_validation,
                "URM_validation_condition": urm_validation_condition,
                "URM_validation_profile": urm_validation_profile,
                "URM_test": urm_test,
                "URM_test_condition": urm_test_condition,
                "URM_test_profile": urm_test_profile,
            }

            self.ICM_DICT = {}

            save_data_dict_zip(self.URM_DICT, self.ICM_DICT, pre_split_path, pre_split_filename)

        logger.info(f"{self.dataset_name}: Cold User Dataset loaded")

        print_stat_datareader(self)


import getopt
import sys
from loguru import logger
import colorama
import signal
from AnimeUnityEngine import scraper, logging_aux, res_obj_manipulator, jdownloader
import printer

config = {'crawl_path': None, 'download_path': None, 'print_level': 9, 'season': None, 'log_level': 'WARNING', 'file_log':False}
version = "v1.0"

def sig_handler(_signo, _stack_frame):
    print("\n")
    sys.exit(0)
@logging_aux.logger_wraps()
def main():
    signal.signal(signal.SIGTERM, sig_handler)
    signal.signal(signal.SIGINT, sig_handler)
    logging_aux.init_logger(level=config['log_level'], file_log=config['file_log'])
    if len(sys.argv) == 1:
        keyword = interactive_mode()
    else:
        keyword = cli_mode()
    logger.debug("Keyword selected: {}".format(keyword))
    search_res = scraper.search(title=keyword)
    logger.debug("search results: {}".format(search_res))
    if not search_res:
        print(f"{colorama.Fore.RED}No Anime Found{colorama.Style.RESET_ALL}")
        logger.debug("No anime found, keyword: {}".format(keyword))
        exit(1)
    logger.debug("Printing anime list")
    printer.print_anime_list(search_res, config, 1)
    anime_id = input("ID: ")
    logger.debug("ID selected: {}".format(anime_id))
    selected = res_obj_manipulator.get_selected_anime_obj_by_id(search_res, anime_id)
    logger.debug("Anime selected: {}".format(selected))
    logger.debug("Printing anime episodes")
    if config['season'] is not None:
        selected = scraper.season_scraper(selected, config)
        logger.debug(f"Season scraped: {selected}")
    printer.print_anime_list(selected, config, 2)
    if config['crawl_path'] is not None and config['download_path'] is not None:
        if not isinstance(selected, type([])):
            selected = [selected]

        jdownloader.send_to_jdownloader(selected, config)

@logging_aux.logger_wraps()
def cli_mode():
    keyword = None
    global config

    argv = sys.argv[1:]

    try:
        opts = getopt.getopt(argv, 'k:s:p:hv', ['printlevel=', 'keyword=', 'crawlpath=', 'jdownloadpath=', 'season=', 'loglevel=','help','version', 'filelog'])
    except getopt.GetoptError:
        # stampa l'informazione di aiuto ed esce:
        usage()
        sys.exit(2)
    for opt, arg in opts:
        if opt in ['-k', '--keyword']:
            keyword = arg
        if opt in ['--jdownloadpath']:
            config['download_path'] = arg
        if opt in ['--crawlpath']:
            config['crawl_path'] = arg
        if opt in ['-p', '--printlevel']:
            config['print_level'] = int(arg)
        if opt in ['-s', '--season']:
            config['season'] = []
            for elem in str.split(arg, ','):
                config['season'].append(elem)
        if opt in ['--loglevel']:
            if arg in logging_aux.defined_log_levels:
                config['loglevel'] = arg
            else:
                logger.warning(
                    f"Log level '{arg}' not valid.\nValid log levels are {logging_aux.defined_log_levels}.\nSetting log level to {config['loglevel']}")
        if opt in ['-h', '--help']:
            usage()
            sys.exit(0)
        if opt in ['-v', '--version']:
            print(f"AnimeUnityCLIPy {version}")
            sys.exit(0)
        if opt in ['--filelog']:
            config['file_log'] = True

    if keyword is None:
        logger.warning("No keyword selected")
        sys.exit(1)
    return keyword

@logging_aux.logger_wraps()
def interactive_mode():
    keyword = input("Keyword: ")
    return keyword

def usage():
    usage = f"AnimeUnityCLIPy {version} Usage:\n" \
            f"\t-k, --keyword (str):\t\tSpecify the keyword to search\n" \
            f"\t-p, --printlevel (int):\t\tSpecify the print level (1: title only, 2: title and info, 3: title,info and episodes,...)\n" \
            f"\t-s, --season (str):\t\tSpecify what to look for ({scraper.defined_anime_types.append('ALL')}), Multiple options can be selected (TV,Movie)\n" \
            f"\t--loglevel (str):\t\tLog level -.- One of these options: {logging_aux.defined_log_levels}\n" \
            f"\t--filelog: \t\t\tSave log > warning to a file\n" \
            f"\t--jdownloadpath (Path):\t\tDestination folder for the anime dir. MUST be used in conjunction with --crawlpath\n" \
            f"\t--crawlpath (Path):\t\tDestination folder for the crawljobs. MUST be used in conjunction with -jdp\n" \
            f"\t-h, --help:\t\t\tShow this screen\n" \
            f"\t-v, --version:\t\t\tPrint software version\n"
    print(usage)

if __name__ == "__main__":
    main()


import copy
from dataclasses import dataclass, field
from pathlib import Path
from typing import List, NamedTuple

FILE_DIR = Path(__file__).parent

def get_gamma(text: List[str]) -> List[int]:
    gamma = [0] * len(text[0])
    for line in text:
        for ii, char in enumerate(line):
            if bool(int(char)):
                gamma[ii] += 1
            else:
                gamma[ii] -= 1
    return gamma

def convert_gamma(nums: List[str]) -> int:
    gamma = nums[:]
    ii = 0
    for ii, num in enumerate(nums):
        if num <= 0:
            gamma[ii] = '0'
        else:
            gamma[ii] = '1'
    gamma = "".join(gamma)
    return gamma

def get_board(matrices: List[num]) -> str:

    remaining = copy.deepcopy(matrices)
    ii = 0
    while len(remaining) > 1:
        most = 0
        for n in remaining:
            if bool(int(n[ii])):
                most += 1
            else:
                most -= 1
        if common:
            if most >= 0:
                most = "1"
            else:
                most = "0"
            remaining = [n for n in remaining if n[ii] == most]
        else:
            if most < 0:
                most = "1"
            else:
                most = "0"
            remaining = [n for n in remaining if n[ii] == most]
        ii += 1
    return remaining[0]

if __name__ == "__main__":
    DATA = (FILE_DIR / "input.txt").read_text().strip()
    data = [x for x in DATA.split('\n\n')]
    breakpoint()