from __future__ import print_function
import pyzbar.pyzbar as pyzbar
from pyzbar.pyzbar import decode
import numpy as np
import cv2
from imutils.video import WebcamVideoStream
from imutils.video import FPS
import imutils
import glob
import sys, time, math

calib_path  = "/Users/benzandonati/Desktop/code/opencv/CalibImages/"
mtx   = np.loadtxt(calib_path+'cameraMatrix.txt', delimiter=',')
dist   = np.loadtxt(calib_path+'cameraDistortion.txt', delimiter=',')

dimension = 70 #- mm

objp = np.zeros((2*2,3), np.float32)
objp[:,:2] = np.mgrid[0:2,0:2].T.reshape(-1,2)

criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, dimension, 0.001)

axis = np.float32([[1,0,0], [0,1,0], [0,0,1]]).reshape(-1,3)

def gstreamer_pipeline (capture_width=640, capture_height=360, display_width=1360, display_height=768, framerate=60, flip_method=0) :
    return ('nvarguscamerasrc ! '
    'video/x-raw(memory:NVMM), '
    'width=(int)%d, height=(int)%d, '
    'format=(string)NV12, framerate=(fraction)%d/1 ! '
    'nvvidconv flip-method=%d ! '
    'video/x-raw, width=(int)%d, height=(int)%d, format=(string)BGRx ! '
    'videoconvert ! '
    'video/x-raw, format=(string)BGR ! appsink'  % (capture_width,capture_height,framerate,flip_method,display_width,display_height))

def draw(img, corners, imgpts):
    corner = tuple(corners[0].ravel())
    img = cv2.line(img, corner, tuple(imgpts[0].ravel()), (255,0,0), 3)
    img = cv2.line(img, corner, tuple(imgpts[1].ravel()), (0,255,0), 3)
    img = cv2.line(img, corner, tuple(imgpts[2].ravel()), (0,0,255), 3)
    return img

def decode(im) :
  # Find barcodes and QR codes
  decodedObjects = pyzbar.decode(im)

  # Print results
  for obj in decodedObjects:
    print('Type : ', obj.type)
    print('Data : ', obj.data)
    print('Points : ', obj.polygon,'\n')

  return decodedObjects

# Display barcode and QR code location
def display(im, decodedObjects):

  # Loop over all decoded objects
  for decodedObject in decodedObjects:
    points = decodedObject.polygon

    # If the points do not form a quad, find convex hull
    if len(points) > 4 :
      hull = cv2.convexHull(np.array([point for point in points], dtype=np.float32))
      hull = list(map(tuple, np.squeeze(hull)))
    else :
      hull = points;

    # Number of points in the convex hull
    n = len(hull)

    # Draw the convext hull
    for j in range(0,n):
      cv2.line(im, hull[j], hull[ (j+1) % n], (0,0,0), 3)

  # Display results

  #cv2.imshow("Results", im);
  #cv2.waitKey(0);

# Main
if __name__ == '__main__':
  #cap = cv2.VideoCapture(0)

  # construct the argument parse and parse the arguments

  font = cv2.FONT_HERSHEY_SIMPLEX
  print("[INFO] sampling frames from webcam...")
  cv2.VideoCapture(gstreamer_pipeline(flip_method=0), cv2.CAP_GSTREAMER)
  fps = FPS().start()

  while True:

    frame = cap.read()
    #frame = imutils.resize(frame, width=800)
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    decodedObjects = decode(frame)

    #if args["display"] > 0:
    #print(len(decodedObjects))
    if len(decodedObjects) > 0:

      if str(decodedObjects[0][0]) == "b'51.645349/-0.632181'" :
        break

      cv2.putText(frame,str(decodedObjects[0][0]),(10,50), font, 0.5,(0,0,0),1,cv2.LINE_AA)

      points = decodedObjects[0].polygon
      corners = np.array([point for point in points], dtype=np.float32)

      #print(corners)

      temp0 = corners[0]
      temp1 = corners[1]
      temp2 = corners[2]
      temp3 = corners[3]

      corners = np.array([temp0, temp1, temp3, temp2])

      #print(corners)

      corners2 = cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)

      ret,rvecs, tvecs = cv2.solvePnP(objp, corners2, mtx, dist)

      imgpts, jac = cv2.projectPoints(axis, rvecs, tvecs, mtx, dist)

      print(tvecs*dimension)
      if len(corners2) > 3 :
        frame = draw(frame,corners2,imgpts)

    display(frame, decodedObjects)

    #im = imutils.resize(frame, width=300)
    #cv2.imshow("Results", frame);
    fps.update()
    key = cv2.waitKey(1)
    if key == 27:
      break

  fps.stop()

  print("[INFO] elasped time: {:.2f}".format(fps.elapsed()))
  print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))

  cap.release()
  cv2.destroyAllWindows()


import json

class Teacher:
    def __init__(self, identifier, lang="en"):
        with open(f"Scenarios/{lang}/teachers/{identifier}.json", "r") as f:
            data = json.load(f)
        self.name = data["name"]
        self.character = data["character"]
        self.few_shots = "".join(data["few_shots"])

        self.voice = data["voice"]
        self.audioConfig = data["audioConfig"]


"""
Adapted from
    - https://github.com/PyTorchLightning/lightning-bolts/blob/master/pl_bolts/models/self_supervised/swav/swav_module.py
Bugs to fix:
- STL10 augmentation
- weight_init, bn3 and so on.
"""

import os
import math

import torch
from torch import nn
from torch import distributed as dist
import pytorch_lightning as pl
from pytorch_lightning.callbacks import LearningRateMonitor, ModelCheckpoint

from backbone import resnet18, resnet50, SwAV
from optimizer import LARS
from lr_scheduler import linear_warmup_decay
from dataloader import get_swav_transform, SwAVFinetuneTransform, STL10DataModule, CIFAR10DataModule
from callback import SSLOnlineEvaluator

def exclude_from_wt_decay(named_params, weight_decay):
    skip_list = ["bias", "bn"]
    params = []
    excluded_params = []
    for name, param in named_params:
        if not param.requires_grad:
            continue
        elif any(layer_name in name for layer_name in skip_list):
            excluded_params.append(param)
        else:
            params.append(param)
    return [
        {"params": params, "weight_decay": weight_decay},
        {"params": excluded_params, "weight_decay": 0.0},
    ]

class Net(pl.LightningModule):
    def __init__(
        self,
        # ---- Model -----
        backbone_arch,
        first_conv,
        maxpool1,
        hidden_mlp,
        feature_dim,
        num_prototypes,
        # ----- Optimizer/schedular -----
        optimizer,
        lr,
        exclude_bn_bias,
        weight_decay,
        warmup_epochs,
        max_epochs,
        # start_lr,
        # final_lr,
        # ----- Queue -----
        num_samples,
        queue_length,
        queue_path,
        queue_start_epoch,
        # ----- Miscellaneous -----
        dataset,
        total_gpus,
        batch_size,
        crops_for_assign,
        num_crops,
        sinkhorn_iterations,
        epsilon,
        temperature,
        freeze_prototypes_epochs,
    ):
        """
        Args:
            crops_for_assign: list of crop ids for computing assignment
            num_crops: number of global and local crops, ex: [2, 6]

            queue_length: set queue when batch size is small,
                must be divisible by total batch-size (i.e. total_gpus * batch_size),
                set to 0 to remove the queue
            queue_path: folder within the logs directory
            queue_start_epoch: start uing the queue after this epoch
        """

        super().__init__()
        self.total_batch_size = batch_size * total_gpus
        # self.queue_length = queue_length
        # self.queue_path = queue_path
        # self.queue_start_epoch = queue_start_epoch

        self.save_hyperparameters()

        if backbone_arch == "resnet18":
            backbone = resnet18
        elif backbone_arch == "resnet50":
            backbone = resnet50
        else:
            raise ValueError("Backbone unknown.")
        self.model = SwAV(
            backbone=backbone(first_conv=first_conv, maxpool1=maxpool1),
            hid_dim=hidden_mlp,
            out_dim=feature_dim,
            normalize=True,
            num_prototypes=num_prototypes,
        )

        self.get_assignments = (
            self.distributed_sinkhorn if total_gpus > 1 else self.sinkhorn
        )

    def setup(self, stage):
        assert self.hparams.queue_length % self.total_batch_size == 0
        self.queue = None
        if self.hparams.queue_length > 0:
            # if not os.path.exists(queue_folder):
            #     os.makedirs(queue_folder)
            self.hparams.queue_path = os.path.join(
                self.logger.log_dir,
                self.hparams.queue_path,
                "queue" + str(self.trainer.global_rank) + ".pth",
            )
            if os.path.isfile(self.hparams.queue_path):
                self.queue = torch.load(self.hparams.queue_path)["queue"]
            self.queue_use = False

    def forward(self, x):
        return self.model.backbone(x)

    def training_step(self, batch, batch_idx):
        loss = self.shared_step(batch)
        self.log("train_loss", loss)
        return loss

    def validation_step(self, batch, batch_idx):
        loss = self.shared_step(batch)
        self.log("val_loss", loss)

    def configure_optimizers(self):
        steps_per_epoch = math.ceil(
            self.hparams.num_samples // self.total_batch_size
        )
        if self.hparams.exclude_bn_bias:
            params = exclude_from_wt_decay(
                self.named_parameters(), weight_decay=self.hparams.weight_decay
            )
        else:
            params = self.parameters()

        if self.hparams.optimizer == "lars":
            optimizer = LARS(
                params,
                lr=self.hparams.lr,
                momentum=0.9,
                weight_decay=self.hparams.weight_decay,
                trust_coefficient=0.001,
            )
        elif self.hparams.optimizer == "adam":
            optimizer = torch.optim.Adam(
                params, lr=self.hparams.lr, weight_decay=self.hparams.weight_decay
            )

        warmup_steps = steps_per_epoch * self.hparams.warmup_epochs
        total_steps = steps_per_epoch * self.hparams.max_epochs

        return dict(
            optimizer=optimizer,
            lr_scheduler=torch.optim.lr_scheduler.LambdaLR(
                optimizer,
                linear_warmup_decay(warmup_steps, total_steps, cosine=True),
            ),
            interval="step",
            frequency=1,
        )

    # def optimizer_step(
    #     self,
    #     epoch,
    #     batch_idx,
    #     optimizer,
    #     optimizer_idx,
    #     optimizer_closure,
    #     on_tpu,
    #     using_native_amp,
    #     using_lbfgs,
    # ):
    #     for param_group in optimizer.param_groups:
    #         param_group["lr"] = self.lr_schedule[self.trainer.global_step]
    #     self.log(
    #         "lr",
    #         self.lr_schedule[self.trainer.global_step],
    #         on_step=True,
    #         on_epoch=False,
    #     )

    #     super().optimizer_step(
    #         epoch,
    #         batch_idx,
    #         optimizer,
    #         optimizer_idx,
    #         optimizer_closure,
    #         on_tpu,
    #         using_native_amp,
    #         using_lbfgs,
    #     )

    def on_after_backward(self) -> None:
        if self.current_epoch < self.hparams.freeze_prototypes_epochs:
            for name, p in self.model.named_parameters():
                if "prototypes" in name:
                    p.grad = None
                    break
            else:
                raise RuntimeError("No prototype tensor found in your model.")

    def on_train_epoch_start(self):
        if self.hparams.queue_length > 0:
            if self.current_epoch == self.hparams.queue_start_epoch and self.queue is None:
                # Init the queue
                self.queue = torch.zeros(
                    len(self.crops_for_assign),
                    self.hparams.queue_length // (self.hparams.total_gpus),
                    self.hparams.feature_dim,
                )
                if self.hparams.total_gpus > 0:
                    self.queue = self.queue.cuda()

    def on_train_epoch_end(self, outputs) -> None:
        if self.queue is not None:
            torch.save({"queue": self.queue}, self.queue_path)

    def shared_step(self, batch):
        if self.hparams.dataset == "stl10":
            batch = batch[0]  # unlabeled data
        images, _ = batch
        images = images[:-1]

        # Step 1: normalize the prototypes
        with torch.no_grad():
            w = self.model.head.prototype.weight.data.clone()
            w = nn.functional.normalize(w, dim=1, p=2)
            self.model.head.prototype.weight.copy_(w)

        # Step 2: multi forward pass
        embedding, outputs = self.model(images)
        embedding = embedding.detach()

        # Step 3: SwAV loss
        batch_size = self.hparams.batch_size
        loss = 0
        for i, crop_id in enumerate(self.hparams.crops_for_assign):
            with torch.no_grad():
                out = outputs[batch_size * crop_id : batch_size * (crop_id + 1)]

                # Step 4: use the queue
                if self.queue is not None:
                    if not self.queue_use:
                        if not torch.all(self.queue[i, -1, :] == 0):
                            # Only concatenate the queue when it is filled.
                            self.queue_use = True
                    if self.queue_use:
                        out = torch.cat(
                            (self.queue[i] @ self.model.head.prototype.weight.t(), out)
                        )
                    # fill the queue
                    self.queue[i, batch_size:] = self.queue[i, :-batch_size].clone()
                    self.queue[i, :batch_size] = embedding[
                        crop_id * batch_size : (crop_id + 1) * batch_size
                    ]

                # Step 5: get assignments
                q = torch.exp(out / self.hparams.epsilon).t()
                q = self.get_assignments(q, self.hparams.sinkhorn_iterations)[
                    -batch_size:
                ]
            sub_loss = 0
            for v in torch.arange(sum(self.hparams.num_crops)):
                if v == crop_id:
                    continue
                p = (
                    outputs[batch_size * v: batch_size * (v + 1)]
                    / self.hparams.temperature
                ).softmax(dim=1)
                sub_loss -= (q * torch.log(p)).sum(dim=1).mean()
            loss += sub_loss / (sum(self.hparams.num_crops) - 1)
        return loss / len(self.hparams.crops_for_assign)

    # def get_linear_warmup_cosine_annealing_scheduler(self):
    #     global_batch_size = self.hparams.total_gpus * self.hparams.batch_size
    #     step_per_epoch = torch.ceil(self.hparams.num_samples // global_batch_size)

    #     warmup_lrs = torch.linspace(
    #         self.hparams.start_lr, self.hparams.lr, self.warmup_epochs * step_per_epoch
    #     )

    #     cosine_steps = step_per_epoch * (
    #         self.hparams.max_epochs - self.hparams.warmup_epochs
    #     )
    #     # Angular frequency of cosine function. Thus the period equals 2 * cosine_steps.
    #     w = math.pi / cosine_steps
    #     # Amplitude of cosine function
    #     a = 0.5 * (self.hparams.lr - self.hparams.final_lr)
    #     cosine_lrs = [
    #         0.5 * (self.hparams.lr + self.hparams.final_lr) + a * torch.cos(w * step)
    #         for step in range(cosine_steps)
    #     ]
    #     return torch.cat([warmup_lrs, cosine_lrs])

    def sinkhorn(self, Q, num_iters):
        with torch.no_grad():
            Q /= Q.sum()
            K, B = Q.shape
            u = torch.zeros(K, device=self.device)
            r = torch.ones(K, device=self.device) / K
            c = torch.ones(B, device=self.device) / B
            for _ in range(num_iters):
                u = Q.sum(dim=1)
                Q *= (r / u).unsqueeze(1)
                Q *= (c / Q.sum(dim=0)).unsqueeze(0)
            return (Q / Q.sum(dim=0, keepdim=True)).t().float()

    def distributed_sinkhorn(self, Q, nmb_iters):
        with torch.no_grad():
            sum_ = Q.sum()
            dist.all_reduce(sum_)

            K, B = Q.shape
            r = torch.ones(K).cuda(non_blocking=True) / K
            c = torch.ones(B).cuda(non_blocking=True) / (self.hparams.total_gpus * B)

            for _ in range(nmb_iters):
                sum_1 = Q.sum(dim=1)
                dist.all_reduce(sum_1)
                Q *= (r / sum_1).unsqueeze(1)
                Q *= (c / Q.sum(dim=0)).unsqueeze(0)
            return (Q / Q.sum(dim=0, keepdim=True)).t().float()

if __name__ == "__main__":
    pl.seed_everything(42)
    # [32, 16] for CIFAR10, [96, 36] for STL10 [224, 96] for ImageNet
    SIZE_CROPS = [32, 16]
    CROPS_FOR_ASSIGN = [0, 1]
    NUM_CROPS = [2, 1]  # [2, 1] for CIFAR10, [2, 4] for STL10, [2, 6] for ImageNet.
    # [0.33, 0.10] for CIFAR10 & STL10, [0.14, 0.05] for ImageNet
    MIN_SCALE_CROPS = [0.33, 0.10]
    MAX_SCALE_CROPS = [1, 0.33]
    USE_GAUSSIAN_BLUR = True  # False for CIFAR10, True for ImageNet & STL10
    JITTER_STRENGTH = 1.0
    DATA_DIR = "/home/tiankang/wusuowei/data/"
    BATCH_SIZE = 128
    DATAMODULE = CIFAR10DataModule
    transforms = get_swav_transform(
        means=DATAMODULE.means,
        stds=DATAMODULE.stds,
        size_crops=SIZE_CROPS,
        num_crops=NUM_CROPS,
        min_scale_crops=MIN_SCALE_CROPS,
        max_scale_crops=MAX_SCALE_CROPS,
        use_gaussian_blur=USE_GAUSSIAN_BLUR,
        jitter_strength=JITTER_STRENGTH,
    )
    datamodule = DATAMODULE(DATA_DIR, BATCH_SIZE, *transforms)

    BACKBONE_ARCH = "resnet50"
    FIRST_CONV = False  # False for CIFAR10 & STL10, True for ImageNet
    MAXPOOL1 = False  # False for CIFAR10 & STL10, True for ImageNet
    HIDDEN_MLP = 2048
    FEATURE_DIM = 128
    NUM_PROTOTYPES = [512]

    OPTIMIZER = "adam"  # 'adam' for CIFAR10 & STL10, 'lars' for ImageNet
    LR = 1e-3
    WEIGHT_DECAY = 1e-6
    EXCLUDE_BN_BIAS = True
    WARMUP_EPOCHS = 10
    MAX_EPOCHS = 100
    MAX_STEPS = -1

    NUM_SAMPLES = 50000  # 95_000 for STL10 mixed dataloader
    QUEUE_PATH = "queue"
    QUEUE_LENGTH = 0
    QUEUE_START_EPOCH = 15

    GPUS = [9]
    TOTAL_GPUS = len(GPUS) * 1  # I only have one node, sadly
    SINKHORN_ITERATIONS = 3
    EPSILON = 0.05
    TEMPERTURE = 0.1
    FREEZE_PROTOTYPES_EPOCHS = 1

    model = Net(
        backbone_arch=BACKBONE_ARCH,
        first_conv=FIRST_CONV,
        maxpool1=MAXPOOL1,
        hidden_mlp=HIDDEN_MLP,
        feature_dim=FEATURE_DIM,
        num_prototypes=NUM_PROTOTYPES,
        optimizer=OPTIMIZER,
        lr=LR,
        weight_decay=WEIGHT_DECAY,
        exclude_bn_bias=EXCLUDE_BN_BIAS,
        warmup_epochs=WARMUP_EPOCHS,
        max_epochs=MAX_EPOCHS,
        num_samples=NUM_SAMPLES,
        queue_length=QUEUE_LENGTH,
        queue_path=QUEUE_PATH,
        queue_start_epoch=QUEUE_START_EPOCH,
        dataset=DATAMODULE.name,
        total_gpus=TOTAL_GPUS,
        batch_size=BATCH_SIZE,
        crops_for_assign=CROPS_FOR_ASSIGN,
        num_crops=NUM_CROPS,
        sinkhorn_iterations=SINKHORN_ITERATIONS,
        epsilon=EPSILON,
        temperature=TEMPERTURE,
        freeze_prototypes_epochs=FREEZE_PROTOTYPES_EPOCHS,
    )

    callbacks = [
        LearningRateMonitor(logging_interval="step"),
        ModelCheckpoint(save_last=True, save_top_k=1, monitor="val_loss"),
        SSLOnlineEvaluator(
            dataset=DATAMODULE.name,
            z_dim=model.model.backbone.out_dim,
            hid_dim=None,
            num_classes=DATAMODULE.num_classes,
            drop_p=0.0,
        ),
    ]
    CHECKPOINT = ""
    FINETUNE = False
    if not CHECKPOINT:
        trainer = pl.Trainer(
            deterministic=True,
            max_epochs=MAX_EPOCHS,
            max_steps=None if MAX_STEPS == -1 else MAX_STEPS,
            gpus=GPUS,
            num_nodes=1,
            distributed_backend="ddp" if TOTAL_GPUS > 1 else None,
            sync_batchnorm=True if TOTAL_GPUS > 1 else False,
            precision=16,
            callbacks=callbacks,
            # fast_dev_run=True,
        )

        trainer.fit(model, datamodule=datamodule)
    else:
        if not FINETUNE:
            trainer = pl.Trainer(
                deterministic=True,
                resume_from_checkpoint=CHECKPOINT,
                max_epochs=MAX_EPOCHS,
                max_steps=None if MAX_STEPS == -1 else MAX_STEPS,
                gpus=GPUS,
                num_nodes=1,
                distributed_backend="ddp" if TOTAL_GPUS > 1 else None,
                sync_batchnorm=True if TOTAL_GPUS > 1 else False,
                precision=32,
                callbacks=callbacks,
                # fast_dev_run=True,
            )
            trainer.fit(model, datamodule=datamodule)
        else:
            raise NotImplementedError


from gitter_chat_recognition.link_checker import link_checker as link_checker
from googlesearch import search

def google_search(query_test):
    query = 'gitter ' + query_test
    my_results_list = []
    for i in search(query,  # The query you want to run
                    tld='com',  # The top level domain
                    lang='en',  # The language
                    num=10,  # Number of results per page
                    start=0,  # First result to retrieve
                    stop=3,  # Last result to retrieve
                    pause=2.0,  # Lapse between HTTP requests
                    ):
        if(i.find('https://gitter.im') != -1):
            my_results_list.append(i)
    for elem in my_results_list:
        link = elem.split('?')
        if link_checker(link[0], query_test) is not None:
            return link[0]
    return None


from django.urls import path
from . import views

app_name = "components"

urlpatterns = [
    path("about/",views.about_view,name="about"),
    path("contact/", views.contact_view, name="contact"),
    path("faq/",views.faq_view,name="faq"),
    # path("question/",views.faq_question,name="faqQuestion"),
    path('privacy_policy', views.privacy_policy, name='privacyPolicy'),
    path('terms_and_conditions', views.terms_and_conditions, name='termsAndConditions'),
]


from pyspark.sql import SparkSession
from pyspark.sql import Row
from pyspark.sql import SQLContext
from graphframes import *
import collections

def mapper(line):
    fields = line.split()
    return Row(userId=int(fields[0]),movieId=int(fields[1]),rating=int(fields[2]),timestamp=int(fields[3]))

spark = SparkSession.builder.appName("movieGraph").getOrCreate()
movie = lines.map(mapper)

schemaMovie = spark.createDataFrame(movie).cache()
schemaMovie.createOrReplaceTempView("movie")

movieWatchedByUser = spark.sql("SELECT userId,movieId from movie")
movieRatings = spark.sql("SELECT movieId,rating from movie")

g= GraphFrame(movieWatchedByUser,movieRatings)

print(g)

spark.stop()


from collections import deque
quantity = int(input())
names_queue = deque()
command = input()
while not command == "Start":
    names_queue.append(command)
    command = input()
command = input()
while not command == "End":
    if command.isdigit():
        command = int(command)
        if command <= quantity:
            print(f"{names_queue.popleft()} got water")
            quantity -= command
        else:
            print(f"{names_queue.popleft()} must wait")
    elif command.split()[0] == "refill":
        liters = int(command.split()[1])
        quantity += liters
    command = input()
print(f"{quantity} liters left")

Lists as Stacks and Queues/water_dispenser.py


#----------------------------------------------------------------------------#
# Imports
#----------------------------------------------------------------------------#
import json
import dateutil.parser
import babel
from flask import Flask, render_template, request, Response, flash, redirect, url_for
from flask_moment import Moment
from flask_sqlalchemy import SQLAlchemy
import logging
from logging import Formatter, FileHandler
from flask_wtf import Form
from forms import *
from flask_migrate import Migrate
import sys
from sqlalchemy import Date, cast
from datetime import date, datetime
import enum
from sqlalchemy import String, Integer, ARRAY,  func
#----------------------------------------------------------------------------#
# App Config.
#----------------------------------------------------------------------------#
app = Flask(__name__)
moment = Moment(app)
app.config.from_object('config')
db = SQLAlchemy(app)
#----------------------------------------------------------------------------#
# Migration.
#----------------------------------------------------------------------------#
migrate = Migrate(app, db)
#----------------------------------------------------------------------------#
# Models.
#----------------------------------------------------------------------------#
class Venue(db.Model):
    __tablename__ = 'venue'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
    city = db.Column(db.String(120))
    state = db.Column(db.String(120))
    address = db.Column(db.String(120))
    phone = db.Column(db.String(120))
    image_link = db.Column(db.String(500))
    facebook_link = db.Column(db.String(120))
    genres = db.Column(db.ARRAY(db.String()))
    website = db.Column(db.String(120))
    seeking_talent = db.Column(db.Boolean)
    seeking_description = db.Column(db.String(250))
    show = db.relationship('Show', backref='venue')
    # TODO: implement any missing fields, as a database migration using Flask-Migrate
class Artist(db.Model):
    __tablename__ = 'artist'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
    city = db.Column(db.String(120))
    state = db.Column(db.String(120))
    phone = db.Column(db.String(120))
    image_link = db.Column(db.String(500))
    genres = db.Column(db.ARRAY(db.String()))
    facebook_link = db.Column(db.String(120))
    website = db.Column(db.String(120))
    seeking_venue = db.Column(db.Boolean)
    seeking_description = db.Column(db.String(250))
    show = db.relationship('Show', backref='artist')
    # TODO: implement any missing fields, as a database migration using Flask-Migrate
class Show(db.Model):
    __tablename__ = 'show'
    id = db.Column(db.Integer, primary_key=True)
    start_time = db.Column(db.DateTime)
    venue_id = db.Column(db.Integer, db.ForeignKey('venue.id'), nullable=False)
    artist_id = db.Column(db.Integer, db.ForeignKey('artist.id'), nullable=False)
# TODO Implement Show and Artist models, and complete all model relationships and properties, as a database migration.
#----------------------------------------------------------------------------#
# Filters.
#----------------------------------------------------------------------------#
def format_datetime(value, format='medium'):
  date = dateutil.parser.parse(value)
  if format == 'full':
      format="EEEE MMMM, d, y 'at' h:mma"
  elif format == 'medium':
      format="EE MM, dd, y h:mma"
  return babel.dates.format_datetime(date, format)
app.jinja_env.filters['datetime'] = format_datetime
#----------------------------------------------------------------------------#
# Controllers.
#----------------------------------------------------------------------------#
@app.route('/')
def index():
  return render_template('pages/home.html')
#  Genres
#----------------------------------------------------------------------------#
# @app.route('/artists/create', methods=['GET'])
# def list_genres():
#   genres = Genre.query.all()
#   return render_template('forms/new_artist.html', genres=genres)
#  Venues
#  ----------------------------------------------------------------
@app.route('/venues')
def venues():
  # TODO: replace with real venues data.
  #  num_shows should be aggregated based on number of upcoming shows per venue.
  # check how you are passing your data, into which jinja part?
  venue_group_by_city= Venue.query.with_entities(func.count(Venue.id), Venue.city, Venue.state).group_by(Venue.city, Venue.state).all()
  data = []
  dateToday = datetime.now()
  for result_venues in venue_group_by_city:
    venues = Venue.query.filter_by(city= result_venues.city).filter_by(state = result_venues.state).all()
    venues_shows = []
    for x in venues:
      if (result_venues.city == x.city) and (result_venues.state == x.state):
        shows = Show.query.filter_by(venue_id =x.id).all()
        num = 0
        for show in shows:
          if show.start_time >= dateToday:
            num =+ 1
      venues_shows.append({
              "id": x.id,
              "name": x.name,
              "upcoming_show": num
          })
    data.append({
          "city" : result_venues.city,
          "state" : result_venues.state,
           "venues" : venues_shows
          })
  return render_template('pages/venues.html', areas=data)
@app.route('/venues/search', methods=['POST'])
def search_venues():
  # TODO: implement search on artists with partial string search. Ensure it is case-insensitive.
  # seach for Hop should return "The Musical Hop".
  # search for "Music" should return "The Musical Hop" and "Park Square Live Music & Coffee"
  search_term = request.form.get('search_term','')
  value = Venue.query.filter(Venue.name.ilike('%'+search_term+'%')).all()
  response = {
    "count": len(value),
    "data": value
  }
  return render_template('pages/search_venues.html', results=response, search_term=search_term)
@app.route('/venues/<int:venue_id>')
def show_venue(venue_id):
  # shows the venue page with the given venue_id
  # TODO: replace with real venue data from the venues table, using venue_id
  data = []
  past_shows =[]
  upcoming_shows = []
  dateToday = datetime.now()
  select_venue_by_id=Venue.query.get(venue_id)
  shows=Show.query.filter_by(venue_id=venue_id).all()
  for show in shows:
    if show.start_time >= dateToday:
      upcoming_shows.append({
      "artist_id": show.artist_id,
      "artist_name": Artist.query.filter_by(id=show.artist_id).first().name,
      "artist_image_link":Artist.query.filter_by(id=show.artist_id).first().image_link ,
      "start_time": show.start_time })
    else:
      past_shows.append({
      "artist_id": show.artist_id,
      "artist_name": Artist.query.filter_by(id=show.artist_id).first().name,
      "artist_image_link":Artist.query.filter_by(id=show.artist_id).first().image_link ,
      "start_time": show.start_time })
  # shows the venue page with the given venue_id
  # TODO: replace with real venue data from the venues table, using venue_id
  data = {
    "id": select_venue_by_id.id,
    "name": select_venue_by_id.name,
    "genres": select_venue_by_id.genres ,
    "address": select_venue_by_id.address,
    "city": select_venue_by_id.city,
    "state": select_venue_by_id.state,
    "phone": select_venue_by_id.phone,
    "website": select_venue_by_id.website,
    "facebook_link": select_venue_by_id.facebook_link,
    "seeking_talent": True,
    "seeking_description": select_venue_by_id.seeking_description,
    "image_link": select_venue_by_id.image_link ,
    "past_shows":past_shows,
    "upcoming_shows": upcoming_shows,
    "past_shows_count": len(past_shows),
    "upcoming_shows_count": len(upcoming_shows)
  }
  return render_template('pages/show_venue.html', venue=data)
#  Create Venue
#  ----------------------------------------------------------------
@app.route('/venues/create', methods=['GET'])
def create_venue_form():
  form = VenueForm()
  return render_template('forms/new_venue.html', form=form)
@app.route('/venues/create', methods=['POST'])
def create_venue_submission():
  # TODO: insert form data as a new Venue record in the db, instead
  # TODO: modify data to be the data object returned from db insertion
  error = False
  try:
    name = request.form.get('name', '')
    city=request.form.get('city', '')
    state=request.form.get('state', '')
    address=request.form.get('address', '')
    phone=request.form.get('phone', '')
    image_link=request.form.get('image_link', '')
    genres= request.form.getlist('genres',)
    facebook_link=request.form.get('facebook_link', '')
    venue = Venue(name=name, city=city, state=state, address=address,
                phone=phone, image_link=image_link, genres=genres,
                facebook_link=facebook_link)
    db.session.add(venue)
    db.session.commit()
  # on successful db insert, flash success
    flash('Venue ' + request.form['name'] + ' was successfully listed!')
  # TODO: on unsuccessful db insert, flash an error instead.
  # e.g., flash('An error occurred. Venue ' + data.name + ' could not be listed.')
  # see: http://flask.pocoo.org/docs/1.0/patterns/flashing/
  except:
    error = True
    db.session.rollback()
    flash('An error occurred.'+ name +' Venue  could not be listed.')
    print(sys.exc_info())
  finally:
    db.session.close()
  return render_template('pages/home.html')
@app.route('/venues/<venue_id>', methods=['DELETE'])
def delete_venue(venue_id):
  # TODO: Complete this endpoint for taking a venue_id, and using
  # SQLAlchemy ORM to delete a record. Handle cases where the session commit could fail.
  try:
   venue = Venue.query.get(venue_id)
   db.session.delete(venue)
   db.session.commit()
  except:
    db.session.rollback()
  finally:
    db.session.close()
  # BONUS CHALLENGE: Implement a button to delete a Venue on a Venue Page, have it so that
  # clicking that button delete it from the db then redirect the user to the homepage
  return None
#  Artists
#  ----------------------------------------------------------------
@app.route('/artists')
def artists():
  # TODO: replace with real data returned from querying the database
  data= Artist.query.all()
  return render_template('pages/artists.html', artists=data)
@app.route('/artists/search', methods=['POST'])
def search_artists():
  # TODO: implement search on artists with partial string search. Ensure it is case-insensitive.
  # seach for "A" should return "Guns N Petals", "Matt Quevado", and "The Wild Sax Band".
  # search for "band" should return "The Wild Sax Band".
  search_term = request.form.get('search_term','')
  value = Artist.query.filter(Artist.name.ilike('%'+search_term+'%')).all()
  response={
    "count": len(value),
    "data": value
  }
  return render_template('pages/search_artists.html', results=response, search_term=search_term)
@app.route('/artists/<int:artist_id>')
def show_artist(artist_id):
  # shows the venue page with the given venue_id
  # TODO: replace with real venue data from the venues table, using venue_id
  data = []
  past_shows = []
  upcoming_shows = []
  dateToday= datetime.now()
  shows = Show.query.filter_by(artist_id=artist_id).all()
  select_artist_by_id = Artist.query.get(artist_id)
  for show in shows:
    if show.start_time >= dateToday:
      upcoming_shows.append({
        "venue_id" : show.venue_id,
        "venue_name" : Venue.query.filter_by(id=show.venue_id).first().name,
        "venue_image_link" : Venue.query.filter_by(id=show.venue_id).first().image_link ,
        "start_time": show.start_time
        })
    else:
      past_shows.append({
      "venue_id" : show.venue_id,
      "venue_name" : Venue.query.filter_by(id=show.venue_id).first().name,
      "venue_image_link" : Venue.query.filter_by(id=show.venue_id).first().image_link ,
      "start_time": show.start_time
      })
  data = ({
    "id": select_artist_by_id.id,
    "name": select_artist_by_id.name,
    "genres": select_artist_by_id.genres,
    "city": select_artist_by_id.city,
    "state": select_artist_by_id.state,
    "phone": select_artist_by_id.phone,
    "website": select_artist_by_id.website,
    "facebook_link": select_artist_by_id.facebook_link,
    "seeking_venue": True,
    "seeking_description": select_artist_by_id.seeking_description,
    "image_link": select_artist_by_id.image_link ,
    "past_shows":past_shows,
    "upcoming_shows": upcoming_shows,
    "past_shows_count": len(past_shows),
    "upcoming_shows_count": len(upcoming_shows)
  })
  return render_template('pages/show_artist.html', artist = data)
#  Update
#  ----------------------------------------------------------------
@app.route('/artists/<int:artist_id>/edit', methods=['GET'])
def edit_artist(artist_id):
  artist = Artist.query.get(artist_id)
  form = ArtistForm()
  form.name.data = artist.name
  form.genres.data = artist.genres
  form.city.data = artist.city
  form.state.data = artist.state
  form.phone.data = artist.phone
  form.facebook_link.data = artist.facebook_link
  form.image_link.data = artist.image_link
  artist = {
    "id": artist.id,
    "name": artist.name,
    "genres": artist.genres,
    "city": artist.city,
    "state": artist.state,
    "phone": artist.phone,
    "facebook_link": artist.facebook_link,
    "image_link" :  artist.image_link
  }
  # TODO: populate form with fields from artist with ID <artist_id>
  return render_template('forms/edit_artist.html', form=form, artist=artist)
@app.route('/artists/<int:artist_id>/edit', methods=['POST'])
def edit_artist_submission(artist_id):
  # TODO: take values from the form submitted, and update existing
  # artist record with ID <artist_id> using the new attributes
  try:
    name = request.form.get('name', '')
    city=request.form.get('city', '')
    state=request.form.get('state', '')
    address=request.form.get('address', '')
    phone=request.form.get('phone', '')
    image_link=request.form.get('image_link', '')
    genres= request.form.getlist('genres',)
    facebook_link=request.form.get('facebook_link', '')
    artist = Artist.query.get(artist_id)
    artist.name = name
    artist.city = city
    artist.state = state
    artist.address = address
    artist.phone = phone
    artist.image_link = image_link
    artist.genres = genres
    artist.facebook_link = facebook_link
    db.session.commit()
    flash(' The artist information updated successfully')
  except:
    db.session.rollback()
  finally:
    db.session.close()
  return redirect(url_for('show_artist', artist_id=artist_id))
@app.route('/venues/<int:venue_id>/edit', methods=['GET'])
def edit_venue(venue_id):
  form = VenueForm()
  venue = Venue.query.get(venue_id)
  form.name.data = venue.name
  form.genres.data = venue.genres
  form.city.data = venue.city
  form.state.data = venue.state
  form.address.data = venue.address
  form.phone.data = venue.phone
  form.facebook_link.data = venue.facebook_link
  venue = {
    "id": venue.id,
    "name": venue.name,
    "genres": venue.genres,
    "city": venue.city,
    "state": venue.state,
    "address": venue.address,
    "phone": venue.phone,
    "facebook_link": venue.facebook_link
  }
  # TODO: populate form with values from venue with ID <venue_id>
  return render_template('forms/edit_venue.html', form=form, venue=venue)
@app.route('/venues/<int:venue_id>/edit', methods=['POST'])
def edit_venue_submission(venue_id):
  # TODO: take values from the form submitted, and update existing
  # venue record with ID <venue_id> using the new attributes
  try:
    name = request.form.get('name', '')
    city=request.form.get('city', '')
    state=request.form.get('state', '')
    address=request.form.get('address', '')
    phone=request.form.get('phone', '')
    genres=request.form.get('genres', '')
    facebook_link=request.form.get('facebook_link', '')
    venue = Venue.query.get(venue_id)
    venue.name = name
    venue.city = city
    venue.state = state
    venue.address = address
    venue.phone = phone
    venue.genres = genres
    venue.facebook_link = facebook_link
    db.session.commit()
    flash(' The venue information updated successfully')
  except:
    db.session.rollback()
  finally:
    db.session.close()
  return redirect(url_for('show_venue', venue_id=venue_id))
#  Create Artist
#  ----------------------------------------------------------------
@app.route('/artists/create', methods=['GET'])
def create_artist_form():
  form = ArtistForm()
  return render_template('forms/new_artist.html', form=form)
@app.route('/artists/create', methods=['POST'])
def create_artist_submission():
  # called upon submitting the new artist listing form
  # TODO: insert form data as a new Venue record in the db, instead
  # TODO: modify data to be the data object returned from db insertion
  error = False
  try:
    name=request.form.get('name', '')
    city=request.form.get('city', '')
    state=request.form.get('state', '')
    phone=request.form.get('phone', '')
    image_link=request.form.get('image_link', '')
    genres=request.form.getlist('genres')
    facebook_link=request.form.get('facebook_link', '')
    artist=Artist(name=name, city=city, state=state, phone=phone,
                  image_link=image_link, genres=genres, facebook_link=facebook_link)
    db.session.add(artist)
    db.session.commit()
  # on successful db insert, flash success
    flash('Artist ' + name + ' was successfully listed!')
  # TODO: on unsuccessful db insert, flash an error instead.
  # e.g., flash('An error occurred. Artist ' + data.name + ' could not be listed.')
  except:
    error = True
    db.session.rollback()
    print(sys.exc_info())
  # TODO: on unsuccessful db insert, flash an error instead.
  # e.g., flash('An error occurred. Artist ' + data.name + ' could not be listed.')
    flash('An error occurred. Artist ' + name + ' could not be listed.')
  finally:
    db.session.close()
  return render_template('pages/home.html')
#  ----------------------------------------------------------------
#  Shows
#  ----------------------------------------------------------------
@app.route('/shows')
def shows():
  # displays list of shows at /shows
  # TODO: replace with real venues data.
  #       num_shows should be aggregated based on number of upcoming shows per venue.
  data = []
  select_all_show = Show.query.all()
  for shows in select_all_show:
    select_by_venue_id= Venue.query.get(shows.venue_id)
    select_by_artist_id= Artist.query.get(shows.artist_id)
    data.append({
    'id' : shows.venue_id,
    'venue_name' : select_by_venue_id.name,
    'artist_id' : shows.venue_id,
    'artist_name' : select_by_artist_id.name,
    'artist_image_link' : select_by_artist_id.image_link,
    'start_time' : shows.start_time
  })
  return render_template('pages/shows.html', shows=data)
@app.route('/shows/create')
def create_shows():
  # renders form. do not touch.
  form = ShowForm()
  return render_template('forms/new_show.html', form=form)
@app.route('/shows/create', methods=['POST'])
def create_show_submission():
  # called to create new shows in the db, upon submitting new show listing form
  # TODO: insert form data as a new Show record in the db, instead
  error= False
  try:
    artist_id=request.form.get('artist_id')
    venue_id=request.form.get('venue_id')
    start_time=request.form.get('start_time')
    show=Show(artist_id=artist_id, venue_id=venue_id, start_time=start_time)
    db.session.add(show)
    db.session.commit()
  # on successful db insert, flash success
    flash('Show was successfully listed!')
  # TODO: on unsuccessful db insert, flash an error instead.
  # e.g., flash('An error occurred. Show could not be listed.')
  # see: http://flask.pocoo.org/docs/1.0/patterns/flashing/
  except:
    error = True
    db.session.rollback()
    print(sys.exc_info())
    # TODO: on unsuccessful db insert, flash an error instead.
    # e.g., flash('An error occurred. Artist ' + data.name + ' could not be listed.')
    flash('An error occurred. Artist  could not be listed.')
  finally:
    db.session.close()
  return render_template('pages/home.html')
@app.errorhandler(404)
def not_found_error(error):
    return render_template('errors/404.html'), 404
@app.errorhandler(500)
def server_error(error):
    return render_template('errors/500.html'), 500
if not app.debug:
    file_handler = FileHandler('error.log')
    file_handler.setFormatter(
        Formatter('%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]')
    )
    app.logger.setLevel(logging.INFO)
    file_handler.setLevel(logging.INFO)
    app.logger.addHandler(file_handler)
    app.logger.info('errors')
#----------------------------------------------------------------------------#
# Launch.
#----------------------------------------------------------------------------#
# Default port:
if __name__ == '__main__':
    app.run()
# Or specify port manually:
'''
if __name__ == '__main__':
    port = int(os.environ.get('PORT', 5000))
    app.run(host='0.0.0.0', port=port)
'''


endereco = "Rua das flores 72, apartamento 1002, laranjeiras, Rio de Janeiro, RJ, 23440-120"

#RegEx
import re

# 5 digitos + "-"(opcional) + 3 digitos

padrao = re.compile("[0-9]{5}[-]{0,1}[0-9]{3}")
busca = padrao.search(endereco) # Math

if busca:
    cep = busca.group()
    print(cep)


import FWCore.ParameterSet.Config as cms
from PhysicsTools.HplusCode_v5.variables_cfg import isjerup, isjerdown, isjesup, isjesdown

print( 'isJERup ' ,  isjerup)
print( 'isJERdown ', isjerdown)
print( 'isJESup ',   isjesup)
print( 'isJESdown ', isjesdown)

###
## JETS SELECTIONS
##
from PhysicsTools.HplusCode_v5.userDataJetsProducer_cfi import *
goodJets = topJetsPF.clone(
src = 'goodPatJetsPFlow',
cut =
'pt > 10 & abs(eta)<=2.5',
#'pt > 10 & abs(eta)<=5.2',
muonsSrc ='tightMuons',
isJERup    = isjerup,
isJERdown  = isjerdown,
isJESup    = isjesup,
isJESdown  = isjesdown,
removeOverlap= False,
isData=True
)

bJets = topJetsPF.clone(
src = 'goodPatJetsPFlow',
cut =
'pt > 10  & abs(eta)<=2.5 & '
#'pt > 10  & abs(eta)<=5.2 & '
'bDiscriminator("combinedSecondaryVertexBJetTags") > 0.679 ',
muonsSrc ='tightMuons',
isJERup    = isjerup,
isJERdown  = isjerdown,
isJESup    = isjesup,
isJESdown  = isjesdown,
removeOverlap= False,
isData=True
)

##
## MET SELECTIONS
##
from PhysicsTools.HplusCode_v5.userDataMETsProducer_cfi import *
goodMETs = topMETsPF.clone(
metsSrc ='patMETsPFlow',
jetsSrc ='goodPatJetsPFlow',
isJERup    = isjerup,
isJERdown  = isjerdown,
isJESup    = isjesup,
isJESdown  = isjesdown
)

topSINCROJetSelection = cms.Sequence(
goodJets *
bJets *
goodMETs
)


import datetime

import colander
import mock
import pytest

from moisturizer.schemas import InferredObjectSchema, InferredTypeSchema

@pytest.fixture()
def freeze_now(scope="module"):
    value = datetime.datetime.now()
    yield value

@pytest.fixture()
def object_payload(freeze_now):
    return {
        'id': 'MyType',
        'last_modified': str(freeze_now),
        'foo': '42',
    }

@pytest.fixture()
def invalid_object_payload():
    return {
        'id': 'MyType',
        'last_modified': 'a long time ago',
    }

@pytest.fixture()
def type_payload(object_payload, freeze_now):
    return {
        'properties': {
            'foo': {
                'type': 'string',
                'index': True,
            }
        },
        **object_payload  # noqa
    }

@pytest.fixture()
def invalid_type_payload():
    return {
        'properties': {
            'foo': {
                'type': 'pancakes',
                'index': 42,
            }
        },
    }

class TestInferredSchema(object):

    def test_free_schema(self, object_payload, freeze_now):
        result = InferredObjectSchema().deserialize({})
        expected = {
            'id': result['id'],
            'last_modified': freeze_now,
            'foo': '42',
        }
        assert result == expected

    def test_validate_known_fields(self, invalid_object_payload):
        with pytest.raises(colander.Invalid):
            InferredObjectSchema().deserialize(invalid_object_payload)

    def test_defer_fields(self, object_payload, freeze_now):
        schema = InferredSchema().bind(
            fields={
                'foo': colander.SchemaNode(colander.String())
            }
        )
        result = schema.deserialize(object_payload)
        expected = {
            'id': result['id'],
            'last_modified': freeze_now,
            'foo': '42',
        }
        assert result == expected

        invalid = {**expected}
        invalid['foo'] = True
        with pytest.raises(colander.Invalid):
            result = schema.deserialize(invalid)

class TestTypeSchema(object):

    def test_serialize_type_schema(self, type_payload, freeze_now):
        result = InferredTypeSchema().deserialize(type_payload)
        expected = {
            'id': result['id'],
            'last_modified': freeze_now,
            'foo': '42',
            'properties': {
                'foo': {
                    'type': 'string',
                    'index': True,
                }
            },
        }
        assert result == expected

    def test_validate_type_schema(self, invalid_type_payload):
        with pytest.raises(colander.Invalid):
            InferredTypeSchema().deserialize(invalid_type_payload)


from __future__ import print_function

import re

from sympy.parsing.sympy_parser import (parse_expr, standard_transformations, implicit_application,
                                        implicit_multiplication)

symbol_map = {
    '^': '**',
    'Ln': 'log ',
    'Sin': 'sin ',
    'Cos': 'cos '
}

def translate(bad_text):
    """My custom string-to-Equation-ready SymPy expression translation function

    Arguments:
        bad_text (str): text that is in some bad format that requires string manipulation
            including custom string modifications to math functions, symbols, and operators
            defined by the global symbol_map dictionary (for substitutions), and the regexs
            compiled herein. More advanced manipulations providied by SymPy are defined by
            the global variable `transformations` are inputs to the SymPy parser
    Returns:
        expr (sympy expression): A SymPy expresion created by the SymPy expression parser
            after first doing custom string modifications to math functions, symbols, and operators
    """
    to_symbols = re.compile('|'.join(re.escape(key) for key in symbol_map.keys()))
    bad_text = to_symbols.sub(lambda x: symbol_map[x.group()], bad_text)
    bad_text = re.sub('\n', '', bad_text)
    text = re.sub(r"\s+a(\d)", r"a_\1", bad_text)
    transformations = standard_transformations + (implicit_multiplication, implicit_application)
    expr = parse_expr(text, transformations=transformations)
    return expr


"""
oyoneによるデータ収集の非常用ファイル
もし、モーターおよびArduinoがだめになったとしても
カメラとラズパイさえ生きていれば撮影ができるようにする
"""

import cv2
import save_sensor_img

FRAME_WIDTH = 2592  # MAX 2592
FRAME_HEIGHT = 1944 # MAX 1944

data_saver = save_sensor_img.Data_Saver(save_video=True, save_sensor=True)
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, FRAME_WIDTH)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, FRAME_HEIGHT)
while True:
    ret, frame = cap.read()
    key = cv2.waitKey(1)
    sensor_dict = None
    data_saver.save(frame, sensor_dict, '-')


#coding:utf-8
"""
    wanzifa_blog
    this is my personal blog~~~ðŸ˜„
"""

import sys
import os
from flask import Flask, render_template
from flask_flatpages import FlatPages
from flask_frozen import Freezer
from flask_script import Manager, Shell

DEBUG = True
FLATPAGES_AUTO_RELOAD = DEBUG
FLATPAGES_EXTENSION = '.md'

app = Flask(__name__)
app.config.from_object(__name__)
pages = FlatPages(app)
freezer = Freezer(app)

manager = Manager(app)

def make_shell_context():
    manager.add_command("shell", Shell(make_context=make_shell_context))

@app.route("/wanzifa/")
def index():
    return render_template('index_b.html')

@app.route('/blog/')
def blog():
    articles = (p for p in pages if 'date' in p.meta)
    latest = sorted(articles, key=lambda p: p.meta['date'], reverse=True)
    return render_template('blog.html', pages=latest)

@app.route('/<path:path>/')
def page(path):
    page = pages.get_or_404(path)
    return render_template('page.html', page=page)

if __name__ == '__main__':
    if len(sys.argv) > 1 and sys.argv[1] == 'build':
        freezer.freeze()
    else:
        manager.run()


class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        if not nums:
            return 0
        dp = [1] * len(nums)
        maxLen = 1
        for j in range(1, len(nums)):
            for i in range(j):
                if nums[j] > nums[i]:
                    dp[j] = max(dp[j], dp[i] + 1)
            maxLen = max(maxLen, dp[j])
        return maxLen

import bisect
class Solution2:
    def lengthOfLIS(self, nums: List[int]) -> int:
        if not nums:
            return 0

        lis = [nums[0]]
        for num in nums[1:]:
            if num > lis[-1]:
                lis.append(num)
            else:
                index = bisect.bisect_left(lis, num)
                lis[index] = num
        return len(lis)

0201-0300/0300-Longest Increasing Subsequence/0300-Longest Increasing Subsequence.py


inp = open('fivegmcheck.txt')

out = open('fivegmgames.txt', 'w')

def convert_alg_to_red(move):
    move = move.replace('x', '')
    move = move.replace('+', '')
    move = move.replace('#', '')
    final = move
    if '=' in move:
        equal_ind = move.index('=')
        final = move[:equal_ind]
    if len(final) == 4:
        final = final[0] + final[2:]
    if len(final) == 3 and final[0] in {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}:
        final = final[1:]
    return final

if __name__ == '__main__':
    for g, moves in enumerate(inp):
        moves = moves.replace('x', '')
        moves = moves.replace('+', '')
        moves = moves.replace('#', '')
        moves = moves.replace('\n', '')
        move_list = moves.split(' ')
        flag = False
        if not moves:
            continue
        for i, move in enumerate(move_list):
            if move[0] == 'P':
                flag = True
                break
            final = move
            if '=' in move:
                equal_ind = move.index('=')
                final = move[:equal_ind]
            if len(final) == 4:
                final = final[0] + final[2:]
            if len(final) == 3 and final[0] in {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}:
                final = final[1:]
            move_list[i] = final
        if(flag):
            continue

        moves = " ".join(move_list)
        out.write(moves)
        out.write("\n")
        if g % 100 == 0:
            print(f"game {g}")


import setuptools

with open("README.md", "r", encoding="utf-8") as fh:
    long_description = fh.read()

setuptools.setup(
    name="scraper",
    version="1.0.0",
    author="Gediminas Šimavičius",
    author_email="gediminas.simavicius@gmail.com",
    description="Package for scraping value.today website.",
    long_description=long_description,
    long_description_content_type="text/markdown",
    url="https://github.com/Gedas-LT/value.today-web-scraper",
    install_requires=[
        "beautifulsoup4",
        "fake-useragent",
        "pandas",
        "pytest",
        "requests"
    ],
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    packages=setuptools.find_packages(),
    python_requires=">=3.6",
)


import logging
import warnings
from copy import deepcopy
from datetime import datetime, timedelta
from datetime import time
from pathlib import Path
from tkinter.filedialog import askopenfilenames, askopenfilename
from tkinter.messagebox import showerror

import numpy as np
import pandas as pd
import utm
from tqdm import tqdm

from src.magrnd.ground_one.data_processing.consts import GZ_DIR, EXPECTED_TIMESTAMP_LEN, IA_SAMPLE_RATE_HZ, WINDOW_TITLE, \
    VALIDATED_STR
from src.magrnd.ground_one.loaders.file_identifier import identify_scan
from src.magrnd.ground_one.loaders.ia_file_encoding_fixer import fix_encoding
from src.mag_utils.mag_utils.functional import validator
from src.mag_utils.mag_utils.functional.mag_eili_converter import magmap_file_reformatter
from src.mag_utils.mag_utils.loader import blackwidow, base
from src.mag_utils.mag_utils.loader import main_load
from src.mag_utils.mag_utils.scans import AluminumManScan
from src.mag_utils.mag_utils.scans import magScan, HorizontalScan

warnings.filterwarnings("ignore")

def mag_utils_wrapper_func(path_to_scan_file: Path, scan_type):
    SCAN_TYPE_MAPPING = {"widow": blackwidow,
                         "base": base}

    # create gz dir if does not exist
    if not GZ_DIR.exists():
        GZ_DIR.mkdir()

    # hide logging
    logger = logging.getLogger("mag_utils.functional.logger")
    logger.setLevel(logging.INFO)

    # perform validation of data
    validated_file_path = GZ_DIR / "validated.txt"

    # scan_type_object = base

    validator.validate(file_to_validate_path=str(path_to_scan_file),
                       validated_file_path=str(validated_file_path),
                       log_file_path=str(GZ_DIR / "faulty_lines_log.txt"),
                       file_type=scan_type)

    scan = SCAN_TYPE_MAPPING[scan_type].load(validated_file_path.__str__())

    # delete validated file
    validated_file_path.unlink()
    scan.file_name = str(path_to_scan_file)
    return scan

def auto_format_time(time_str: str):
    if time_str is None:
        return
    # remove 1900-01-01 from old GZ IA files
    if '1900-' in time_str:
        time_str = time_str[11:]
    if ":" not in time_str:
        # determine if time is valid, and if not make it valid
        zeros_string = '0' * (6 - len(time_str[:time_str.rindex('.')]))
        time_str = (zeros_string + time_str)
        ms_s = "" if "." not in time_str else time_str[time_str.index(".") + 1:]

        # extract time data from string
        microsecond = int(
            float(ms_s) * 10 ** (EXPECTED_TIMESTAMP_LEN - len(
                ms_s))) if ms_s else 0  # for taking only first 6 digits after the decimal
        hour, minute, second = time_str[:2], time_str[2:4], time_str[4:time_str.index(".")]
    else:
        hour, minute, second = tuple(time_str.split(":"))
        second, microsecond = tuple(second.split(".")) if "." in second else (second, 0)

    return time(hour=int(hour),
                minute=int(minute),
                second=int(second),
                microsecond=int(microsecond))

def load_gz(path_to_scan_file: Path):
    # save original format time function to undo change later
    original_format_time_function = blackwidow.format_time

    # set to use custom function
    blackwidow.format_time = auto_format_time

    # load scan
    scan = blackwidow.lab_txt_format_loader(str(path_to_scan_file))

    # return format time to original state
    blackwidow.format_time = original_format_time_function

    return scan

def load_widow(path_to_scan_file: Path):
    return mag_utils_wrapper_func(path_to_scan_file, "widow")

def load_base(path_to_scan_file: Path):
    return mag_utils_wrapper_func(path_to_scan_file, "base")

def load_ia_raw(path_to_scan_file: Path, path_to_calib_file=None):  # todo: work with mike

    """
    :param path: str scan file path
    :return: ia matrix of bx,by,height,time
    """

    ## LOAD IA DATA ##

    # read all gps data
    gps_df = pd.read_csv(path_to_scan_file, delimiter=',', skiprows=3, names=list(range(15)), skipfooter=2,
                         error_bad_lines=True)
    gps_df = gps_df.iloc[gps_df[1].dropna().index, :]

    # read all sensor data
    b_df = pd.read_csv(path_to_scan_file, delimiter=' ', skiprows=3, names=list(range(8)), skipfooter=2,
                       error_bad_lines=True)
    b_df = b_df.iloc[b_df[7].dropna().index, :]

    gps_df.iloc[:, 2] = gps_df.iloc[:, 2].interpolate()
    gps_df.iloc[:, 4] = gps_df.iloc[:, 4].interpolate()

    height = gps_df.iloc[:, 9].values

    # handle time format
    time = gps_df.iloc[:, 1].values
    time_s = [t.zfill(8) for t in time.astype(str)]
    t_seconds = np.array([int(t[:2]) * 3600 + int(t[2:4]) * 60 + float(t[4:]) for t in
                          time_s])  # time in seconds and not H:M:S

    # find if there is a day transfer within scan
    diff_t = np.diff(t_seconds)
    if any(diff_t < 0):
        next_day_index, = np.where(diff_t < 0)[0]
        t_seconds[next_day_index + 1:] += 3600 * 24

    gps_index = b_df.iloc[:, 2].values

    vectorized_translate_gps = np.vectorize(blackwidow.translate_gps)
    x_utm, y_utm = vectorized_translate_gps(gps_df.iloc[:, 4].values, gps_df.iloc[:, 2].values)

    sensor_df_new = pd.DataFrame({'bx': b_df.iloc[:, 5],
                                  'by': b_df.iloc[:, 6],
                                  'bz': b_df.iloc[:, 7],
                                  'gps_index': gps_index})
    gps_df_new = pd.DataFrame(
        {'x': x_utm,
         'y': y_utm,
         'height': height,
         'time': t_seconds})

    sensor_df_new = sensor_df_new.append({'x': None, 'y': None, 'height': None, 'time': None},
                                         ignore_index=True)

    # merging gps and b ia data and interpolating data
    groups = sensor_df_new.groupby('gps_index')
    ia_data_matrix = pd.DataFrame()
    index_for_adding_gps = 0

    for group in tqdm(groups):
        if index_for_adding_gps >= len(gps_df_new['x']):
            pass
        else:
            index_for_group = group[1].index[0]
            group[1]['x'][index_for_group] = gps_df_new['x'][index_for_adding_gps]
            group[1]['y'][index_for_group] = gps_df_new['y'][index_for_adding_gps]
            group[1]['height'][index_for_group] = gps_df_new['height'][index_for_adding_gps]
            group[1]['time'][index_for_group] = gps_df_new['time'][index_for_adding_gps]

        ia_data_matrix = pd.concat([ia_data_matrix, group[1]])
        index_for_adding_gps += 1
    ia_data_matrix.drop(columns='gps_index', inplace=True)
    ia_data_matrix = ia_data_matrix.astype('float64').interpolate()

    # translate numbers back to time
    ia_data_matrix["time"] = [
        (datetime(year=1970, month=1, day=1, hour=0, minute=0, second=0) + timedelta(seconds=t)).time() for t in
        ia_data_matrix["time"]]

    ## CALIBRATE
    from src.magrnd.ground_one.data_processing.ia_calibration import apply_ia_calib
    calib_xyz = apply_ia_calib(ia_data_matrix, path_to_calib_file)
    ia_data_matrix["B"] = np.linalg.norm(calib_xyz, axis=1)

    if path_to_calib_file is None:
        return ia_data_matrix

    return magScan(file_name=str(path_to_scan_file),
                   x=ia_data_matrix['x'],
                   y=ia_data_matrix['y'],
                   a=ia_data_matrix['height'],
                   b=ia_data_matrix['B'],
                   time=ia_data_matrix['time'],
                   is_base_removed=True)

def load_ia_calibrated(path_to_scan_file: Path):
    df = pd.read_csv(path_to_scan_file, delimiter=r"\s+")
    vectorized_from_latlon = np.vectorize(utm.from_latlon)
    gps = vectorized_from_latlon(df["Latitude"], df["Longitude"], 36)

    return magScan(file_name=str(path_to_scan_file),
                   x=gps[0],
                   y=gps[1],
                   a=df['Altitude'],
                   b=df['MagneticField'],
                   time=df['Time'],
                   is_base_removed=False)

def universal_loader(path_to_scan_file: Path, path_to_calib_file: Path = None):
    # fix file encoding if needed
    fix_encoding(path_to_scan_file, path_to_calib_file)

    scan_type = identify_scan(path_to_scan_file)
    if scan_type == "widow":
        return load_widow(path_to_scan_file)
    elif scan_type == "base":
        return load_base(path_to_scan_file)
    elif scan_type == "ia_raw":
        # if path to calib file was not passed, ask user to provide it
        if path_to_calib_file is None:
            path_to_calib_file = Path(askopenfilename(title="Select calibration file"))
        scan = load_ia_raw(path_to_scan_file, path_to_calib_file)
        scan.sampling_rate = IA_SAMPLE_RATE_HZ
        return scan
    elif scan_type == "ia_calibrated":
        return load_ia_calibrated(path_to_scan_file)
    elif scan_type == "gz":
        return load_gz(path_to_scan_file)
    else:
        showerror(WINDOW_TITLE, "File type not recognized. Please try again")
        raise NotImplementedError

def load(scan_paths: list = None):
    if scan_paths is None:
        scan_paths = [Path(file_path) for file_path in
                      askopenfilenames(title="Select file",
                                       filetypes=[("All Files", "*.*")])]

    # if one file is selected, make it the scan path, else opt for vertical scan loading
    if isinstance(scan_paths, Path):
        scan_paths = [scan_paths]

    if not len(scan_paths):
        raise ValueError("Invalid number of files selected.")

    loaded_scans = []
    for scan_path in scan_paths:
        # handle mag eili files
        if scan_path.suffix == ".dat":
            scan_path = magmap_file_reformatter(scan_path)

        # try loading thru main_load, if unsuccessful, use universal loader
        try:
            scan = main_load.load(str(scan_path), validate=True)

            if isinstance(scan, AluminumManScan):
                raise Exception("Aluminum man is not supported in mag_utils yet!")

            # removing "validated" from the file name
            if VALIDATED_STR in scan.file_name:
                validated_index = scan.file_name.rindex(VALIDATED_STR)
                scan.file_name = scan.file_name[:validated_index] + scan.file_name[
                                                                    validated_index + len(VALIDATED_STR):]
        except Exception as e:
            print(f"Encountered error: {e}, falling back to universal loader..")

        scan = universal_loader(scan_path)

        loaded_scans.append(scan)

    # check if given more than one HorizontaScan if so, join all scans together. if given single scan return only it.
    if isinstance(loaded_scans[0], HorizontalScan):
        if len(loaded_scans) > 1:
            appended_scans = deepcopy(loaded_scans[0])
            for scan in loaded_scans[1:]:
                appended_scans = appended_scans.append(scan)
            return appended_scans

    if len(loaded_scans) == 1:
        return loaded_scans[0]

    return loaded_scans


import pdb
import json
import logging
from pathlib import Path
from os.path import abspath

from app._types import uvc_recieve
from config import assetsdir
from streaming_form_data import StreamingFormDataParser
from streaming_form_data.targets import FileTarget
from app.app import App
from app.responses import rbody, rstart200_json, rstart201_html

logger = logging.getLogger(__name__)

class MaxSizeValidator:
    _chunksize = 0

    def __init__(self, max_size: int, filepath: Path):
        self._filepath = filepath
        self._max_size = max_size

    def callback(self, chunk: bytes) -> None:
        self._chunksize += len(chunk)
        if self._chunksize > self._max_size:
            logger.debug("rolling back new file on disk")
            self._filepath.unlink(missing_ok=True)
            raise ValueError("maximum file size exceeded")

async def parse_file_to_disk(
    recieve: uvc_recieve,
    headers: dict[str, str],
    filepath: Path,
    max_size: int = 100000,
) -> None:
    parser = StreamingFormDataParser(headers=headers)
    callback = MaxSizeValidator(max_size, filepath).callback
    str_filepath = abspath(filepath)
    file_target = FileTarget(str_filepath, allow_overwrite=False, validator=callback)
    parser.register("file", file_target)

    more_body = True
    while more_body:
        data = await recieve()
        parser.data_received(data.get("body", b""))
        more_body = data.get("more_body", False)

async def read_body(receive: uvc_recieve) -> str:
    body = b""
    more_body = True
    while more_body:
        message = await receive()
        body += message.get("body", b"")
        more_body = message.get("more_body", False)
    return body.decode("utf-8")

@App.route(
    r"^/profiles/(.+)/?.*$",
    scope_params={"method": "GET"},
    qs_args={"orderby": "string", "limit": "int", "offset": "int", "desc": "bool"},
)
async def get_profiles(scope, recieve, send):
    profiles = scope["state"]["profiles"]
    resource_path = scope["group"][0]
    querystring_args = scope["qs_args"]

    if resource_path:
        async with profiles() as p:
            response_body = (
                await p.queryfilter("uname", resource_path, **querystring_args) or None
            )
            await send(rstart200_json)
            await send(rbody(json.dumps(response_body).encode("utf_8")))
    else:
        raise ValueError("invalid querystring: mandatory parameters missing")

@App.route(
    r"^/assets/upload/?.*$",
    scope_params={"method": "POST"},
    qs_args={"uname": "string", "title": "string", "parentpk": "string"},
)
async def post_asset(scope, recieve, send):
    assets = scope["state"]["assets"]
    querystring_args = scope["qs_args"]

    uname = querystring_args.get("uname", "")
    parentid = querystring_args.get("parentpk", "")
    title = querystring_args.get("title", "")

    async with assets() as a:
        if uname and parentid:
            new_row = await a.insert(
                ["uname", "parentpk"], [uname, parentid], returning=True, encoding=None
            )
            pk = new_row["pk"]
        elif uname and title:
            new_row = await a.insert(
                ["uname", "title"], [uname, title], returning=True, encoding=None
            )
            pk = new_row["pk"]
        else:
            raise ValueError("invalid querystring: mandatory parameters missing")
        filepath = assetsdir / (str(pk) + ".tex")
        headers = {a.decode("utf-8"): b.decode("utf-8") for a, b in scope["headers"]}
        await parse_file_to_disk(recieve, headers, filepath, max_size=10000000)

    await send(rstart201_html)
    await send(rbody(None))

@App.route(
    r"^/assets/upload/?.*$", scope_params={"method": "DELETE"}, qs_args={"pk": "string"}
)
async def delete_asset(scope, recieve, send):
    assets = scope["state"]["assets"]
    querystring_args = scope["qs_args"]

    pk = querystring_args.get("pk", "")
    async with assets() as a:
        if pk:
            await a.delete("pk", pk)
        else:
            raise ValueError("invalid querystring: mandatory parameters missing")
        filepath = assetsdir / (str(pk) + ".tex")
        logger.debug("deleting" + abspath(filepath))
        filepath.unlink(missing_ok=True)

    await send(rstart201_html)
    await send(rbody(None))


import string
from collections import namedtuple

import requests

LongPollServer = namedtuple('LongPollServer', 'server key ts chat_id')

class Vk():
    def __init__(self, client_id):
        self._client_id = client_id

    @staticmethod
    def AUTH_URL(params):
        return string.Template(
            'https://oauth.vk.com/authorize'
            '?client_id=$client_id'
            '&display=page'
            '&scope=messages,offline'
            '&response_type=token'
            '&v=5.44').substitute(params)

    @staticmethod
    def API_URL(method):
        return 'https://api.vk.com/method/' + method

    @staticmethod
    def api(method, token, params=dict()):
        params = params.copy()
        params['access_token'] = token
        r = requests.get(Vk.API_URL(method), params=params)
        if r.status_code != requests.codes.ok:
            return None

        json = r.json()
        print('VK api response: ' + str(json))

        if 'response' in json:
            return json['response']

        return None

    def get_auth_url(self):
        params = {'client_id': self._client_id}
        return Vk.AUTH_URL(params)

    @staticmethod
    def get_long_poll_server(token, chat_id):
        method = 'messages.getLongPollServer'
        server = Vk.api(method, token)
        if server == None:
            return None

        return LongPollServer(server['server'], server['key'],
                              server['ts'], chat_id)

    @staticmethod
    def poll(client, retry=True):
        server, key, ts, chat_id = client.next_server
        url = 'http://' + server
        params = {'key': key, 'ts': ts, 'wait': 25, 'act': 'a_check', 'mode': 2}
        r = requests.get(url, params=params)
        if r.status_code != requests.codes.ok:
            next_server = Vk.get_long_poll_server(token=client.vk_token,
                                                  chat_id=client.chat_id)
            if next_server == None:
                return None

            client.next_server = next_server
            if retry:
                return Vk.poll(client, retry=False)
            else:
                return None

        json = r.json()
        print("Poll results: " + str(json))
        if 'failed' in json:
            next_server = Vk.get_long_poll_server(token=client.vk_token,
                                                  chat_id=client.chat_id)
            if next_server == None:
                return None

            client.next_server = next_server
            if retry:
                return Vk.poll(client, retry=False)
            else:
                return None

        next_server = LongPollServer(server, key, json['ts'], chat_id)
        client.next_server = next_server
        return json['updates']


import copy
import math
import time

import numpy as np
import torch
from pytorch3d.renderer import camera_position_from_spherical_angles
from skimage.feature import peak_local_max

from nemo.utils import call_func_by_name
from nemo.utils import camera_position_to_spherical_angle
from nemo.utils import construct_class_by_name
from nemo.utils import flow_warp
from nemo.utils import load_off

def loss_fg_only(obj_s, clu_s=None, device="cuda"):
    return torch.ones(1, device=device) - torch.mean(obj_s)

def loss_fg_bg(obj_s, clu_s, device="cuda"):
    return torch.ones(1, device=device) - (
        torch.mean(torch.max(obj_s, clu_s)) - torch.mean(clu_s)
    )

def get_corr_pytorch(
    px_samples,
    py_samples,
    kpt_score_map,
    kp_coords,
    kp_vis,
    down_sample_rate,
    hm_h,
    hm_w,
    batch_size=12,
    device="cuda",
):
    all_corr = []

    begin, end = 0, batch_size
    while begin < len(px_samples):
        px_s, py_s = torch.from_numpy(px_samples[begin:end]).to(
            device
        ), torch.from_numpy(py_samples).to(device)
        kpc = torch.from_numpy(kp_coords).to(device)
        kpv = torch.from_numpy(kp_vis).to(device)
        kps = torch.from_numpy(kpt_score_map).to(device)

        xv, yv = torch.meshgrid(px_s, py_s)
        principal_samples = (
            torch.stack([xv, yv], dim=2).reshape(-1, 1, 2).repeat(1, kpc.shape[1], 1)
        )

        kpc = kpc.unsqueeze(1).repeat(1, principal_samples.shape[0], 1, 1)
        kpc += principal_samples
        kpc = kpc.reshape(-1, kpc.shape[2], 2)
        kpc = torch.round(kpc / down_sample_rate)

        kpv = kpv.unsqueeze(1).repeat(1, principal_samples.shape[0], 1)
        kpv = kpv.reshape(-1, kpv.shape[2])
        kpv[kpc[:, :, 0] < 0] = 0
        kpv[kpc[:, :, 0] >= hm_w - 1] = 0
        kpv[kpc[:, :, 1] < 0] = 0
        kpv[kpc[:, :, 1] >= hm_h - 1] = 0

        kpc[:, :, 0] = torch.clamp(kpc[:, :, 0], min=0, max=hm_w - 1)
        kpc[:, :, 1] = torch.clamp(kpc[:, :, 1], min=0, max=hm_h - 1)
        kpc = (kpc[:, :, 1:2] * hm_w + kpc[:, :, 0:1]).long()

        corr = torch.take_along_dim(kps.unsqueeze(0), kpc, dim=2)[:, :, 0]
        corr = torch.sum(corr * kpv, dim=1)

        all_corr.append(corr.reshape(-1, len(px_s), len(py_s)))

        begin += batch_size
        end += batch_size
        if end > len(px_samples):
            end = len(px_samples)

    corr = torch.cat(all_corr, dim=-2).detach().cpu().numpy()
    return corr

def solve_pose(
    cfg,
    feature_map,
    inter_module,
    kp_features,
    clutter_bank,
    poses,
    kp_coords,
    kp_vis,
    px_samples=None,
    py_samples=None,
    debug=False,
    device="cuda",
):
    nkpt, c = kp_features.size()
    memory = kp_features.view(nkpt, c, 1, 1)
    b, c, hm_h, hm_w = feature_map.size()
    pred = {}

    # Step 1: Pre-compute foreground and background features
    start_time = time.time()
    clutter_score = None
    if not isinstance(clutter_bank, list):
        clutter_bank = [clutter_bank]
    for cb in clutter_bank:
        _score = (
            torch.nn.functional.conv2d(feature_map, cb.unsqueeze(2).unsqueeze(3))
            .squeeze(0)
            .squeeze(0)
        )
        if clutter_score is None:
            clutter_score = _score
        else:
            clutter_score = torch.max(clutter_score, _score)

    kpt_score_map = torch.sum(
        feature_map.expand(nkpt, -1, -1, -1) * memory, dim=1
    )  # (nkpt, H, W)
    kpt_score_map = kpt_score_map.detach().cpu().numpy()
    kpt_score_map = kpt_score_map.reshape(nkpt, -1)  # (nkpt, H x W)

    end_time = time.time()
    pred["pre_compute_time"] = end_time - start_time

    # Step 2: Search for initializations
    start_time = end_time
    if px_samples is None or py_samples is None:
        if cfg.inference.search_translation:
            px_samples = np.linspace(
                0,
                hm_w * cfg.model.down_sample_rate,
                cfg.inference.num_px_samples,
                endpoint=True,
            )
            py_samples = np.linspace(
                0,
                hm_h * cfg.model.down_sample_rate,
                cfg.inference.num_py_samples,
                endpoint=True,
            )
        else:
            px_samples = np.array([hm_w * cfg.model.down_sample_rate / 2])
            py_samples = np.array([hm_h * cfg.model.down_sample_rate / 2])

    xv, yv = np.meshgrid(px_samples, py_samples, indexing="ij")
    corr = get_corr_pytorch(
        px_samples,
        py_samples,
        kpt_score_map,
        kp_coords,
        kp_vis,
        cfg.model.down_sample_rate,
        hm_h,
        hm_w,
        device=device,
    )
    corr = corr.reshape(
        poses.shape[0], poses.shape[1], poses.shape[2], poses.shape[3], len(xv), len(yv)
    )
    corr2d = corr.reshape(-1, len(xv), len(yv))

    corr2d_max = np.max(corr2d, axis=0)
    if cfg.inference.search_translation:
        extrema_2d = peak_local_max(
            corr2d_max, min_distance=cfg.inference.min_distance, exclude_border=False
        )
    else:
        extrema_2d = [[0, 0]]
    larger_thr_ext_2d = []
    max_e = None
    max_v = 0
    for e in extrema_2d:
        if corr2d_max[e[0], e[1]] >= cfg.inference.pre_rendering_thr:
            larger_thr_ext_2d.append(e)
        if corr2d_max[e[0], e[1]] > max_v:
            max_v = corr2d_max[e[0], e[1]]
            max_e = e

    extrema = []
    if len(larger_thr_ext_2d) > 0:
        iter_extrema_2d = larger_thr_ext_2d
    else:
        iter_extrema_2d = [max_e]

    for e in iter_extrema_2d:
        c = corr2d[:, e[0], e[1]].reshape(
            poses.shape[0], poses.shape[1], poses.shape[2], poses.shape[3]
        )
        e_azim, e_elev, e_the, e_dist = np.unravel_index(
            np.argmax(c, axis=None), c.shape
        )
        p = poses[e_azim, e_elev, e_the, e_dist]
        extrema.append(
            {
                "azimuth": p[0],
                "elevation": p[1],
                "theta": p[2],
                "distance": p[3],
                "px": px_samples[e[0]],
                "py": py_samples[e[1]],
                "principal": [px_samples[e[0]], py_samples[e[1]]],
            }
        )
    if debug:
        pred["pre_rendering_poses"] = extrema
        pred["corr2d"] = corr2d_max

    if len(extrema) == 0:
        raise NotImplementedError
        pred["final"] = []
        return pred

    end_time = time.time()
    pred["pre_rendering_time"] = end_time - start_time

    # Step 3: Refine object proposals with pose optimization
    start_time = end_time
    refined, object_score_list, seg_map_list = [], [], []
    for i in range(len(extrema)):
        C = camera_position_from_spherical_angles(
            extrema[i]["distance"],
            extrema[i]["elevation"],
            extrema[i]["azimuth"],
            degrees=False,
            device=device,
        )
        C = torch.nn.Parameter(C, requires_grad=True)
        theta = torch.tensor(extrema[i]["theta"], dtype=torch.float32).to(device)
        theta = torch.nn.Parameter(theta, requires_grad=True)
        max_principal = [extrema[i]["px"], extrema[i]["py"]]
        flow = torch.tensor(
            [
                -(max_principal[0] - hm_w * cfg.model.down_sample_rate / 2)
                / cfg.model.down_sample_rate
                * cfg.inference.translation_scale,
                -(max_principal[1] - hm_h * cfg.model.down_sample_rate / 2)
                / cfg.model.down_sample_rate
                * cfg.inference.translation_scale,
            ],
            dtype=torch.float32,
        ).to(device)
        flow = torch.nn.Parameter(flow, requires_grad=True)

        param_list = [C, theta]
        if cfg.inference.optimize_translation:
            param_list.append(flow)

        optim = construct_class_by_name(**cfg.inference.optimizer, params=param_list)
        scheduler_kwargs = {"optimizer": optim}
        scheduler = construct_class_by_name(
            **cfg.inference.scheduler, **scheduler_kwargs
        )

        for epo in range(cfg.inference.epochs):
            projected_map = inter_module(
                C,
                theta,
                mode=cfg.inference.inter_mode,
                blur_radius=cfg.inference.blur_radius,
            ).squeeze()
            flow_map = flow.view(1, 2, 1, 1).repeat(1, 1, hm_h, hm_w)
            projected_map = flow_warp(
                projected_map.unsqueeze(0), flow_map / cfg.inference.translation_scale
            )[0]
            object_score = torch.sum(projected_map * feature_map.squeeze(), dim=0)

            loss = call_func_by_name(
                func_name=cfg.inference.loss,
                obj_s=object_score,
                clu_s=clutter_score,
                device=device,
            )

            loss.backward()
            optim.step()
            optim.zero_grad()

        seg_map = (
            ((object_score > clutter_score) * (object_score > 0.0))
            .detach()
            .cpu()
            .numpy()
            .astype(np.uint8)
        )
        seg_map_list.append(seg_map)
        object_score_list.append(object_score.squeeze().detach().cpu().numpy())

        (
            distance_pred,
            elevation_pred,
            azimuth_pred,
        ) = camera_position_to_spherical_angle(C)
        theta_pred, distance_pred, elevation_pred, azimuth_pred = (
            theta.item(),
            distance_pred.item(),
            elevation_pred.item(),
            azimuth_pred.item(),
        )
        px_pred, py_pred = (
            -flow[0].item() / cfg.inference.translation_scale,
            -flow[1].item() / cfg.inference.translation_scale,
        )

        refined.append(
            {
                "azimuth": azimuth_pred,
                "elevation": elevation_pred,
                "theta": theta_pred,
                "distance": distance_pred,
                "px": px_pred,
                "py": py_pred,
                "principal": [
                    px_pred * cfg.model.down_sample_rate
                    + hm_w * cfg.model.down_sample_rate / 2,
                    py_pred * cfg.model.down_sample_rate
                    + hm_h * cfg.model.down_sample_rate / 2,
                ],
                "score": loss.item(),
            }
        )

    end_time = time.time()
    pred["optimization_time"] = end_time - start_time

    if len(refined) == 1:
        pred["final"] = refined
    else:
        min_score = 1000
        ret = None
        for result in refined:
            if result['score'] < min_score:
                ret = result
                min_score = result['score']
        pred['final'] = ret

    if debug:
        object_score_maps = np.array(object_score_list)
        segmentation_maps = np.array(seg_map_list)
        object_idx_map, new_seg_maps = resolve_occ(segmentation_maps, object_score_maps)
        pred["object_idx_map"] = object_idx_map
        pred["seg_maps"] = new_seg_maps

    return pred

def resolve_occ(seg_maps, score_maps):
    seg_maps_copy = copy.deepcopy(seg_maps)

    """
    obj_idx_map = np.zeros((seg_maps.shape[1], seg_maps.shape[2]), dtype=np.int16)
    obj_idx_map[seg_maps[0] == 1] = 1
    curr_score_map = copy.deepcopy(score_maps[0])
    for i in range(1, seg_maps.shape[0]):
        overlap = (obj_idx_map > 0) * (seg_maps[i] == 1)
    """

    occ_reasoning_mat = np.zeros((seg_maps.shape[0], seg_maps.shape[0]), dtype=np.int16)
    for i in range(0, seg_maps.shape[0]):
        for j in range(0, seg_maps.shape[0]):
            if i >= j:
                continue
            overlap = (seg_maps[i] == 1) * (seg_maps[j] == 1)
            if np.sum(overlap) == 0:
                continue
            score_i = (
                np.sum(overlap * score_maps[i])
                + np.sum((seg_maps[i] - overlap) * score_maps[i]) * 0.5
            )
            score_j = (
                np.sum(overlap * score_maps[j])
                + np.sum((seg_maps[j] - overlap) * score_maps[j]) * 0.5
            )
            if score_i >= score_j:
                occ_reasoning_mat[i][j] = 1
                occ_reasoning_mat[j][i] = -1
                seg_maps_copy[j][overlap == 1] = 0
            else:
                occ_reasoning_mat[j][i] = 1
                occ_reasoning_mat[i][j] = -1
                seg_maps_copy[i][overlap == 1] = 0

    sm = seg_maps_copy[0]
    for i in range(1, seg_maps_copy.shape[0]):
        sm += seg_maps_copy[i]
    # print(np.sum(sm > 1))
    # print([np.sum(seg_maps_copy[i] * score_maps[i]) for i in range(seg_maps_copy.shape[0])])

    seg_maps_pad = np.concatenate(
        [
            np.zeros(
                (1, seg_maps_copy.shape[1], seg_maps_copy.shape[2]),
                dtype=seg_maps_copy.dtype,
            ),
            seg_maps_copy,
        ],
        axis=0,
    )
    return np.argmax(seg_maps_pad, axis=0), seg_maps_copy

def pre_compute_kp_coords(
    mesh_path,
    azimuth_samples,
    elevation_samples,
    theta_samples,
    distance_samples,
    viewport=3000,
):
    """Calculate vertex visibility for cuboid models."""
    xvert, _ = load_off(mesh_path)

    xmin, xmax = np.min(xvert[:, 0]), np.max(xvert[:, 0])
    ymin, ymax = np.min(xvert[:, 1]), np.max(xvert[:, 1])
    zmin, zmax = np.min(xvert[:, 2]), np.max(xvert[:, 2])
    xmean = (xmin + xmax) / 2
    ymean = (ymin + ymax) / 2
    zmean = (zmin + zmax) / 2
    pts = [
        [xmean, ymean, zmin],
        [xmean, ymean, zmax],
        [xmean, ymin, zmean],
        [xmean, ymax, zmean],
        [xmin, ymean, zmean],
        [xmax, ymean, zmean],
    ]

    poses = np.zeros(
        (
            len(azimuth_samples)
            * len(elevation_samples)
            * len(theta_samples)
            * len(distance_samples),
            4,
        ),
        dtype=np.float32,
    )
    num_vis_faces = []
    count = 0
    for azim_ in azimuth_samples:
        for elev_ in elevation_samples:
            for theta_ in theta_samples:
                for dist_ in distance_samples:
                    poses[count] = [azim_, elev_, theta_, dist_]
                    count += 1
                    if elev_ == 0:
                        if azim_ in [0, np.pi / 2, np.pi, 3 * np.pi / 2]:
                            num_vis_faces.append(1)
                        else:
                            num_vis_faces.append(2)
                    else:
                        if azim_ in [0, np.pi / 2, np.pi, 3 * np.pi / 2]:
                            num_vis_faces.append(2)
                        else:
                            num_vis_faces.append(3)

    kp_coords = np.zeros(
        (
            len(azimuth_samples)
            * len(elevation_samples)
            * len(theta_samples)
            * len(distance_samples),
            len(xvert),
            2,
        ),
        dtype=np.float32,
    )
    kp_vis = np.ones(
        (
            len(azimuth_samples)
            * len(elevation_samples)
            * len(theta_samples)
            * len(distance_samples),
            len(xvert),
        ),
        dtype=np.float32,
    )
    xvert_ext = np.concatenate((xvert, pts), axis=0)
    for i, pose_ in enumerate(poses):
        azim_, elev_, theta_, dist_ = pose_

        C = np.zeros((3, 1))
        C[0] = dist_ * math.cos(elev_) * math.sin(azim_)
        C[1] = -dist_ * math.cos(elev_) * math.cos(azim_)
        C[2] = dist_ * math.sin(elev_)
        azimuth = -azim_
        elevation = -(math.pi / 2 - elev_)
        Rz = np.array(
            [
                [math.cos(azimuth), -math.sin(azimuth), 0],
                [math.sin(azimuth), math.cos(azimuth), 0],
                [0, 0, 1],
            ]
        )  # rotation by azimuth
        Rx = np.array(
            [
                [1, 0, 0],
                [0, math.cos(elevation), -math.sin(elevation)],
                [0, math.sin(elevation), math.cos(elevation)],
            ]
        )  # rotation by elevation
        R_rot = np.dot(Rx, Rz)
        R = np.hstack((R_rot, np.dot(-R_rot, C)))
        P = np.array([[viewport, 0, 0], [0, viewport, 0], [0, 0, -1]])
        x3d_ = np.hstack((xvert_ext, np.ones((len(xvert_ext), 1)))).T
        x3d_ = np.dot(R, x3d_)
        # x3d_r_ = np.dot(P, x3d_)
        x2d = np.dot(P, x3d_)
        x2d[0, :] = x2d[0, :] / x2d[2, :]
        x2d[1, :] = x2d[1, :] / x2d[2, :]
        x2d = x2d[0:2, :]
        R2d = np.array(
            [
                [math.cos(theta_), -math.sin(theta_)],
                [math.sin(theta_), math.cos(theta_)],
            ]
        )
        x2d = np.dot(R2d, x2d).T
        x2d[:, 1] *= -1

        # principal = np.array([px_, py_], dtype=np.float32)
        # x2d = x2d + np.repeat(principal[np.newaxis, :], len(x2d), axis=0)

        x2d = x2d[: len(xvert)]
        kp_coords[i] = x2d

        center3d = x3d_[:, len(xvert) :]
        face_dist = np.sqrt(
            np.square(center3d[0, :])
            + np.square(center3d[1, :])
            + np.square(center3d[2, :])
        )
        ind = np.argsort(face_dist)[: num_vis_faces[i]]

        """
        # 13 13 5 13x12 + 13x12 + 5x12 + 5x12 + 5x13 + 5x13
        # 8 17 6 17x8 + 17x8 + 6x8 + 6x8 + 6x17 + 6x17
        if 0 in ind:
            kp_vis[i, 0:mesh_face_breaks[0]] = 1
        if 1 in ind:
            kp_vis[i, mesh_face_breaks[0]:mesh_face_breaks[1]] = 1
        if 2 in ind:
            kp_vis[i, mesh_face_breaks[1]:mesh_face_breaks[2]] = 1
        if 3 in ind:
            kp_vis[i, mesh_face_breaks[2]:mesh_face_breaks[3]] = 1
        if 4 in ind:
            kp_vis[i, mesh_face_breaks[3]:mesh_face_breaks[4]] = 1
        if 5 in ind:
            kp_vis[i, mesh_face_breaks[4]:mesh_face_breaks[5]] = 1
        """

    poses = poses.reshape(
        len(azimuth_samples),
        len(elevation_samples),
        len(theta_samples),
        len(distance_samples),
        4,
    )
    return poses, kp_coords, kp_vis


from problem import RandomGeometricGraphProblem
from typing import List
from queue import Queue

STUDENT_ID = '__BFS__'

class Assignment:
    def __init__(self, problem: RandomGeometricGraphProblem):
        self.problem = problem

    def search(self, criteria: tuple, time_limit) -> List[str]:
        """
        Your documentation should contain the following things:
        - Which algorithm that you designed?
        - Why did you select it?
        - What does each command do?
        """
        frontier = Queue()
        frontier.put((self.problem.initial_state,))
        reached = [self.problem.initial_state]

        while not frontier.empty():
            path = frontier.get()
            if self.problem.is_solution_path(path):
                return list(path)

            for child, _ in self.problem.expand(path[-1]):
                if child in reached:
                    continue
                frontier.put(path + (child,))
                reached.append(child)

        return []


# -*- coding: utf-8 -*-

import numpy as np
from copy import deepcopy

from ..portfolio.contract import Contract
from ..portfolio.position import Position2
from ..portfolio.portfolio import Portfolio
from ..portfolio.trade import Trade
from ..optimal_controls.ou_spread_model import (
    OUSpreadModelSolver
)
from ..simulation.simulate_cointegrated_assets import simulate_ou_spread

def compute_rebalancing_amount(target_nominal, price, contract, portfolio):
    """
    Computes number of units to rebalance
    """
    n_new = int(target_nominal / float(price * contract.multiplier))
    position = portfolio.get_position(contract.symbol)
    if position is not None:
        n_old = position.net_position
    else:
        raise ValueError(f'Cannot compute rebalancing amount. Position for symbol: {contract.symbol} not found.')

    amount = n_new - n_old

    return amount

def create_trade(price, amount, contract):
    """
    Creates a new trade
    """
    if not isinstance(price, (float, int)):
        raise ValueError('price has to be <int> or <float>.')

    if not isinstance(amount, int):
        raise ValueError('amount has to be <int>.')

    if not isinstance(contract, Contract):
        raise ValueError('contract has to be <Contract>.')

    if amount == 0:
        return None

    if amount > 0:
        action = 'BOT'
    elif amount < 0:
        action = 'SLD'
    else:
        raise ValueError('amount invalid.')

    # Compute trading commissions
    if contract.sec_type == 'STK':
        commission = (4.0 / 10000) * abs(amount) * price

    elif contract.sec_type == 'F':
        commission = 1.0

    return Trade(contract.symbol, action, price, abs(amount),
                 contract.sec_type, commission)

def simulate_pairs_trading(
        model_parameters,
        strategy_parameters,
        a, b, s, T, dt,
        contract_a, contract_b,
        n_steps,
        simulation_number):

    #T = strategy_parameters.trading_horizon
    #dt = T / n_steps

    # Create contract objects
    #contract_a = Contract(strategy_parameters.symbol_a, 'F', 50)
    #contract_b = Contract(strategy_parameters.symbol_b, 'F', 20)

    # Simulate prices
    n_sim = 1 # hard coded, sima are instead produced by several calls.
    # a, b, s = simulate_ou_spread(
    #     n_sim, n_steps, model_parameters.b_0, model_parameters.x_0,
    #     model_parameters.kappa, model_parameters.theta,
    #     model_parameters.eta, model_parameters.mu_b,
    #     model_parameters.sigma_b, dt)

    # Create position objects
    PositionA = Position2(contract_a)
    PositionB = Position2(contract_b)

    # Create portfolio
    portfolio = Portfolio(f'Portfolio #{simulation_number}')
    portfolio.add_position(PositionA)
    portfolio.add_position(PositionB)

    for i in range(0, n_steps):

        #------------------------------------------------------------------#
        #                       Update Tradng Model                        #
        #------------------------------------------------------------------#

        # Compute ln-spread
        spread = np.log(a[i]) - np.log(b[i])

        # Percentage allocations
        time_left = T - dt*i
        optimal_decisions = OUSpreadModelSolver.solve_asset_weights(
            model_parameters, strategy_parameters, spread, time_left)

        #------------------------------------------------------------------#
        #                      Rebalance position in A                     #
        #------------------------------------------------------------------#

        # Rebalance position in A
        amount = compute_rebalancing_amount(
            optimal_decisions.alloc_a_trunc, a[i], contract_a, portfolio)

        # Create trade
        trade = create_trade(a[i], amount, contract_a)

        if trade is not None:

            # Add the trade to the position
            portfolio.add_trade(trade)

        # Update portfolio market value
        portfolio.update_market_value(contract_a.symbol, a[i], a[i])

        #------------------------------------------------------------------#
        #                      Rebalance position in B                     #
        #------------------------------------------------------------------#

        # Rebalance position in B
        amount = compute_rebalancing_amount(
            optimal_decisions.alloc_b_trunc, b[i], contract_b, portfolio)

        # Create trade
        trade = create_trade(b[i], amount, contract_b)

        if trade is not None:

            # Add the trade to the position
            portfolio.add_trade(trade)

        # Update portfolio market value
        portfolio.update_market_value(contract_b.symbol, b[i], b[i])

    return portfolio

def simulate_strategy(model_parameters, strategy_parameters, n_steps, n_sim):

    contract_a = Contract(strategy_parameters.symbol_a, 'F', 50)
    contract_b = Contract(strategy_parameters.symbol_b, 'F', 20)

    portfolios = {}
    a_prices = {}
    b_prices = {}

    for i in range(0, n_sim):

        # Simulate prices and spread
        A_t, B_t, X_t = simulate_ou_spread(
             n_sim, n_steps, model_parameters.b_0, model_parameters.x_0,
             model_parameters.kappa, model_parameters.theta,
             model_parameters.eta, model_parameters.mu_b,
             model_parameters.sigma_b,
             strategy_parameters.trading_horizon / float(n_steps))

        # Simulate pairs trading strategy
        portfolio = simulate_pairs_trading(
            model_parameters,
            strategy_parameters,
            A_t, B_t, X_t,
            strategy_parameters.trading_horizon,
            strategy_parameters.trading_horizon / float(n_steps),
            contract_a, contract_b,
            n_steps,
            i)

        portfolios.update({i: deepcopy(portfolio)})
        a_prices.update({i: A_t})
        b_prices.update({i: B_t})

    return a_prices, b_prices, portfolios