from __future__ import absolute_import, division, print_function
from libtbx.utils import Sorry
import libtbx.load_env
import iotbx.pdb
import sys, re
from mmtbx.refinement.flip_peptide_side_chain import flip_residue
from iotbx.pdb.utils import all_chain_ids
from mmtbx.utils import run_reduce_with_timeout
from mmtbx.validation.clashscore import check_and_report_reduce_failure

def seg_id_to_chain_id(pdb_hierarchy):
  import string
  two_character_chain_ids = []
  segid_list = []
  seg_dict = {}
  for atom in pdb_hierarchy.atoms():
    if atom.segid not in segid_list:
      segid_list.append(atom.segid)
  lower_letters = string.ascii_lowercase
  upper_letters = string.ascii_uppercase
  two_character_chain_ids = all_chain_ids()
  for id in segid_list:
    chainID = two_character_chain_ids[0]
    seg_dict[id] = chainID
    two_character_chain_ids.remove(chainID)
  return seg_dict

def find_bare_chains_with_segids(pdb_hierarchy):
  bare_chains = False
  for chain in pdb_hierarchy.chains():
    if chain.id in ['', ' ', '  ']:
      segid = None
      for atom in chain.atoms():
        if segid == None:
          segid = atom.segid
        elif segid != None and segid != atom.segid:
          #require that each chain have a unique segid for this logic
          return False
      if segid != None and segid not in ['', ' ', '  ', '   ', '    ']:
        bare_chains = True
  return bare_chains

def assign_chain_ids(pdb_hierarchy, seg_dict):
  rename_txt = ""
  for chain in pdb_hierarchy.chains():
    if chain.id in ['', ' ', '  ']:
      segid = None
      for atom in chain.atoms():
        if segid == None:
          segid = atom.segid
        elif segid != atom.segid:
          print(segid, atom.segid)
          raise Sorry("multiple segid values defined for chain")
      new_id = seg_dict[segid]
      chain.id = new_id
      rename_txt = rename_txt + \
      "segID %s renamed chain %s for Reduce N/Q/H analysis\n" % (segid, new_id)
  return rename_txt

def force_unique_chain_ids(pdb_hierarchy):
  used_chain_ids = []
  two_char = all_chain_ids()
  #filter all used chains
  for model in pdb_hierarchy.models():
    for chain in model.chains():
      cur_id = chain.id
      if cur_id in two_char:
        two_char.remove(cur_id)
  #force unique chain ids
  for model in pdb_hierarchy.models():
    for chain in model.chains():
      cur_id = chain.id
      if cur_id not in used_chain_ids:
        used_chain_ids.append(cur_id)
      else:
        new_id = two_char[0]
        chain.id = new_id
        two_char.remove(new_id)

def get_nqh_flips(pdb_hierarchy):
  pdb_string = pdb_hierarchy.as_pdb_string()
  output = run_reduce(pdb_string=pdb_string, remove_hydrogens=True)
  user_mods = []
  score_dict = {}
  atom_notes = []
  for line in output.stdout_lines:
    if re.match(r'USER  MOD', line):
      flip = re.search(r':(.{15}):FLIP(.*):sc=.*[F|C]\(o=(.*),f=(.*)\)',line)
      if(flip):
        if flip.group(3)[-1:] == '!':
          score_o = float(flip.group(3)[:-1])
        else:
          score_o = float(flip.group(3))
        if flip.group(4)[-1:] == '!':
          score_f = float(flip.group(4)[:-1])
        else:
          score_f = float(flip.group(4))
        score_diff = score_f - score_o
        if score_f <= -2.0:
          user_mods.append('!'+flip.group(1).strip())
        else:
          user_mods.append(flip.group(1).strip())
        score_dict[flip.group(1).strip()] = score_diff
        if re.search(r'HIS',line):
          atom_notes.append([flip.group(1).strip(),flip.group(2).strip()])
  return user_mods, atom_notes, score_dict

# return true if H atoms are inconsistent with Reduce protonation state
# if no D or E H's are present, always return False to allow flip
def check_for_his_h(residue, atom_notes, key):
  atom_list =[]
  for atom in residue.atoms():
    atom_list.append(atom.name)

  #check for no H atoms
  if not (" HD1" in atom_list or " HD2" in atom_list or " HE1" in atom_list or
          " HE2" in atom_list):
    return False
  for entry in atom_notes:
    if entry[0] == key:
      if entry[1].strip() == "no HD1":
        if not ( (" HD2" in atom_list and " HE1" in atom_list and " HE2" in atom_list) and
                 not " HD1" in atom_list ):
          return True
      elif entry[1].strip() == "no HE2":
        if not ( (" HD1" in atom_list and " HD2" in atom_list and " HE1" in atom_list) and
                 not " HE2" in atom_list):
          return True
      elif entry[1].strip() == "+bothHN":
        if not (" HD1" in atom_list and " HD2" in atom_list and " HE1" in atom_list and
                " HE2" in atom_list):
          return True
  return False

def run_reduce(pdb_string, remove_hydrogens=True):
  assert (libtbx.env.has_module(name="reduce"))
  trim = " -quiet -trim -"
  build = " -quiet -build -allalt -"
  input_str = ""
  if(remove_hydrogens):
    clean = run_reduce_with_timeout(parameters=trim,
                                    stdin_lines=pdb_string)
    check_and_report_reduce_failure(clean, pdb_string, "reduce_failure.pdb")
    input_str = "\n".join(clean.stdout_lines)
  else:
    input_str = pdb_string
  output = run_reduce_with_timeout(parameters=build,
                                   stdin_lines=input_str)
  check_and_report_reduce_failure(output, input_str, "reduce_failure.pdb")
  return output

def flip_selected(pdb_hierarchy, # changed in-place
                  mon_lib_srv,
                  flip_list,
                  atom_notes,
                  score_dict,
                  log):
  sites_cart_start = pdb_hierarchy.atoms().extract_xyz()
  total_flipped = 0
  #
  # XXX TEMPORARY DISABLED. THIS DOES NOT COVER ALL. USE GRM INSTEAD OF LINK STUFF. XXX
  #
  ##find excluded residues that are covalently linked
  exclude_sidechain = []
  #for arg in apply_cif_links:
  #  for res in arg.pdbres_pair:
  #    resname = res[8:11]
  #    if resname.upper() in ['ASN', 'GLN', 'HIS']:
  #      chainID = res[11:13]
  #      resnum = res[13:-1]
  #      key = chainID.strip()+resnum+resname
  #      #exclude_sidechain.append(res[8:-1].strip())
  #      exclude_sidechain.append(key)
  #print exclude_sidechain
  for model in pdb_hierarchy.models():
    for chain in model.chains():
      for residue_group in chain.residue_groups():
        conformers = residue_group.conformers()
        for conformer in residue_group.conformers():
          residue = conformer.only_residue()
          key = chain.id+residue.resid()+residue.resname+"    "+conformer.altloc
          key = key.strip()
          if key[0:9] in exclude_sidechain:
            print(key[0:9]+' is covalently modified...skipping', file=log)
          elif '!'+key in flip_list:
            print('** '+key+' **'+' both conformations clash, **PLEASE CHECK MANUALLY**', file=log)
          elif key in flip_list:
            if residue.resname=="HIS":
              if check_for_his_h(residue, atom_notes, key)==True:
                continue
            print(key, file=log)
            # here we are going to do flips in hierarchy and then simply
            # extract xray_structure with updated coordinates
            flip_residue(residue,mon_lib_srv)
            total_flipped += 1
  print("\nTotal number of N/Q/H flips: %d\n" % total_flipped, file=log)

def flip(pdb_hierarchy, log=None, mon_lib_srv=None):
  if mon_lib_srv is None:
    mon_lib_srv = mmtbx.monomer_library.server.server()
  if(log is None): log = sys.stdout
  pdb_hierarchy.atoms().reset_i_seq()
  print("Analyzing N/Q/H residues for possible flip corrections...", file=log)
  tmp_pdb_hierarchy = pdb_hierarchy.deep_copy()
  tmp_pdb_hierarchy.atoms().reset_i_seq()
  #analyze chain/segid relationship
  bare_chains = find_bare_chains_with_segids(pdb_hierarchy=pdb_hierarchy)
  if bare_chains:
    seg_dict = seg_id_to_chain_id(pdb_hierarchy=tmp_pdb_hierarchy)
    rename_txt = assign_chain_ids(pdb_hierarchy=tmp_pdb_hierarchy,
                                        seg_dict=seg_dict)
    print(rename_txt, file=log)
  if tmp_pdb_hierarchy.overall_counts().n_duplicate_chain_ids > 0:
    force_unique_chain_ids(
      pdb_hierarchy=tmp_pdb_hierarchy)
  try:
    flip_list, atom_notes, score_dict = get_nqh_flips(
      pdb_hierarchy = tmp_pdb_hierarchy)
  except OSError as e :
    if (e.errno == 32) :
      print("WARNING: system error attempting to run Reduce", file=log)
      print("         this may indicate a crash or OS conflict", file=log)
      print("         phenix.refine will continue running, but you", file=log)
      print("         should check Asn/Gln/His residues visually.", file=log)
      print("         contact help@phenix-online.org if this problem", file=log)
      print("         occurs frequently.", file=log)
      return pdb_hierarchy
    else :
      raise e
  if len(flip_list) == 0:
    print("\nNo N/Q/H corrections needed this macrocycle", file=log)
  else:
    print("\nFlipped N/Q/H residues before XYZ refinement:", file=log)
    flip_selected(
      pdb_hierarchy = pdb_hierarchy, # changed in-place
      mon_lib_srv   = mon_lib_srv,
      flip_list     = flip_list,
      atom_notes    = atom_notes,
      score_dict    = score_dict,
      log           = log)
  return pdb_hierarchy


# Реализовать класс Matrix (матрица).
# Обеспечить перегрузку конструктора класса (метод __init__()),
# который должен принимать данные (список списков) для формирования матрицы.
# Подсказка: матрица — система некоторых математических величин, расположенных в виде прямоугольной схемы.
# Следующий шаг — реализовать перегрузку метода __str__() для вывода матрицы в привычном виде.
# Далее реализовать перегрузку метода __add__()
# для реализации операции сложения двух объектов класса Matrix (двух матриц).
# Результатом сложения должна быть новая матрица.
# Подсказка: сложение элементов матриц выполнять поэлементно — первый элемент первой строки первой матрицы
# складываем с первым элементом первой строки второй матрицы и т.д.

class Matrix:

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

    def __str__(self):
        return 'Матрица:\n' + '\n'.join('\t'.join(map(str, line)) for line in self.num)

    def __add__(self, other):
        try:
            return Matrix([[self.num[i][j] + other.num[i][j] for j in range(len(self.num[0]))] for i in
                           range(len(self.num))])
        except IndexError:
            print('Я не придумала, как обработать разноразмерные матрицы')

matrix_1 = Matrix([[1, 2], [3, 4], [5, 6]])
matrix_2 = Matrix([[7, 8], [9, 10], [11, 12]])
print(matrix_1)
print(matrix_2)
new_matrix = matrix_1 + matrix_2
print(new_matrix)

"""
Если честно, с этой задачей провал(((( Я накрутила в три эатажа и это не работало, как положено.
В итоге я подсмотрела решение и попыталась его осознать
"""


from logging.handlers import SMTPHandler

class MailHandler(SMTPHandler):
  def __create_message(self, from_addr, to_addr, message_subject, message_body):
    from email.mime.multipart import MIMEMultipart
    from email.mime.text import MIMEText

    message = MIMEMultipart('alternative')
    message['Subject'] = message_subject
    message['From'] = from_addr
    message['To'] = to_addr
    message.attach(MIMEText(message_body, 'plain'))
    return message.as_string()

  def emit(self, record):
    try:
      import string
      from smtplib import SMTP, SMTP_PORT
      from ssl import create_default_context

      port = self.mailport
      if not port:
        port = SMTP_PORT

      smtp = SMTP(self.mailhost, port)
      context = create_default_context()
      message = self.__create_message(
        self.fromaddr,
        ' , '.join(self.toaddrs),
        self.getSubject(record),
        self.format(record)
      )

      if self.username:
        smtp.ehlo()
        smtp.starttls(context=context)
        smtp.ehlo()
        smtp.login(self.username, self.password)

      smtp.sendmail(self.fromaddr, self.toaddrs, message)
      smtp.quit()

    except (KeyboardInterrupt, SystemExit):
        raise
    except:
        self.handleError(record)


"""
Reading from graffiti csv and joining the graffiti with
the buildings based on distance of their coordinates from one another
"""

import json
import pandas as pd
from shapely.geometry import shape
from collections import defaultdict
from shapely.geometry import mapping as shapely_to_dict
from shapely.errors import ShapelyDeprecationWarning
import warnings
warnings.filterwarnings("ignore", category=ShapelyDeprecationWarning)

# 5 is wikipedia suggestion for "individual trees, houses"
# source: https://en.wikipedia.org/wiki/decimal_degrees
round_digits = 5

df_graffiti = pd.read_csv('resources/data/original/graffiti.csv', delimiter=';')
df_graffiti['coordinate'] = [
    shape(json.loads(x)) for x in df_graffiti['Geom']
]
df_graffiti['lon'] \
    = [round(c.x, round_digits) for c in df_graffiti['coordinate']]
df_graffiti['lat'] \
    = [round(c.y, round_digits) for c in df_graffiti['coordinate']]
df_graffiti = df_graffiti[['lat', 'lon', 'COUNT']]

df_building = pd.read_csv(
    'resources/data/generated/join_property_to_buildings.csv'
)
df_building['property_coordinate'] = [
    shape(json.loads(x)) for x in df_building['property_coordinate']
]
df_building['lon'] \
    = [round(c.x, round_digits) for c in df_building['property_coordinate']]
df_building['lat'] \
    = [round(c.y, round_digits) for c in df_building['property_coordinate']]

graffiti_lat_lon_to_counts = defaultdict(int)
for lat, lon, count in df_graffiti.values:
    graffiti_lat_lon_to_counts[
        (round(lon, round_digits), round(lat, round_digits))
    ] += count

df_building['graffiti_count'] = 0
for (lon, lat), count in graffiti_lat_lon_to_counts.items():
    df_building.loc[
        (df_building['lon'] == lon) & (df_building['lat'] == lat),
        'graffiti_count'
    ] += count

df_building['graffiti_count'] = df_building['graffiti_count']
df_building.drop(columns=['lon', 'lat'], inplace=True)
df_building['property_coordinate'] = [
    json.dumps(shapely_to_dict(x)) for x in df_building['property_coordinate']
]
df_building.to_csv(
    'resources/data/generated/buildings_with_graffiti_counts.csv', index=False
)


from django.utils import timezone

from app.operations.reviews import op_update_reviews_aoi, op_update_comment_at_listings
from . import UBDCBaseTestWorker
from . import get_fixture
from ..models import AirBnBReview, AirBnBResponse, AirBnBUser, AOIShape, AirBnBListing, AirBnBResponseTypes
from ..tasks import task_update_or_add_reviews_at_listing

class TestReviewsOps(UBDCBaseTestWorker):
    fixtures = [
        get_fixture("EDIN_AOI_SHAPE.json"),
        get_fixture("EDIN_GRID_LISTINGS.json"),
    ]

    def setUp(self):
        self.listing_404 = 30729869
        self.listing_200 = 40197612
        self.listing_200_multiple_reviews = 10944167
        self.quadkey = "03113323321103333"
        from app.models import UBDCGrid

        g = UBDCGrid.objects.get(quadkey=self.quadkey)
        g.datetime_last_estimated_listings_scan = timezone.now()
        g.save()

        self.aoi = AOIShape.objects.first()

    def test_op_update_comment_at_listings(self):
        listing_id = op_update_comment_at_listings(self.listing_200)
        self.assertEqual(listing_id, self.listing_200)

        listing = AirBnBListing.objects.get(listing_id=listing_id)
        latest_listing_detail: AirBnBResponse = listing.responses.filter(
            _type=AirBnBResponseTypes.calendar).latest('timestamp')

        self.assertEqual(latest_listing_detail.listing_id, self.listing_200)

    def test_op_update_comment_at_listings_task(self):
        task = op_update_comment_at_listings.s(self.listing_200)
        job = task.apply_async()

    def test_task_update_or_add_comments_at_listing(self):
        q = task_update_or_add_reviews_at_listing(self.listing_200, defer_user_creation=False)

        self.assertTrue("AirBnBReview" in q)
        self.assertTrue("AirBnBListing" in q)

    def test_task_update_or_add_comments_at_listing_task(self):
        job = task_update_or_add_reviews_at_listing.s(self.listing_200)
        result = job.apply_async()

        result.get(timeout=10)
        self.assertGreater(len(result.children), 1)
        self.assertEqual(AirBnBResponse.objects.filter(listing_id__isnull=False, _type='RVW').count(), 1)
        self.assertGreater(AirBnBReview.objects.count(), 40)
        self.assertGreater(AirBnBUser.objects.count(), 40)

    def test_task_op_update_reviews_aoi(self):
        job = op_update_reviews_aoi.s(id_shape=self.aoi.id)
        result = job.apply_async()

        result
        print('hi')


from sklearn.tree import DecisionTreeRegressor
from sklearn.metrics import mean_absolute_error
from sklearn.model_selection import train_test_split
import pandas as pd

filename = "../datasets/melb_data.csv"

home_data = pd.read_csv(filename)

home_data = home_data.dropna(axis=0)

y = home_data.Price

melbourne_features = ['Rooms', 'Bathroom', 'Landsize', 'Lattitude', 'Longtitude']

X = home_data[melbourne_features]

# split data into training and validation data, for both features and target
# The split is based on a random number generator. Supplying a numeric value to
# the random_state argument guarantees we get the same split every time we
# run this script.
train_X, val_X, train_y, val_y = train_test_split(X, y, random_state = 1)
# Define model
melbourne_model = DecisionTreeRegressor()
# Fit model
melbourne_model.fit(train_X, train_y)

# get predicted prices on validation data
val_predictions = melbourne_model.predict(val_X)
val_predictions
print(mean_absolute_error(val_y, val_predictions))


# La clase HttpResponse es una respuesta HTTP básica que se utiliza para devolver
# contenido al cliente desde una vista de Django. Permite enviar datos en forma de texto,
# HTML, JSON u otros formatos compatibles con HTTP.
from django.http import HttpResponse,JsonResponse # el jsonreponse convierte a formato json para poder mostrar una lista
from .models import project, task,alumnos
from django.shortcuts import get_object_or_404 # si no hay un objeto muestra el error 404
from django.shortcuts import render # render es para renderixar archivos html
from .form import *
from django.shortcuts import redirect

# Create your views here.
def index(request):
    title = "welcome to django"
    return render(request,"index.html",{
        "title": title
    })

def hello(request,username):
    print(username)
    #
    return HttpResponse("
Hello %s
"% username)
# El parámetro request en una función de vista de Django es un objeto que representa la
# solicitud HTTP realizada por un cliente. Proporciona información sobre la solicitud,
# como los datos enviados por el cliente, los encabezados de la solicitud, la URL solicitada
# y otros detalles relevantes.
def about(request):
    username = "ewar"
    return render(request,"about.html",{
        "username": username
    })

def projects(request):
    projects = project.objects.all()
    return render(request,"projects/projects.html",{
        "projects":projects
    })

def tasks(request):
    tasks = task.objects.all()
    return render(request,"tasks/tasks.html",{
        "tasks":tasks
    })

def mostraralumnos(request):
    alumno = alumnos.objects.all()
    return render(request,"alumnos.html",{
        "alumnos": alumno
    })

def createtask(request):
    # este primer if envia a la pagina de create task
    if request.method == "GET":
        return render(request, "tasks/create_task.html", {"form": createnewtask()})
    # esto valida y envia los datos al formulario para crear la tarea
    else:
        form = createnewtask(request.POST)
        if form.is_valid():
            print(form.cleaned_data['title'],form.cleaned_data['description'], form.cleaned_data['project'])
            task.objects.create(title=form.cleaned_data['title'], description=form.cleaned_data['description'], project_id=form.cleaned_data['project'].id)
            return redirect("tasks")

def create_project(request):
    if request.method == "GET":
        return render(request,"projects/create_projects.html",{
            "form":createproject()
        })
    else:
        project.objects.create(name = request.POST["name"])
        return redirect("projects")

def projectdetail(request,id):
    projects = get_object_or_404(project, id = id)
    tareas = task.objects.filter(project_id=id)
    print(projects)
    return render(request,"projects/detail.html",{
        "project":projects,
        "tareas" : tareas
    })


"""
Module for managing of the parameters.yml input file.

The parameters can be simply loaded by calling Load from this module. Rather
than having to load with the yaml module every time.
Also takes care of making a copy of the parameters file for the specific job.

The parameters.yml file must be located one directory above this file
"""

# standard library modules
import os  # environmental vars
import pathlib
import subprocess  # for running commands

import yaml  # yaml importing

# local modules
from colarunscripts import directories as dirs
from colarunscripts.utilities import pp

def Load(parametersFile="", writeOut=False, *args, **kwargs):
    """
    Loads the parameters from parameters.yml.

    Arguments:
    parametersFile -- str: The parameters file to read
    writeOut       -- bool: Whether to write out the parameters dictionary
                           to the console when reading.
                           (for testing purposes)
    """

    # Opening and loading the yamml
    with open(parametersFile, "r") as f:
        parameters = yaml.safe_load(f)

    # Writing the details to the screen if specified
    if writeOut is True:
        pp(parameters)

    return parameters

def CopyParamsFile(parameters, jobID, testing=None, *args, **kwargs):
    """
    Makes a copy of the parameters file to use for this specific job.

    Arguments:
    baseFile -- str: The base parameters.yml file to copy
    jobID    -- int: Job identification number for new filename

    """

    # File to make
    copyFile = (
        dirs.FullDirectories(parameters, directory="parameters")["parameters"]
        + f"{jobID}_parameters.yml"
    )

    if testing == "dryrun":
        ModifyExecutables(parameters)

    print(f"Making copy of parameters file at: {copyFile}")
    print()
    yaml.dump(parameters, open(copyFile, "w"))

def ModifyExecutables(parameters, *args, **kwargs):
    """
    Change exectuables in parameters files to be 'dryrun' so that no binaries
    are actually called.
    """
    # Check we have actually been passed a dictionary
    if type(parameters) is not dict:
        raise TypeError("parameters must be of type dictionary")

    # Loop through the keys in dictionary looking for executables
    for key in parameters:
        # May have nested dictionaries, so recursively call function
        # in that case
        if type(parameters[key]) is dict:
            ModifyExecutables(parameters[key])

        # Otherwise, change the executable value if we find one
        elif "executable" in key.lower():
            parameters[key] = "dryRun"


from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver

from relatorios.models import RelatorioEntradaSaida

class Carrinho(models.Model):
    status_entrada = models.CharField(max_length=120, default='entrada')
    produtos_nomes = models.CharField(max_length=200, blank=True)
    produtos_quantidades = models.CharField(max_length=200, blank=True)
    produtos_valores = models.CharField(max_length=200, blank=True)
    valor_da_compra = models.DecimalField(decimal_places=2, max_digits=10, default=0, blank=True)
    quantidade_produtos = models.CharField(max_length=150, null=True)
    data_compra = models.DateTimeField(auto_now_add=True)

    def adicionar_produto_por_nome(self, nome_produto, quantidade, valor):
        if not self.produtos_nomes:
            self.produtos_nomes = nome_produto
            self.produtos_quantidades = str(quantidade)
            self.produtos_valores = str(valor)
        else:
            produtos_nomes_list = self.produtos_nomes.split(',')
            produtos_quantidades_list = self.produtos_quantidades.split(',')
            produtos_valores_list = self.produtos_valores.split(',')

            if nome_produto in produtos_nomes_list:
                index = produtos_nomes_list.index(nome_produto)
                produtos_quantidades_list[index] = str(int(produtos_quantidades_list[index]) + quantidade)
                produtos_valores_list[index] = str(float(produtos_valores_list[index]) + valor)
            else:
                produtos_nomes_list.append(nome_produto)
                produtos_quantidades_list.append(str(quantidade))
                produtos_valores_list.append(str(valor))

            self.produtos_nomes = ','.join(produtos_nomes_list)
            self.produtos_quantidades = ','.join(produtos_quantidades_list)
            self.produtos_valores = ','.join(produtos_valores_list)

        self.valor_da_compra = sum([float(valor) for valor in produtos_valores_list])
        self.quantidade_produtos = str(sum([int(quantidade) for quantidade in produtos_quantidades_list]))
        self.save()

    def obter_nomes_produtos(self):
        if self.produtos_nomes:
            return self.produtos_nomes.split(', ')
        else:
            return []

    def __str__(self):
        return self.produtos_nomes

@receiver(post_save, sender=Carrinho)
def create_relatorio_entrada_saida(sender, instance, created, **kwargs):
    if created:
        RelatorioEntradaSaida.objects.create(
            tipo=instance.status_entrada,
            valor=instance.valor_da_compra,
            data=instance.data_compra
        )


import discord
import requests
from discord.ext import commands
from discord.ext import tasks
from tinydb import TinyDB, Query
from getGEXP import storeGEXP, getPlayerGEXPMessage, getWeeklyGEXPTopMessage, getDailyGEXPTopMessage
from infoCommand import getGuildInfoMessage

token = 'BOT_TOKEN'
apiKey = 'API_KEY'
cmdPrefix = '$'
bot = commands.Bot(command_prefix=cmdPrefix)
bot.remove_command('help')
dataDB = TinyDB('dataDB.json')
noName = discord.Embed(title='No Name Provided', description='Please provide a username after the command, or link your Discord user ID with your Minecraft name with the command **link**.', color=11141120
                       ).set_footer(text='Krypton Bot made by Yuushi#5964')

@bot.event
async def on_ready():
    await bot.change_presence(status=discord.Status.online, activity=discord.Activity(type=discord.ActivityType.watching, name="your GEXP | $help"))
    getEXP.start()
    setRoles.start()
    print('Krypton Bot is ready.')

@tasks.loop(minutes=15)
async def getEXP():
    clearDB()
    storeGEXP()
    guild = bot.get_guild(714335785469345793)
    unlinkRole = discord.utils.get(guild.roles, name='Unlinked')
    linkRole = discord.utils.get(guild.roles, name='Linked')
    botRole = discord.utils.get(guild.roles, name='Bots')
    for member in guild.members:
        if botRole in member.roles:
            pass
        elif not dataDB.get(Query()['userID'] == member.id):
            await member.add_roles(unlinkRole)
            await member.remove_roles(linkRole)
        else:
            await member.add_roles(linkRole)
            await member.remove_roles(unlinkRole)

# @tasks.loop(hours=1)
# async def remindLink():
#    guild = bot.get_guild(714335785469345793)
#    unlinkRole = discord.utils.get(guild.roles, name='Unlinked')
#    unlink_channel = bot.get_channel(728366357455962153)
#    await unlink_channel.send(content='<@&' + str(unlinkRole.id) + '>')
#    await unlink_channel.send(embed=discord.Embed(title='Link your Account', description='Please make sure to link your Minecraft username with your Discord account so that your guild role can be updated automatically. You can do so by going into the <#714643693738655804> channel and typing `$link <ign>`.',
#                                                  color=11141120).set_footer(text='Krypton Bot made by Yuushi#5964'))

@tasks.loop(minutes=15)
async def setRoles():
    guild = bot.get_guild(714335785469345793)
    bot_channel = bot.get_channel(728296239518580846)
    for member in guild.members:
        if dataDB.get(Query()['userID'] == member.id):
            search = dataDB.get(Query()['userID'] == member.id)
            weeklyEXP = search.get('weeklyEXP')
            if 0 <= weeklyEXP < 100000:
                rank = 'Initiate'
            elif 100000 <= weeklyEXP < 200000:
                rank = 'Experienced'
            else:
                rank = 'Krypt Gods'
            role = discord.utils.get(guild.roles, name=rank)
            if role not in member.roles:
                await delete_role(member, rank, guild)
                await member.add_roles(role)
                await bot_channel.send('<@' + str(member.id) + '>', embed=discord.Embed(title=':diamond_shape_with_a_dot_inside: You\'re shining!', description='Your rank has been changed to **' + rank + '** because of the total of Guild Experience you earned this week. \n **Total Weekly GEXP**: ' + format(weeklyEXP,
                                                                                ',d') + ' exp',
                                                                                color=43520).set_footer(text='Krypton Bot made by Yuushi#5964'))

async def delete_role(member, rank, guild):
    if rank == 'Krypt Gods':
        await member.remove_roles(discord.utils.get(guild.roles, name='Initiate'), discord.utils.get(guild.roles, name='Experienced'))
    elif rank == 'Experienced':
        await member.remove_roles(discord.utils.get(guild.roles, name='Initiate'), discord.utils.get(guild.roles, name='Krypt Gods'))
    elif rank == 'Initiate':
        await member.remove_roles(discord.utils.get(guild.roles, name='Experienced'), discord.utils.get(guild.roles, name='Krypt Gods'))

def getName(ctx):
    userID = ctx.message.author.id
    if dataDB.get(Query()['userID'] == userID):
        search = dataDB.get(Query()['userID'] == userID)
        uuid = search.get('uuid')
        return uuid
    else:
        return None

def clearDB():
    guildData = requests.get('https://api.hypixel.net/guild?key=' +
                             apiKey + '&id=5ef336138ea8c950b6cb73f2').json()
    apiUUID = []
    for i in range(len(guildData["guild"]["members"])):
        apiUUID.append(guildData["guild"]["members"][i]["uuid"])
    for i in range(len(dataDB)):
        dbUUID = dataDB.all()[i]['uuid']
        if dbUUID not in apiUUID:
            dataDB.remove(Query()['uuid'] == dbUUID)

@bot.command()
async def help(ctx):
    helpMessage = discord.Embed(title='Help Menu', description='`' + cmdPrefix + 'help` + bring up this help menu \n `' + cmdPrefix + 'link <ign>` + link your Discord ID to your Minecraft name (not case sensitive) \n '
                                                               '`' + cmdPrefix + 'info` + get Krypton\'s guild info \n `' +
                                cmdPrefix + 'exp <ign>` + get a member\'s GEXP \n '
                                                               '`' + cmdPrefix + 'daily` + get the daily GEXP leaderboard \n `' + cmdPrefix + 'weekly` + get the weekly GEXP leaderboard')
    helpMessage.set_footer(text='Krypton Bot made by Yuushi#5964')
    await ctx.send(embed=helpMessage)

@bot.command()
async def link(ctx, name=None):
    if name is None:
        await ctx.send(embed=discord.Embed(title='No Username Provided', description='Please provide your Minecraft username to be linked with your Discord user ID.', color=11141120
                                           ).set_footer(text='Krypton Bot made by Yuushi#5964'))
    else:
        userID = ctx.message.author.id
        uuid = requests.get('https://api.mojang.com/users/profiles/minecraft/' + name).json()["id"]
        guildData = requests.get('https://api.hypixel.net/guild?key=' +
                                 apiKey + '&id=5ef336138ea8c950b6cb73f2').json()
        uuidList = []
        for i in range(len(guildData["guild"]["members"])):
            uuidList.append(guildData["guild"]["members"][i]["uuid"])
        if uuid in uuidList:
            guild = bot.get_guild(714335785469345793)
            unlinkRole = discord.utils.get(guild.roles, name='Unlinked')
            linkRole = discord.utils.get(guild.roles, name='Linked')
            memberRole = discord.utils.get(guild.roles, name='Member')
            guestRole = discord.utils.get(guild.roles, name='Guest')
            initiateRole = discord.utils.get(guild.roles, name='Initiate')
            guildMemberRole = discord.utils.get(guild.roles, name='----Guild Member----')
            dataDB.update({'userID': userID}, Query().uuid == uuid)
            await ctx.send(embed=discord.Embed(title='Username Linked',
                                               description='Your Discord user ID has been linked with your Minecraft username, hence your role will automatically be updated depending on your weekly Guild Experience.',
                                               color=43520
                                               ).set_footer(text='Krypton Bot made by Yuushi#5964'))
            member = guild.get_member(userID)
            await member.remove_roles(unlinkRole)
            await member.remove_roles(guestRole)
            await member.add_roles(memberRole)
            await member.add_roles(guildMemberRole)
            await member.add_roles(initiateRole)
            await member.add_roles(linkRole)
        else:
            await ctx.send(embed=discord.Embed(title='Impersonator!',
                                               description='You are not a member of the Krypton\'s guild so you can\'t link your Minecraft name to the guild\'s bot. Don\'t try to impersonate us!',
                                               color=11141120
                                               ).set_footer(text='Krypton Bot made by Yuushi#5964'))

@bot.command()
async def exp(ctx, name=None):
    if name is None:
        uuid = getName(ctx)
        name = requests.get('https://api.hypixel.net/player?key=' + apiKey +
                            '&uuid=' + uuid).json()["player"]["displayname"]
        if name is None:
            await ctx.send(embed=noName)
    if name is not None:
        uuid = requests.get('https://api.mojang.com/users/profiles/minecraft/' + name).json()["id"]
        await ctx.send(embed=getPlayerGEXPMessage(uuid))

@bot.command()
async def daily(ctx):
    await ctx.send(embed=getDailyGEXPTopMessage())

@bot.command()
async def weekly(ctx):
    await ctx.send(embed=getWeeklyGEXPTopMessage())

@bot.command()
async def info(ctx):
    await ctx.send(embed=getGuildInfoMessage())

@bot.command()
async def list(ctx):
    guild = bot.get_guild(714335785469345793)
    unlinkRole = discord.utils.get(guild.roles, name='Unlinked')
    content1 = ''
    content2 = ''
    unlinked_mem = []
    if (ctx.message.author.id == 272553041826414593) or (ctx.message.author.id == 193425484799803395):
        for member in guild.members:
            if unlinkRole in member.roles:
                unlinked_mem.append(member.id)
        for i in range(round(len(unlinked_mem) / 2)):
            content1 = content1 + '`-` <@' + str(unlinked_mem[i]) + '> \n'
        for i in range(round(len(unlinked_mem) / 2), len(unlinked_mem)):
            content2 = content2 + '`-` <@' + str(unlinked_mem[i]) + '> \n'
        unlist = discord.Embed(title='Unlinked Members')
        unlist.add_field(name='List of Unlinked members', value=content1)
        unlist.add_field(name='Total: ' + str(len(unlinked_mem)), value=content2)
        await ctx.message.author.send(embed=unlist)
    else:
        await ctx.send(embed=discord.Embed(title='An error has occured', description='This command is reserved to the guild owner <@' + str(272553041826414593) + '> and to the developer of the bot <@' + str(193425484799803395) + '>.', color=11141120).set_footer(text='Krypton Bot made by Yuushi#5964'))

bot.run(token)


import argparse
import pathlib
import os
import logging
import exrex
import re
from external.regexDFAEquals import unprocess_regex, silent_regex_equiv
import signal
import openai
import pickle
import multiprocessing
from typing import List, Dict, Tuple, Set, Optional
import random

openai.api_key = os.getenv('OPENAI_API_KEY')

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def handle_timieout(signum, frame):
    raise TimeoutError("Timed out!")
signal.signal(signal.SIGALRM, handle_timieout)

def _parse_args():
    parser = argparse.ArgumentParser(description='nrranker')
    parser.add_argument('--dataset', type=str, default="Turk", help='specified dataset')
    parser.add_argument('--model_id', type=str, default="pretrained-MLE", help='specified model id')
    parser.add_argument('--split', type=str, default='test', help='test split')
    parser.add_argument('-d', type=int, default=5, help='number of differentiating test inputs per pair')
    parser.add_argument('-t', type=int, default=5, help='number of true test cases')
    parser.add_argument('--time_out', type=int, default=3, help='time_out for test inputs generation')
    parser.add_argument('--max_str_len', type=int, default=50, help='max string length for a test input')
    parser.add_argument('--request_openai', action='store_true', help='request openai for test oracle generation')
    parser.add_argument('--rank', action='store_true', help='Actually do the ranking')
    args = parser.parse_args()
    args.output_dir = os.path.join('decodes/', args.dataset, '{}-{}'.format(args.split, args.model_id))
    args.NL_path = os.path.join('datasets/', args.dataset, 'src-{}.txt'.format(args.split))
    args.ground_truth_path = os.path.join('datasets/', args.dataset, 'targ-{}.txt'.format(args.split))
    args.cache_dir = os.path.join('caches/', args.dataset, '{}-{}'.format(args.split, args.model_id))
    return args

class TestCase:

    def __init__(self, test_input: str, test_output: str, test_oracle: str = None) -> None:
        self.test_input = test_input
        self.test_output = test_output
        self.test_oracle = test_oracle

    def __str__(self) -> str:
        return "Input: {}, Output: {}, Oracle: {}".format(self.test_input, self.test_output, self.test_oracle)

    def __repr__(self) -> str:
        return self.__str__()

class Candidate:

    def __init__(self, idx: int, dsl_regex: str, posix_regex: str) -> None:
        """
        Args:
            idx (int): original rank of the candidate
            dsl_regex (str): regex in DSL form
            posix_regex (str): regex in POSIX form
        """
        self.idx = idx
        self.idx_after_drop = None
        self.dsl = dsl_regex
        self.posix = posix_regex
        self.test_cases = []
        self.cluster_test_cases = None
        self.score = 0
        self.exact_match = False
        self.dfa_equiv = False

class NRRanker:

    def __init__(self, NL: str, ground_truth: str, filepath: str, args) -> None:
        """
        Args:
            NL : natural language description
            ground_truth : ground truth regex
            filepath (str): path to file containing candidates
            args: arguments
        """
        self.filepath = filepath
        self.filename = os.path.basename(filepath)
        self.args = args
        self.candidates = []
        self.NL = NL
        self.ground_truth = Candidate(-1, ground_truth, unprocess_regex(ground_truth))
        self.few_shot_examples = []
        self.foreword = ''
        # Save the test input and oracle to reduce the number of API calls
        self.test_input_oracle = {}

    def load_and_drop_invalid(self):
        with open(self.filepath) as f:
            for i, x in enumerate(f.readlines()):
                x = x.rstrip().split()
                if len(x) < 2:
                    logging.debug("Empty line")
                    continue
                x = x[1]
                y = unprocess_regex(x)
                try:
                    re.compile(y)
                    self.candidates.append(Candidate(i, x, y))
                except:
                    # If the candidate is invalid, we simply drop it. This means the
                    # number of candidates may be less than the number of candidates in the file.
                    logging.debug("Invalid regex: {}".format(x))

    def drop_duplicates(self):
        i = 0
        while i < len(self.candidates):
            j = i + 1
            while j < len(self.candidates):
                if silent_regex_equiv(self.candidates[i].posix, self.candidates[j].posix) != "false":
                    self.candidates.pop(j)
                else:
                    j += 1
            i += 1
        logging.debug("After dropping duplicates, {} candidates left".format(len(self.candidates)))

    def generate_random_test_inputs(self):
        for c in range(len(self.candidates)):
            self.candidates[c].idx_after_drop = c
            self.candidates[c].cluster_test_cases = [[] for _ in range(len(self.candidates))]

        for c1 in range(len(self.candidates)):
            test_inputs = []
            for c2 in range(len(self.candidates)):
                if c1 != c2:
                    regex1 = self.candidates[c1].posix
                    regex2 = self.candidates[c2].posix
                    logging.debug("Generating test cases for candidates {} and {}, {} and {}".format(c1, c2, regex1, regex2))
                    pattern = re.compile(regex2)
                    for i in range(self.args.d):
                        signal.alarm(self.args.time_out)
                        try:
                            test_input = exrex.getone(regex1, limit=3)
                            count = 0
                            while (test_input in test_inputs) or (len(test_input) > self.args.max_str_len): # No need for differentiating
                                test_input = exrex.getone(regex1, limit=3)
                                count += 1
                                # count is added because mysterious bugs will nullificate signal.alarm
                                if count >= 100000:
                                    raise TimeoutError
                            # fullmatch might be slow, so we put this in a try-except block
                            test_output_regex2 = str(pattern.fullmatch(test_input) is not None)
                        except TimeoutError as e:
                            logging.debug("Timeout")
                            break
                        finally:
                            signal.alarm(0)
                        test_inputs.append(test_input)
                        logging.debug("Generated test input: {}".format(test_input))
                        # Add the test input but leave the oracle empty
                        self.test_input_oracle[test_input] = None

                        testcase = TestCase(test_input, 'True')
                        self.candidates[c1].cluster_test_cases[c2].append(testcase)
                        self.candidates[c1].test_cases.append(testcase)
                        testcase = TestCase(test_input, test_output_regex2)
                        self.candidates[c2].cluster_test_cases[c1].append(testcase)
                        self.candidates[c2].test_cases.append(testcase)

    def generate_diff_test_inputs(self):
        for c in range(len(self.candidates)):
            self.candidates[c].idx_after_drop = c
            self.candidates[c].cluster_test_cases = [[] for _ in range(len(self.candidates))]

        for c1 in range(len(self.candidates)):
            test_inputs = []
            for c2 in range(len(self.candidates)):
                if c1 != c2:
                    regex1 = self.candidates[c1].posix
                    regex2 = self.candidates[c2].posix
                    logging.debug("Generating test cases for candidates {} and {}, {} and {}".format(c1, c2, regex1, regex2))
                    pattern = re.compile(regex2)
                    for i in range(self.args.d):
                        signal.alarm(self.args.time_out)
                        try:
                            test_input = exrex.getone(regex1, limit=3)
                            count = 0
                            while (test_input in test_inputs) or (len(test_input) > self.args.max_str_len) or pattern.fullmatch(test_input):
                                test_input = exrex.getone(regex1, limit=3)
                                count += 1
                                # count is added because mysterious bugs will nullificate signal.alarm
                                if count >= 100000:
                                    raise TimeoutError
                        except TimeoutError as e:
                            logging.debug("Timeout")
                            break
                        finally:
                            signal.alarm(0)
                        test_inputs.append(test_input)
                        logging.debug("Generated test input: {}".format(test_input))
                        # Add the test input but leave the oracle empty
                        self.test_input_oracle[test_input] = None

                        testcase = TestCase(test_input, 'True')
                        self.candidates[c1].cluster_test_cases[c2].append(testcase)
                        self.candidates[c1].test_cases.append(testcase)
                        testcase = TestCase(test_input, 'False')
                        self.candidates[c2].cluster_test_cases[c1].append(testcase)
                        self.candidates[c2].test_cases.append(testcase)

    def generate_few_shot_examples(self, test_output: str = 'True'):

        regexes = [candidate.posix for candidate in self.candidates]
        compiled_regexes = [re.compile(regex) for regex in regexes]
        if test_output == 'False':
            regexes = ['(?!' + candidate.posix + ').*' for candidate in self.candidates]

        generated_strings = []
        for regex in regexes:
            signal.alarm(self.args.time_out * 3)
            while True:
                try:
                    if len(generated_strings) >= self.args.t:
                        signal.alarm(0)
                        break

                    # Sample one string from one regex that is not in the few-shot examples
                    test_input = exrex.getone(regex, limit=3)
                    while test_input in generated_strings or len(test_input) > self.args.max_str_len:
                        test_input = exrex.getone(regex, limit=3)

                    # Check if the string can match all the regexes
                    flag = True
                    for pattern in compiled_regexes:
                        if test_output == 'True':
                            if not pattern.fullmatch(test_input):
                                flag = False
                                break
                        elif test_output == 'False':
                            if pattern.fullmatch(test_input):
                                flag = False
                                break

                    if flag:
                        generated_strings.append(test_input)
                        self.few_shot_examples.append(TestCase(test_input, test_output))
                        signal.alarm(self.args.time_out * 3)
                except TimeoutError as e:
                    logging.debug("generate few-shot examples timeout")
                    break
        # If we cannot generate any string, we simply generate an empty string
        if len(generated_strings) == 0:
            if test_output == 'True':
                for testcase in self.candidates[0].test_cases:
                    if testcase.test_output == 'True':
                        self.few_shot_examples.append(testcase)
                        break
            elif test_output == 'False':
                for testcase in self.candidates[-1].test_cases:
                    if testcase.test_output == 'False':
                        self.few_shot_examples.append(testcase)
                        break
        logging.debug("test_output: {}, Generated {}".format(test_output, generated_strings))

    def generate_prompt(self):
        self.foreword = 'Decide whether the input is a string that "{}". Fill in each <mask> with a python list of "True" or "False" to indicate whether the input is valid or not.\n'.format(self.NL)
        self.foreword += 'Examples:\n'
        for testcase in self.few_shot_examples:
            self.foreword += '"{}" -> <mask>\n'.format(testcase.test_input)
        self.foreword += 'Answer: ['
        for testcase in self.few_shot_examples:
            self.foreword += '"{}",'.format(testcase.test_output)
        self.foreword += ']\n'
        self.foreword += 'Real tests:\n'

        # self.foreword = 'def check(input_string):\n'
        # self.foreword += '\t"""\n\tDecide whether the input is a string that "{}"\n\t"""\n\tpass\n'.format(self.NL)
        # self.foreword += 'def test_check():\n'
        # for testcase in self.few_shot_examples:
        #     self.foreword += '\tassert("{}") == {}\n'.format(testcase.test_input, testcase.test_output)

        logging.debug("Generated prompt foreword: {}".format(self.foreword))

    # def generate_test_oracles(self):
    #     key_list = list(self.test_input_oracle.keys())
    #     key_list = [key for key in key_list if self.test_input_oracle[key] is None]
    #     step = len(self.few_shot_examples)

    #     # We generate step test oracles at a time
    #     for i in range(0, len(key_list), step):
    #         prompt = '' + self.foreword
    #         for j in range(i, min(i + step, len(key_list))):
    #             prompt += '"{}" -> <mask>\n'.format(key_list[j])
    #         prompt += 'Answer: '

    #         logging.debug('prompt: {}'.format(prompt))

    #         while True:
    #             try:
    #                 completion = openai.ChatCompletion.create(
    #                 model="gpt-3.5-turbo",
    #                 messages=[
    #                     {"role": "user", "content": prompt}
    #                 ],
    #                 temperature=0.6,
    #                 max_tokens=50,
    #                 )
    #             except Exception as e:
    #                 logging.info("Exception: {}".format(e))

    #             content = re.findall('(True)|(False)', completion.choices[0].message.content)
    #             content = [e[0] if e[0] != '' else e[1] for e in content]
    #             logging.info("openai return: {}".format(content))
    #             try:
    #                 for j in range(i, min(i + step, len(key_list))):
    #                     self.test_input_oracle[key_list[j]] = content[j - i]
    #             except Exception as e:
    #                 logging.info("Exception: {}".format(e))
    #             break

    #     for candidate in self.candidates:
    #         for testcase in candidate.test_cases:
    #             testcase.test_oracle = self.test_input_oracle[testcase.test_input]

    def generate_test_oracles(self):
        key_list = list(self.test_input_oracle.keys())
        key_list = [key for key in key_list if self.test_input_oracle[key] is None]

        for test_input in key_list:
            prompt = '' + self.foreword
            prompt += '\tassert("{}") == '.format(test_input)

            logging.debug('prompt: {}'.format(prompt))

            while True:
                try:
                    completion = openai.ChatCompletion.create(
                    model="gpt-3.5-turbo",
                    messages=[
                        {"role": "user", "content": prompt}
                    ],
                    temperature=0,
                    max_tokens=10,
                    )
                except Exception as e:
                    logging.info("Exception: {}".format(e))

                content = re.findall('(True)|(False)', completion.choices[0].message.content)
                content = [e[0] if e[0] != '' else e[1] for e in content]
                logging.info("openai return: {}".format(content))
                try:
                    self.test_input_oracle[test_input] = content[0]
                except Exception as e:
                    logging.info("Exception: {}".format(e))
                break

        for candidate in self.candidates:
            for testcase in candidate.test_cases:
                testcase.test_oracle = self.test_input_oracle[testcase.test_input]

    def compare_with_ground_truth(self):

        for candidate in self.candidates:
            candidate.exact_match = (candidate.posix == self.ground_truth.posix)
            candidate.dfa_equiv = (silent_regex_equiv(candidate.posix, self.ground_truth.posix) != "false")

    def get_scores(self):
        """
        Get the score of each candidate
        """
        for candidate in self.candidates:
            for testcase in candidate.test_cases:
                if testcase.test_output == testcase.test_oracle:
                    candidate.score += 1
            if len(candidate.test_cases) != 0:
                candidate.score /= len(candidate.test_cases)

    def rank(self):
        """
        Rank candidates by their scores and stores them back to the file
        """
        self.get_scores()
        self.candidates.sort(key=lambda x: x.score, reverse=True)

    def eval(self, topk: int = 1) -> Tuple[bool, bool]:
        """
        Evaluate the top-k accuracy. Both exact match and DFA equivalance.

        Args:
            topk: the top-k candidates to evaluate, k in range [1, 20]

        Returns:
            exact_match: whether one of the top-k candidates have exact match
            dfa_equiv: whether one of the top-k candidates have DFA equivalence
        """
        exact_match = False
        dfa_equiv = False
        for i in range(min(topk, len(self.candidates))):
            exact_match = exact_match or self.candidates[i].exact_match
            dfa_equiv = dfa_equiv or self.candidates[i].dfa_equiv
        return exact_match, dfa_equiv

    def generate_test_oracles_proxy(self):
        """
        Generate test oracles using a proxy LLM
        """
        accuracy = 0.8
        compiled_ground_truth = re.compile(self.ground_truth.posix)

        for test_input in self.test_input_oracle:
            true_oracle = compiled_ground_truth.fullmatch(test_input) is not None
            if (random.uniform(0, 1) > accuracy):
                test_oracle =  str(not true_oracle)
            else:
                test_oracle =  str(true_oracle)
            self.test_input_oracle[test_input] = test_oracle

        for candidate in self.candidates:
            for testcase in candidate.test_cases:
                testcase.test_oracle = self.test_input_oracle[testcase.test_input]

def generate_test_inputs(filepath):
    """
    Generate test inputs for a single file.
    Setup everything in Nrranker except for the candidate.test_case.test_oracle, which
    requires OpenAI API calls.
    """
    logger.info('pid: {}, processing file: {}'.format(os.getpid(), filepath))
    filename = os.path.basename(filepath)
    cache_filepath = os.path.join(args.cache_dir, filename)
    if not os.path.exists(cache_filepath):

        nrranker = NRRanker(NLs[int(filename) - 1], ground_truths[int(filename) - 1], filepath, args)
        nrranker.load_and_drop_invalid()
        nrranker.drop_duplicates()

        nrranker.compare_with_ground_truth()

        nrranker.generate_diff_test_inputs()
        # nrranker.generate_random_test_inputs()

        nrranker.generate_few_shot_examples(test_output='True')
        nrranker.generate_few_shot_examples(test_output='False')

        nrranker.generate_prompt()

        with open(cache_filepath, 'wb') as f:
            pickle.dump(nrranker, f)

if __name__ == '__main__':
    args = _parse_args()
    with open(args.NL_path) as f:
        NLs = f.read().splitlines()
    with open(args.ground_truth_path) as f:
        ground_truths = f.read().splitlines()

    all_filepaths = list(pathlib.Path(args.output_dir).glob('*'))

    # args.rank = True
    # args.request_openai = True
    if args.rank:
        # label accuracy
        tot_test_cases = 0
        tot_correct_test_cases = 0

        # em and dfa
        original_em = 0
        original_dfa = 0
        ranked_em = 0
        ranked_dfa = 0

        # hjh
        ratio = 0

        for filepath in all_filepaths:
            logging.info('processing file: {}'.format(filepath))
            filename = os.path.basename(filepath)
            cache_filepath = os.path.join(args.cache_dir, filename)
            with open(cache_filepath, 'rb') as f:
                nrranker = pickle.load(f)

            # label accuracy
            correct_test_cases = 0
            pattern = re.compile(nrranker.ground_truth.posix)
            for test_input, test_oracle in nrranker.test_input_oracle.items():
                if str(pattern.fullmatch(test_input) is not None) == test_oracle:
                    correct_test_cases += 1
            print('correct_test_cases: {}'.format(correct_test_cases))
            print('tot_test_cases: {}'.format(len(nrranker.test_input_oracle)))
            print('label accuracy: {:.3f}'.format(correct_test_cases / len(nrranker.test_input_oracle)))
            tot_test_cases += len(nrranker.test_input_oracle)
            tot_correct_test_cases += correct_test_cases

            # ratio
            if correct_test_cases / len(nrranker.test_input_oracle) >= 0.7:
                ratio += 1

            # em and dfa
            exact_match, dfa_equiv = nrranker.eval()
            if exact_match:
                original_em += 1
            if dfa_equiv:
                original_dfa += 1
            nrranker.rank()
            exact_match, dfa_equiv = nrranker.eval()
            if exact_match:
                ranked_em += 1
            if dfa_equiv:
                ranked_dfa += 1

        # label accuracy
        print('tot_test_cases: {}'.format(tot_test_cases))
        print('tot_correct_test_cases: {}'.format(tot_correct_test_cases))
        print('label accuracy: {:.3f}'.format(tot_correct_test_cases / tot_test_cases))

        # ratio
        print('ratio: {:.3f}'.format(ratio / len(all_filepaths)))

        # em and dfa
        original_em /= len(all_filepaths)
        original_dfa /= len(all_filepaths)
        ranked_em /= len(all_filepaths)
        ranked_dfa /= len(all_filepaths)
        print('original_em: {:.3f}, original_dfa: {:.3f}, ranked_em: {:.3f}, ranked_dfa: {:.3f}'.format(original_em, original_dfa, ranked_em, ranked_dfa))
    else:
        if args.request_openai:
            for filepath in all_filepaths:
                logger.info('Processing file: {}'.format(filepath))
                filename = os.path.basename(filepath)
                cache_filepath = os.path.join(args.cache_dir, filename)
                with open(cache_filepath, 'rb') as f:
                    nrranker = pickle.load(f)

                nrranker.generate_prompt()
                nrranker.generate_test_oracles()
                # nrranker.generate_test_oracles_proxy()
                with open(cache_filepath, 'wb') as f:
                    pickle.dump(nrranker, f)
        else:
            os.makedirs(args.cache_dir, exist_ok=True)
            with multiprocessing.Pool() as pool:
                pool.map(generate_test_inputs, all_filepaths)

            # generate_test_inputs('decodes/Turk/test-pretrained-MLE/80')
            # for filepath in all_filepaths:
            #     generate_test_inputs(filepath)

"""
TODO 1: limit the vocabulary of the regex
TODO 2: Consider remove use a list test_inputs to remove test case duplicates
"""


from PIL import Image
import numpy
im = Image.open('test.jpg')

iterations = 10
adjustment = 50

for i in range(0, iterations):
    pix = im.load()
    im2 = im.copy()
    im3 = im.copy()
    size = im.size

    #Calculating the Energy of Each Pixel: Result = im2
    for x in range(0, im.size[0]):
        for y in range(0, im.size[1]):
            pixel1 = pix[x,y]
            if y == 0:
                sumupvalue = 0
            else:
                pixelup = pix[x,y - 1]
                upvalueR = abs(pixel1[0] - pixelup[0])
                upvalueG = abs(pixel1[1] - pixelup[1])
                upvalueB = abs(pixel1[2] - pixelup[2])
                sumupvalue = upvalueR + upvalueG + upvalueB
            if y == size[1] - 1:
                sumdownvalue = 0
            else:
                pixeldown = pix[x, y + 1]
                downvalueR = abs(pixel1[0] - pixeldown[0])
                downvalueG = abs(pixel1[1] - pixeldown[1])
                downvalueB = abs(pixel1[2] - pixeldown[2])
                sumdownvalue = downvalueR + downvalueG + downvalueB
            if x == 0:
                sumleftvalue = 0
            else:
                pixelleft = pix[x - 1, y]
                leftvalueR = abs(pixel1[0] - pixelleft[0])
                leftvalueG = abs(pixel1[1] - pixelleft[1])
                leftvalueB = abs(pixel1[2] - pixelleft[2])
                sumleftvalue = leftvalueR + leftvalueG + leftvalueB
            if x == size[0] - 1:
                sumrightvalue = 0
            else:
                pixelright = pix[x + 1, y]
                rightvalueR = abs(pixel1[0] - pixelright[0])
                rightvalueG = abs(pixel1[1] - pixelright[1])
                rightvalueB = abs(pixel1[2] - pixelright[2])
                sumrightvalue = rightvalueR + rightvalueG + rightvalueB
            pixelenergy = sumupvalue + sumdownvalue + sumleftvalue + sumrightvalue
            im2.putpixel((x, y), (0, 0, int((pixelenergy)/adjustment)))

    #Bottom Row Starting Cumulative Energy
    pix2 = im2.load()
    pix3 = im3.load()
    for x2 in range(0, im.size[0]):
        pe2 = pix2[x2, im.size[1]-1]
        initial = pe2[2]
        im3.putpixel((x2, im.size[1]-1), (initial, 0 , 0))
    #Rest of the Image Cumulative Energy: Result = im3
    for y3 in reversed(range(0, im.size[1] - 1)):
        for x3 in range(0, im.size[0]):
            pe3 = pix2[x3, y3]
            if x3 == 0:
                pe3below_middle = pix3[x3, y3 + 1]
                pe3below_right = pix3[x3 + 1, y3 + 1]
                p2me = pe3below_middle[0]
                p2re = pe3below_right[0]
                choice = [p2me, p2re]
                decision = min(choice)
            elif x3 == im.size[0] - 1:
                pe3below_left = pix3[x3 - 1, y3 + 1]
                pe3below_middle = pix3[x3, y3 + 1]
                p2me = pe3below_middle[0]
                p2re = pe3below_right[0]
                choice = [p2me, p2re]
                decision = min(choice)
            else:
                pe3below_left = pix3[x3 - 1, y3 + 1]
                pe3below_middle = pix3[x3, y3 + 1]
                pe3below_right = pix3[x3 + 1, y3 + 1]
                p2le = pe3below_left[0]
                p2me = pe3below_middle[0]
                p2re = pe3below_right[0]
                choice = [p2le, p2me, p2re]
                decision = min(choice)
            cumulative3 = ((pe3[2] + decision))
            im3.putpixel((x3, y3), (int(cumulative3), 0, 0))

    #Finding Starting Point to Remove Slice
    im5 = im3.copy()
    startval = []
    for x4 in range(0, im.size[0]):
        pe4 = pix3[x4, 0]
        startval.append(pe4[0])
    xstart = min(startval)
    route = []
    while True:
        for x4 in range(0, im.size[0]):
            pe4 = pix3[x4, 0]
            if  pe4[0] != xstart:
                continue
            else:
                startco_ord = x4
                break
        break
    #Finding Actual Slice to Remove: Result = im5
    for y5 in range(0, im.size[1]):
            if y5 == im.size[1] - 1:
                im5.putpixel((startco_ord, y5), (0, 100, 0))
                route.append(startco_ord)
            else:
                if startco_ord == 0:
                    pe5below_middle = pix3[startco_ord, y5 + 1]
                    pe5below_right = pix3[startco_ord + 1, y5 + 1]
                    p5me = pe5below_middle[0]
                    p5re = pe5below_right[0]
                    p5le = -1
                    choice2 = [p5me, p5re]
                    decision2 = min(choice2)

                elif startco_ord == im.size[0] - 1:
                    pe5below_left = pix3[startco_ord - 1, y5 + 1]
                    pe5below_middle = pix3[startco_ord, y5 + 1]
                    p5le = pe5below_left[0]
                    p5me = pe5below_middle[0]
                    p5re = -1
                    choice2 = [p5me, p5le]
                    decision2 = min(choice2)

                else:
                    pe5below_left = pix3[startco_ord - 1, y5 + 1]
                    pe5below_middle = pix3[startco_ord, y5 + 1]
                    pe5below_right = pix3[startco_ord + 1, y5 + 1]
                    p5le = pe5below_left[0]
                    p5me = pe5below_middle[0]
                    p5re = pe5below_right[0]
                    choice2 = [p5me, p5re, p5le]
                    decision2 = min(choice2)

                im5.putpixel((startco_ord, y5), (0, 100, 0))
                if decision2 == p5me:
                    startco_ord = startco_ord
                    route.append(startco_ord)
                elif decision2 == p5le:
                    startco_ord = startco_ord - 1
                    route.append(startco_ord)
                elif decision2 == p5re:
                    startco_ord = startco_ord + 1
                    route.append(startco_ord)
    im5.show()

    #Editing Original Image: Result = im
    for y8 in range(0, im.size[1]):
        for x8 in range(0, im.size[0]):
            if x8 == im.size[0] - 1:
                im.putpixel((x8, y8), (0, 100, 0))
            elif x8 > route[y8]:
                shift = pix[x8 + 1, y8]
                im.putpixel((x8, y8), shift)
            elif x8 < route[y8]:
                continue

    a = numpy.array(im)
    b = numpy.delete(a, -1, axis=1)
    im = Image.fromarray(b)

im.show()


# Author: Mitchell Fehr
# Date: 10/5/2016
#
# "Sock Merchant" Python 3 Solution

import sys
n = int(input().strip())
c = [int(c_temp) for c_temp in input().strip().split(' ')]

d = dict()
pairs = 0

for sock in c:
    if sock in d:
        d[sock] = d[sock]+1
    else:
        d[sock] = 1

for key in d:
    pairs += d[key] // 2

print(pairs)


import sys
sys.path.append(f'/home/nathan-burns/Projects/Sports-Text')
sys.path.append(f'/home/nathan-burns/Projects/Sports-Text/Dodgers')
sys.path.append(f'/Users/nathanburns/Projects/Sports-Text')
sys.path.append(f'/Users/nathanburns/Projects/Sports-Text/Dodgers')

import requests
import datetime
from twilio.rest import Client
import keys

from dodgersMorningModel import DodgersMorningModel
from dodgersMorningText import dodgersMorningText
from MLBTeams import MLBTeams

espnUrl = "http://site.api.espn.com/apis/site/v2/sports/baseball/mlb/teams/" + str(MLBTeams.LosAngelesDodgers.value)
espn = requests.get(espnUrl)
espnData = espn.json()

message = ""

client = Client(keys.account_sid, keys.auth_token)

if espn.status_code == 200:
    try:
        awayTeam = espnData["team"]["nextEvent"][0]["competitions"][0]["competitors"][1]["team"]["displayName"]
        homeTeam = espnData["team"]["nextEvent"][0]["competitions"][0]["competitors"][0]["team"]["displayName"]
        if (awayTeam == "Los Angeles Dodgers"):
            win = espnData["team"]["nextEvent"][0]["competitions"][0]["competitors"][1]["winner"]
            dodgersScore = espnData["team"]["nextEvent"][0]["competitions"][0]["competitors"][1]["score"]["displayValue"]
            oponentScore = espnData["team"]["nextEvent"][0]["competitions"][0]["competitors"][0]["score"]["displayValue"]
        else:
            win = espnData["team"]["nextEvent"][0]["competitions"][0]["competitors"][0]["winner"]
            dodgersScore = espnData["team"]["nextEvent"][0]["competitions"][0]["competitors"][0]["score"]["displayValue"]
            oponentScore = espnData["team"]["nextEvent"][0]["competitions"][0]["competitors"][1]["score"]["displayValue"]
        boxScoreLink = espnData["team"]["nextEvent"][0]["links"][4]["href"]
        place = espnData["team"]["standingSummary"]
        record = espnData["team"]["record"]["items"][0]["summary"]

        morningModel = DodgersMorningModel(awayTeam, homeTeam, win, dodgersScore, oponentScore, boxScoreLink, place, record)
        morningText = dodgersMorningText(morningModel)
        message = morningText.MorningText()
        print(morningText.message)
    except:
        morningText = dodgersMorningText()
        message = morningText.MorningTextNoGame()
        print(morningText.message)

message = client.messages.create(
    body=message,
    to=keys.target_number,
    from_=keys.twilio_number,
)

print(message.body)


from bs4 import BeautifulSoup
import requests
import re
import operator

def find_between(s, first, last):
    return re.search(first + r'(.*)' + last, s, re.DOTALL | re.MULTILINE).group(1)

def get_teams(teams=[]):
    page = 0;

    while True:
        page += 1
        soup = BeautifulSoup(requests.get("http://www.gosugamers.net/dota2/rankings?page=" + str(page)).text)

        for index, data in enumerate(soup.find_all(class_="main no-game")):
            html = str(data)

            country = re.findall(r'\"(.+?)\"', html)[2]
            team = find_between(html, '', "")
            rank = index + ((page -1) * 50)
            show_rank = str(rank + 1)
            teams.insert(rank, {"rank": show_rank, "irank": (rank + 1), "country": country, "name": team})

            #Somehow this stops the loop if it reaches the end - no idea why
            try:
                if teams[rank] is None:
                    pass
            except IndexError:
                teams.pop(len(teams) - 1)
                teams.reverse()
                return teams

def get_games(teams, games=[]):
    # Need to complete team names which end in ...
    # teams is an optional parameter as there is no need to load the teams twice
    page = 0
    nows = 0

    while True:
        page += 1
        soup = BeautifulSoup(requests.get("http://www.gosugamers.net/dota2/gosubet?u-page=" + str(page)).text)
        for index, data in enumerate(soup.find_all(class_="match hover-background")):
            html = str(data)

            #Finding the time the match starts at
            time_html = data.parent.parent.find(class_="live-in")

            if time_html is None:
                if data.parent.parent.find(class_="score-wrap") is None:
                    if page is 1:
                        time = "Now"
                    else:
                        continue
                else:
                    continue
            else:
                time = str(time_html.text).rstrip().replace('\n', '')

            #Finds the first team and auto completes if name ends with ...
            team1 = find_between(html, "", "", " ")
            if team2.endswith("..."):
                for team in teams:
                    if team["name"].startswith(team2.strip("...")):
                        team2 = team["name"]
                        break

            #time_test = find_between(time_html, '\n', '')

            rank = index + ((page - 1) * 15)

            games.insert(rank, {"position": rank, "team1": team1, "team2": team2, "time": time})

            #Somehow this stops the loop if it reaches the end - no idea why
            try:
                if games[rank] is None:
                    pass
            except IndexError:
                games.pop(len(games) - 1)
                games.reverse()
                return games

def get_team(name, teams):
    for team in teams:
        if team["name"] == name:
            return team

def get_next_match(team_name, teams, games):
    games.sort(key=operator.itemgetter('position'))
    for game in games:
        if (game["team1"] == team_name) | (game["team2"] == team_name):
            games.reverse()
            return game


# coding: utf-8
from numpy import *
from cv2 import *

class Example(object):

    @classmethod
    def fellow_object(cls):
        capture = VideoCapture(0)
        namedWindow("Src")
        namedWindow("Mask")
        namedWindow("Dst")

        low_thresh = array([110, 50, 50])
        up_thresh = array([140, 255, 255])
        while True:
            ret, frame = capture.read()

            if ret is True:
                hsv = cvtColor(frame, COLOR_BGR2HSV)
                mask = inRange(hsv, low_thresh, up_thresh)
                dst = bitwise_and(frame, frame, mask=mask)

                imshow("Src", frame)
                imshow("Mask", mask)
                imshow("Dst", dst)

                c = waitKey(33)
                if c == ord('q'):
                    break

            else:
                break

if __name__ == "__main__":
    Example.fellow_object()


import csv
import json

def main():
    caption = []
    dic = {}
    max_number_of_children = 4
    threshold = 0.5
    with open('english/english_4454.csv', 'r') as csvfile:
        reader = csv.reader(csvfile)
        ct = 0

        for row in reader:
            if (ct > 0):
                caption.append(row[0])
                simi_row = row[4:]

                res = sorted(range(len(simi_row)),
                             key=lambda sub: simi_row[sub])
                pt = 0
                while float(simi_row[res[pt]]) < threshold:
                    pt += 1
                res = res[:pt]
                dic[ct-1] = res
            ct += 1

    # Replace the keyword by your choice
    keyword = 'A praying monk (earthenware toy).'
    start = caption.index(keyword)
    seen = set([keyword])
    max_lvl = 4

    def to_tree(idx, lvl):
        if lvl == max_lvl:
            return {
                "name": caption[idx],
                "value": 0
            }
        else:
            childs = []
            count = 0
            for i in dic[idx]:
                if caption[i] not in seen:
                    seen.add(caption[i])
                    childs.append(to_tree(i, lvl+1))
                    count += 1
                if count == max_number_of_children:
                    break
            return {
                "name": caption[idx],
                "children": childs
            }

    radial_tree = to_tree(start, 1)
    with open("radial.json", "w") as outfile:
        json.dump(radial_tree, outfile)

if __name__ == "__main__":
    main()


'''
Paramecium counter

check this
https://github.com/opencv/opencv_attic/blob/master/opencv/samples/cpp/fitellipse.cpp
https://stackoverflow.com/questions/42206042/ellipse-detection-in-opencv-python
http://docs.opencv.org/3.1.0/dd/d49/tutorial_py_contour_features.html
'''
import matplotlib.pyplot as plt
from skimage import data, color, img_as_ubyte
from skimage.io import imread
from skimage.feature import canny
from skimage.transform import hough_ellipse
from skimage.draw import ellipse_perimeter

filename = "/Users/Romain/Dropbox/Projects/New computational neuroscience/Biological models/Paramecium/Experiments/paramecie in drop on agar.jpg"

img = imread(filename)
image_gray = imread(filename, as_grey = True)
edges = canny(image_gray, sigma=2.0,low_threshold=0.55, high_threshold=0.8)

result = hough_ellipse(edges, accuracy=20, threshold=250,min_size=100, max_size=120)
result.sort(order='accumulator')

# Estimated parameters for the ellipse
best = list(result[-1])
yc, xc, a, b = [int(round(x)) for x in best[1:5]]
orientation = best[5]

# Draw the ellipse on the original image
cy, cx = ellipse_perimeter(yc, xc, a, b, orientation)
img[cy, cx] = (0, 0, 255)
# Draw the edge (white) and the resulting ellipse (red)
edges = color.gray2rgb(img_as_ubyte(edges))
edges[cy, cx] = (250, 0, 0)

fig2, (ax1, ax2) = plt.subplots(ncols=2, nrows=1, figsize=(8, 4), sharex=True,
                                sharey=True,
                                subplot_kw={'adjustable':'box-forced'})

ax1.set_title('Original picture')
ax1.imshow(img)

ax2.set_title('Edge (white) and result (red)')
ax2.imshow(edges)

#img = cv2.medianBlur(img,11)
#edges = cv2.Canny(img,10,80)
#th = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,15,2)
#contours, hierarchy = cv2.findContours(edges,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#cv2.drawContours(edges,contours,0,(0,0,255))

#plt.imshow(img, cmap='gray')
#plt.axis('off')
ax2.show()

#cv2.imshow('Image', img)
#cv2.waitKey(0)
#cv2.destroyAllWindows()


import paramiko

# ip = '2600:1f16:e7a:a088:51b:4369:e4e3:6ff8'
# name ='ubuntu'
# key_path='/home/drl/Jerry/tool/aws_ohio.pem'
#
# key=paramiko.RSAKey.from_private_key_file(key_path )
#
# #建立一个加密的管道
# scp=paramiko.Transport((ip,22))
#
#
# #建立连接
# scp.connect(username=name,pkey=key)
# #建立一个sftp客户端对象，通过ssh transport操作远程文件
# sftp=paramiko.SFTPClient.from_transport(scp)
# #Copy a remote file (remotepath) from the SFTP server to the local host
# sftp.get('/home/ubuntu/README','log-files/')
# # #Copy a local file (localpath) to the SFTP server as remotepath
# # sftp.put('/root/crash-6.1.6.tar.gz','/tmp/crash-6.1.6.tar.gz')
# scp.close()
# #2402:f000:6:3801:2d55:548f:d03c:ccad/64

import paramiko,datetime,os
import socket
hostname='2600:1f16:e7a:a088:805d:16d6:f387:62e5'
username='ubuntu'

key_path='/home/drl/Jerry/tool/aws_ohio.pem'
key=paramiko.RSAKey.from_private_key_file(key_path )

port=22

local_dir='/home/drl/PycharmProjects/DeployedProjects/CR_CPG/Hyper_lab/tmp/model'
remote_dir='/home/ubuntu/jerry/examples/tmp'
try:
    t=paramiko.Transport((hostname,port))
    t.connect(username=username,  pkey=key)
    sftp=paramiko.SFTPClient.from_transport(t)
    #files=sftp.listdir(dir_path)
    files=sftp.listdir(remote_dir)
    for f in files:
        print('')
        print( '#########################################')
        print('Beginning to download file from %s %s ' % (hostname,datetime.datetime.now()) )
        print( 'Downloading file:',os.path.join(remote_dir,f))
        sftp.get(os.path.join(remote_dir,f),os.path.join(local_dir,f))#下载

        #sftp.put(os.path.join(local_dir,f),os.path.join(remote_dir,f))#上传
        print ('Download file success %s ' % datetime.datetime.now())
        print ('')
        print ('##########################################')
    t.close()

except Exception:
    print ("connect error!")
#
# import paramiko
# import os
# from stat import S_ISDIR as isdir
#
#
# def down_from_remote(sftp_obj, remote_dir_name, local_dir_name):
#     """远程下载文件"""
#     remote_file = sftp_obj.stat(remote_dir_name)
#     if isdir(remote_file.st_mode):
#         # 文件夹，不能直接下载，需要继续循环
#         check_local_dir(local_dir_name)
#         print('开始下载文件夹：' + remote_dir_name)
#         for remote_file_name in sftp.listdir(remote_dir_name):
#             sub_remote = os.path.join(remote_dir_name, remote_file_name)
#             sub_remote = sub_remote.replace('\\', '/')
#             sub_local = os.path.join(local_dir_name, remote_file_name)
#             sub_local = sub_local.replace('\\', '/')
#             down_from_remote(sftp_obj, sub_remote, sub_local)
#     else:
#         # 文件，直接下载
#         print('开始下载文件：' + remote_dir_name)
#         sftp.get(remote_dir_name, local_dir_name)
#
# def put_to_remote(sftp_obj, remote_dir_name, local_dir_name):
#     """远程下载文件"""
#     remote_file = sftp_obj.stat(remote_dir_name)
#     if isdir(remote_file.st_mode):
#         # 文件夹，不能直接下载，需要继续循环
#         check_local_dir(local_dir_name)
#         print('开始上传文件夹：' + remote_dir_name)
#         for remote_file_name in sftp.listdir(remote_dir_name):
#             sub_remote = os.path.join(remote_dir_name, remote_file_name)
#             sub_remote = sub_remote.replace('\\', '/')
#             sub_local = os.path.join(local_dir_name, remote_file_name)
#             sub_local = sub_local.replace('\\', '/')
#             down_from_remote(sftp_obj, sub_remote, sub_local)
#     else:
#         # 文件，直接下载
#         print('开始下载文件：' + remote_dir_name)
#         sftp.put(local_dir_name,remote_dir_name )
#
# def check_local_dir(local_dir_name):
#     """本地文件夹是否存在，不存在则创建"""
#     if not os.path.exists(local_dir_name):
#         os.makedirs(local_dir_name)
#
#
# if __name__ == "__main__":
#     """程序主入口"""
#     # 服务器连接信息
#     host_name = hostname
#     user_name = username
#
#     port = 22
#     # 远程文件路径（需要绝对路径）
#     remote_dir =  remote_dir
#     # 本地文件存放路径（绝对路径或者相对路径都可以）
#     local_dir = local_dir
#
#     # 连接远程服务器
#     t = paramiko.Transport((host_name, port))
#     t.connect(username=user_name, pkey=key)
#     sftp = paramiko.SFTPClient.from_transport(t)
#
#     # 远程文件开始下载
#    # down_from_remote(sftp, remote_dir, local_dir)
#     put_to_remote(sftp, remote_dir, local_dir)
#     # 关闭连接
#     t.close()


import cv2
import os
import json
from pathlib import Path

# Get the input filename
rootFolder = Path(os.path.dirname(os.path.realpath(__file__)))
outFolder = rootFolder / "out"
tilesFolder = rootFolder / "../common/tiles"
dataFilePath = outFolder / "data.json"

# Create an output folder if it doesn't already exist
if not os.path.isdir(outFolder):
    os.mkdir(outFolder)

# Calculate and return the average color for the given image
def getAverageColor(img):
    ################################################
    # Your code here
    ################################################
    pass

# Create a list of metadata objects (see handout) and save it as a JSON file
def generateMetadata():
    # Iterate thorugh the tile images
    for imgName in os.listdir(tilesFolder):
        img_path = tilesFolder / imgName
        print(img_path.resolve())

        ################################################
        # Your code here
        ################################################

# Check if the output file exists
if os.path.isfile(dataFilePath):
    print("File already exists, overwrite existing file? y/n")
    ans = input()
    # Overwrite the file if the user inputs 'y'
    if ans == "y" or ans == "Y":
        generateMetadata()
    else:
        print("Quitting.")
else:
    generateMetadata()


# (c) Nelen & Schuurmans.  GPL licensed, see LICENSE.rst.
# -*- coding: utf-8 -*-
"""
Popup info rendering
--------------------

A WMS source has FeatureLines. Clicking on the map opens a popup that shows
all the lines from the WMS GetFeatureInfo call. Every line can be configured
to be rendered in a certain way. This module contains the various renderers.

"""
from __future__ import unicode_literals
from __future__ import print_function
import datetime
import json
import logging

from django.utils.translation import ugettext_lazy as _
# ^^^ Note: the lasy ugettext as choices() is used in a model.
from django.utils.safestring import mark_safe

from lizard_wms.chart import google_column_chart_url

# Keep these constants in the order of their value.
# They need to be one character long, btw.
RENDER_TWO_DECIMALS = 'A'
RENDER_INTEGER = 'B'
RENDER_GC_COLUMN = 'C'
RENDER_IMAGE = 'I'
RENDER_IMAGE_FULLWIDTH = 'J'
RENDER_URL_MORE_LINK = 'M'
RENDER_TEXT = 'T'
RENDER_URL = 'U'
RENDER_URL_LIKE = 'W'
RENDER_XLS_DATE = 'X'

#: The default renderer for a popup item: as text.
DEFAULT_RENDERER = RENDER_TEXT

#: Choices for popup rendering: every FeatureLine can choose how it wants to be
#: displayed.
POPUP_RENDER_CHOICES = (
    (RENDER_TEXT, _("Text")),
    (RENDER_IMAGE, _("Link to an image")),
    (RENDER_IMAGE_FULLWIDTH, _("Link to an image, full table width")),
    (RENDER_INTEGER, _("Integer")),
    (RENDER_TWO_DECIMALS, _("Float with two decimals")),
    (RENDER_XLS_DATE, _("Excel date format")),
    (RENDER_URL, _("URL")),
    (RENDER_URL_LIKE, _("URL-like text")),
    (RENDER_URL_MORE_LINK, _("URL shown as 'click here' link")),
    (RENDER_GC_COLUMN, _("Google column chart")),
    )

LINK_TEMPLATE = '''
%(link_text)s
'''

logger = logging.getLogger(__name__)

def choices():
    """Return choices for the FeatureLine model.

    See :ref:`popup-choices` for the available choices.
    """
    return POPUP_RENDER_CHOICES

def xls_date_to_string(xldate):
    """Return iso-formatted date from an excel float date.

    The method is adapted from http://stackoverflow.com/a/1112664/27401 with
    the assumption that it is a 1900-based date instead of a 1904 one...

    """
    dt = datetime.datetime(1899, 12, 30) + datetime.timedelta(days=xldate)
    return dt.isoformat()[:10]  # Yes, this can be formatted more nicely.

def popup_info(feature_line, value):
    """Return dict with info for the WMS popup.

    It should return a dict with three items:

    - **label_on_separate_line**: the output is normally a two-column
      table. When this option is set to True, the label is printed on a line
      of its own with the value on a whole line of its own, below. Used for
      big google graphs.

    - **label**: the label. Shown in the first column.

    - **value**: the value to show. Use ``mark_safe()`` when returning a bunch
      of html. Note that we do some html rendering here ourselves instead of
      in the template as we know which rendering methods to use here in this
      file. The template *used* to be littered with exceptions, being tightly
      coupled to the constants in this file. Not anymore.

    The value is rendered based on the ``render_as`` attribute of the
    featureline. See :ref:`popup-choices` for the available choices.

    """
    render_as = feature_line.render_as
    replacement_link_text = None
    label = feature_line.description or feature_line.name
    if render_as in [RENDER_GC_COLUMN, RENDER_IMAGE_FULLWIDTH]:
        label_on_separate_line = True
    else:
        label_on_separate_line = False

    # First some special cases that "convert" themselves to other renderers.
    if render_as == RENDER_GC_COLUMN:
        try:
            json_data = json.loads(value)
            if json_data is None:
                # See https://github.com/nens/deltaportaal/issues/4
                logger.warn(
                    "https://github.com/nens/deltaportaal/issues/4 "
                    "hits again")
                raise ValueError("Somehow the json data doesn't exist???")
            value = google_column_chart_url(json_data)
        except (TypeError, ValueError):
            logger.exception(
                "Exception when loading json google chart data")
            value = ''
        if value != '':
            render_as = RENDER_IMAGE
        else:
            render_as = RENDER_TEXT
            value = _("Error converting data to a graph")
    elif render_as == RENDER_XLS_DATE:
        try:
            date_value = float(value)
        except ValueError:
            logger.warn("Not a float-like value for XLS date: %r", value)
            return
        value = xls_date_to_string(date_value)
        render_as = RENDER_TEXT
    elif render_as == RENDER_URL_LIKE:
        # Quite brittle, but equal to the code from the template that it
        # replaces.
        value = 'http://' + value
        render_as = RENDER_URL
    elif render_as == RENDER_URL_MORE_LINK:
        replacement_link_text = _("Click here for more information")
        if not 'http://' in value:
            value = 'http://' + value
            # Yes, this means we could do the same for RENDER_URL_LIKE
            # options, but I'm leaving that one alone for the moment.
        render_as = RENDER_URL
    elif render_as == RENDER_INTEGER:
        try:
            value = float(value)
        except ValueError:
            logger.warn("Not a number-like value: %r", value)
            return
        value = unicode(int(round(value)))
        render_as = RENDER_TEXT
    elif render_as == RENDER_TWO_DECIMALS:
        try:
            value = float(value)
        except ValueError:
            logger.warn("Not a number-like value: %r", value)
            return
        value = '%0.2f' % value
        render_as = RENDER_TEXT

    # OK, now the actual rendering. Only text, url and image renderers are
    # left.
    if render_as == RENDER_TEXT:
        pass  # value is fine.
    elif render_as == RENDER_IMAGE:
        value = mark_safe('' % value)
    elif render_as == RENDER_IMAGE_FULLWIDTH:
        value = mark_safe('' % value)
    elif render_as == RENDER_URL:
        link_text = replacement_link_text or value
        value = mark_safe(LINK_TEMPLATE % {'url': value,
                                           'link_text': link_text})

    return {
        'label': label,
        'label_on_separate_line': label_on_separate_line,
        'value': value,
        }


def solution(H):
    stack = list()
    count = 0
    for h in H:
        while len(stack) != 0 and stack[-1] > h:
            stack.pop()
        if len(stack) == 0 or stack[-1] < h:
            count += 1
            stack.append(h)

    return count


"""init

Revision ID: acc8b8a37ccd
Revises:
Create Date: 2021-10-06 08:00:00.000000

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = "acc8b8a37ccd"
down_revision = None
branch_labels = None
depends_on = None

def upgrade():
    op.create_table(
        "offer",
        sa.Column("id", sa.INTEGER(), nullable=True),
        sa.Column("product_id", sa.INTEGER(), nullable=True),
        sa.Column("check_interval", sa.INTEGER(), nullable=True),
        sa.Column("url", sa.VARCHAR(), nullable=False),
        sa.ForeignKeyConstraint(
            ["product_id"],
            ["product.id"],
        ),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index("ix_offer_url", "offer", ["url"], unique=False)
    op.create_index("ix_offer_product_id", "offer", ["product_id"], unique=False)
    op.create_index("ix_offer_id", "offer", ["id"], unique=False)
    op.create_index(
        "ix_offer_check_interval", "offer", ["check_interval"], unique=False
    )
    op.create_table(
        "product",
        sa.Column("id", sa.INTEGER(), nullable=True),
        sa.Column("category", sa.VARCHAR(), nullable=False),
        sa.Column("name", sa.VARCHAR(), nullable=False),
        sa.Column("image", sa.VARCHAR(), nullable=True),
        sa.Column("description", sa.VARCHAR(), nullable=True),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index("ix_product_name", "product", ["name"], unique=False)
    op.create_index("ix_product_image", "product", ["image"], unique=False)
    op.create_index("ix_product_id", "product", ["id"], unique=False)
    op.create_index("ix_product_description", "product", ["description"], unique=False)
    op.create_index("ix_product_category", "product", ["category"], unique=False)
    op.create_table(
        "history",
        sa.Column("id", sa.INTEGER(), nullable=True),
        sa.Column("offer_id", sa.INTEGER(), nullable=True),
        sa.Column("datetime", sa.INTEGER(), nullable=False),
        sa.Column("availability", sa.INTEGER(), nullable=False),
        sa.Column("price", sa.INTEGER(), nullable=False),
        sa.Column("price_currency", sa.VARCHAR(), nullable=False),
        sa.ForeignKeyConstraint(
            ["offer_id"],
            ["offer.id"],
        ),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index(
        "ix_history_price_currency", "history", ["price_currency"], unique=False
    )
    op.create_index("ix_history_price", "history", ["price"], unique=False)
    op.create_index("ix_history_offer_id", "history", ["offer_id"], unique=False)
    op.create_index("ix_history_id", "history", ["id"], unique=False)
    op.create_index("ix_history_datetime", "history", ["datetime"], unique=False)
    op.create_index(
        "ix_history_availability", "history", ["availability"], unique=False
    )

def downgrade():
    op.drop_index("ix_history_availability", table_name="history")
    op.drop_index("ix_history_datetime", table_name="history")
    op.drop_index("ix_history_id", table_name="history")
    op.drop_index("ix_history_offer_id", table_name="history")
    op.drop_index("ix_history_price", table_name="history")
    op.drop_index("ix_history_price_currency", table_name="history")
    op.drop_table("history")
    op.drop_index("ix_product_category", table_name="product")
    op.drop_index("ix_product_description", table_name="product")
    op.drop_index("ix_product_id", table_name="product")
    op.drop_index("ix_product_image", table_name="product")
    op.drop_index("ix_product_name", table_name="product")
    op.drop_table("product")
    op.drop_index("ix_offer_check_interval", table_name="offer")
    op.drop_index("ix_offer_id", table_name="offer")
    op.drop_index("ix_offer_product_id", table_name="offer")
    op.drop_index("ix_offer_url", table_name="offer")
    op.drop_table("offer")


#Pseudo Scholl Analysis
#Count all nodes inbetween two spheres and plot a histogram of that
from math import sqrt
from ini.trakem2.display import Display
from jarray import array
import sys
sys.path.append("/Users/berthola/Desktop/Fiji Scripts")
from matrixoperator import Matrix
from javax.media.j3d import Transform3D
from javax.vecmath import Point3d
from ij.io import FileSaver

#-------------Transformation-------------------------------------

m = [0.9509217490842972, 0.24926674965164644, -0.18334097915241027, -51626.05759575438,
     -0.2722540786706435, 0.9555797748775074, -0.11289380183274611, -28182.499757448437,
     0.14705626054561627, 0.15726850086128405, 0.9765454801857332, -12950.550433910958,
     0.0, 0.0, 0.0, 1.0]
wt = Transform3D(m)

def correct(pa):
  global wt
  p = Point3d(pa[0], pa[1], pa[2])
  wt.transform(p)
  return [p.x, p.y, p.z]

#-----------Get Coordinates of tree------------------------------------

def getNodeCoordinates(tree):
  """ Returns a map of Node instances vs. their X,Y,Z world coordinates. """
  root = tree.getRoot()
  if root is None:
    return {}
  calibration = tree.getLayerSet().getCalibration()
  affine = tree.getAffineTransform()
  coords = []

  for nd in root.getSubtreeNodes():
    fp = array([nd.getX(), nd.getY()], 'f')
    affine.transform(fp, 0, fp, 0, 1)
    x = fp[0] * calibration.pixelWidth
    y = fp[1] * calibration.pixelHeight
    z = nd.getLayer().getZ() * calibration.pixelWidth   # a TrakEM2 oddity
    # data may be a radius or a java.awt.geom.Area
    coords.append( correct([x, y, z]) )
    #print coords[len(coords)-1]
  return coords

def sphereCount(ID, biniter):
  #find center of mass
  tree = Display.getFront().getLayerSet().findById(ID)
  coords = Matrix(getNodeCoordinates(tree))
  center = Matrix( [[0,0,0]] )
  m=coords.getRowDimension()

  for i in range(0, m):
    center += Matrix([coords.getRow( i )])
  center /= float(m)

  #calculate all distances of all points to center of mass and put them in a list
  xdist=[]
  ydist=[]
  zdist=[]
  for i in range(0, m):
    xdiff=[]
    if coords.get(i,0) > center.get(0,0):
      xdiff = coords.get(i,0) - center.get(0,0)
    else:
      xdiff = center.get(0,0) - coords.get(i,0)
    xdist.append(xdiff)

  for i in range(0, m):
    ydiff=[]
    if coords.get(i,1) > center.get(0,1):
      ydiff = coords.get(i,1) - center.get(0,1)
    else:
      ydiff = center.get(0,1) - coords.get(i,1)
    ydist.append(ydiff)

  for i in range(0, m):
    zdiff=[]
    if coords.get(i,2) > center.get(0,2):
      zdiff = coords.get(i,2) - center.get(0,2)
    else:
      zdiff = center.get(0,2) - coords.get(i,2)
    zdist.append(zdiff)

  nodeDist=[]
  dist=[]
  for i in range(0, m):
    dist=sqrt(xdist[i]**2 + ydist[i]**2 + zdist[i]**2)
    nodeDist.append(dist)

  iterations=biniter
  Ri=0 #inner radius
  """
  The maximum distance can only be achieved in the xy-plane
  With "fixed" coordinates this will approx. be 35000nm
  To make the scholl-profiles comparable this length has to be used.
  """
  scholl=[]
  xaxis=[]
  counter=0
  length= int(35000 / biniter + 0.5)
  Ra=length #outer radius

  for i in range(0, biniter):
    for i in range(0, len(nodeDist)):
      if nodeDist[i] <= Ra and nodeDist[i] >= Ri:
        counter += 1
    scholl.append(counter)
    counter=0
    xaxis.append(Ri) # adapt THIS position in all other scripts! Otherwise 1 datapoint is missing!!
    Ri += length
    Ra += length

  return scholl, xaxis

#plot = Plot("histogram", "distance from center", "count",xaxis, scholl)
#plot.show()


import tkinter

fuenteElementos = ("Arial", 18)

def sumar():
    resultado =  float(txt_valor1.get()) + float(txt_valor2.get())
    lbl_resultado["text"]= resultado

def restar():
    resultado =  float(txt_valor1.get()) - float(txt_valor2.get())
    lbl_resultado["text"]= resultado

def multiplicar():
    resultado =  float(txt_valor1.get()) * float(txt_valor2.get())
    lbl_resultado["text"]= resultado

def dividir():
    resultado =  float(txt_valor1.get()) / float(txt_valor2.get())
    lbl_resultado["text"]= resultado

ventana = tkinter.Tk()
ventana.geometry()
ventana.title("Ejemplo Grid")

lbl_titulo = tkinter.Label(ventana, text="Ejemplo Grid", font=("Arial",30), bg="red")

lbl_valor1 = tkinter.Label(ventana, text="Valor 1", font= fuenteElementos)
txt_valor1 = tkinter.Entry(ventana, font= fuenteElementos)

lbl_valor2 = tkinter.Label(ventana, text="Valor 2", font= fuenteElementos)
txt_valor2 = tkinter.Entry(ventana, font= fuenteElementos)

btn_suma = tkinter.Button(ventana, text="+", font= fuenteElementos, bg="green", command= sumar)
btn_resta = tkinter.Button(ventana, text="-", font= fuenteElementos, bg="green", command= restar)
btn_multi = tkinter.Button(ventana, text="*", font= fuenteElementos, bg="green", command= multiplicar)
btn_divi = tkinter.Button(ventana, text="/", font= fuenteElementos, bg="green", command= dividir)

lbl_resultado = tkinter.Label(ventana, text="Resultado", font= fuenteElementos)

#posiciones en el sistema GRID
lbl_titulo.grid(row=0, column=0, columnspan=4, sticky=(tkinter.W,tkinter.E))
lbl_valor1.grid(row=1, column=0)
txt_valor1.grid(row=1, column=1, columnspan=3)

lbl_valor2.grid(row=2, column=0)
txt_valor2.grid(row=2, column=1, columnspan=3)

btn_suma.grid(row=3, column=0, sticky=(tkinter.W, tkinter.E) )
btn_resta.grid(row=3, column=1, sticky=(tkinter.W, tkinter.E))
btn_multi.grid(row=3, column=2, sticky=(tkinter.W, tkinter.E))
btn_divi.grid(row=3, column=3, sticky=(tkinter.W, tkinter.E))

lbl_resultado.grid(row=4, column=0, columnspan=4, sticky=(tkinter.W, tkinter.E))

ventana.mainloop()