import numpy as np
import matplotlib.pyplot as plt
import SVM_algorithm
def init_plot(X, Y):
    pos1 = np.argwhere(Y==1)
    pos2 = np.argwhere(Y==-1)
    data1 = X[pos1[:,0]]
    data2 = X[pos2[:,0]]
    plt.plot(data1[:,0], data1[:,1], 'ro', data2[:, 0], data2[:, 1], 'bs')
    plt.axis()
    plt.show()

def result_plot(w, b, alpha, X, Y, kernel, order, linesize=0.3):
    pos1 = np.argwhere(Y == 1)
    pos2 = np.argwhere(Y == -1)
    data1 = X[pos1[:, 0]]
    data2 = X[pos2[:, 0]]
    up0 = max(X[:,0]) *1.1
    low0 = min(X[:,0]) *1.1
    up1 = max(X[:, 1]) * 1.1
    low1 = min(X[:, 1]) * 1.1
    if kernel=='linear':
        x = np.arange(low0, up0, linesize)
        y = (-w[0, 0] * x - b) / w[0, 1]
        plt.plot(data1[:, 0], data1[:, 1], 'ro', data2[:, 0], data2[:, 1], 'bs', x, y, 'g--')
        plt.axis()
        plt.show()
    else:
        x1 = np.linspace(low0, up0, 300)
        x2 = np.linspace(low1, up1, 300)
        X_grid, Y_grid = np.meshgrid(x1, x2)
        vals = np.zeros_like(X_grid)
        for i in range(X_grid.shape[1]):
            this_X = np.vstack((X_grid[:, i], Y_grid[:, i]))
            this_X = this_X.T
            vals[:, i] = SVM_algorithm.predict(X, Y, this_X, w, b, alpha, kernel, order)
        plt.contour(X_grid, Y_grid, vals)
        plt.plot(data1[:, 0], data1[:, 1], 'ro')
        plt.plot(data2[:, 0], data2[:, 1], 'bs')
    plt.xticks(())
    plt.yticks(())
    plt.show()


import numpy as np
import cv2
import time
import random
import collections
from edgetpu.detection.engine import DetectionEngine
from edgetpu.utils import dataset_utils
from PIL import Image
from matplotlib import cm
import os
import urllib.request

class StopSignDetector(object):
    '''
    Requires an EdgeTPU for this part to work

    This part will run a EdgeTPU optimized model to run object detection to detect a stop sign.
    We are just using a pre-trained model (MobileNet V2 SSD) provided by Google.
    '''

    def download_file(self, url, filename):
        if not os.path.isfile(filename):
            urllib.request.urlretrieve(url, filename)

    def __init__(self, min_score, show_bounding_box, max_reverse_count=0, reverse_throttle=-0.5, debug=False):
        MODEL_FILE_NAME = "ssd_mobilenet_v2_coco_quant_postprocess_edgetpu.tflite"
        LABEL_FILE_NAME = "coco_labels.txt"

        MODEL_URL = "https://github.com/google-coral/edgetpu/raw/master/test_data/ssd_mobilenet_v2_coco_quant_postprocess_edgetpu.tflite"
        LABEL_URL = "https://dl.google.com/coral/canned_models/coco_labels.txt"

        self.download_file(MODEL_URL, MODEL_FILE_NAME)
        self.download_file(LABEL_URL, LABEL_FILE_NAME)

        self.last_5_scores = collections.deque(np.zeros(5), maxlen=5)
        self.engine = DetectionEngine(MODEL_FILE_NAME)
        self.labels = dataset_utils.read_label_file(LABEL_FILE_NAME)

        self.STOP_SIGN_CLASS_ID = 12
        self.min_score = min_score
        self.show_bounding_box = show_bounding_box
        self.debug = debug

        # reverse throttle related
        self.max_reverse_count = max_reverse_count
        self.reverse_count = max_reverse_count
        self.reverse_throttle = reverse_throttle
        self.is_reversing = False

    def convertImageArrayToPILImage(self, img_arr):
        img = Image.fromarray(img_arr.astype('uint8'), 'RGB')

        return img

    '''
    Return an object if there is a traffic light in the frame
    '''
    def detect_stop_sign (self, img_arr):
        img = self.convertImageArrayToPILImage(img_arr)

        ans = self.engine.detect_with_image(img,
                                          threshold=self.min_score,
                                          keep_aspect_ratio=True,
                                          relative_coord=False,
                                          top_k=3)
        max_score = 0
        traffic_light_obj = None
        if ans:
            for obj in ans:
                if (obj.label_id == self.STOP_SIGN_CLASS_ID):
                    if self.debug:
                        print("stop sign detected, score = {}".format(obj.score))
                    if (obj.score > max_score):
                        print(obj.bounding_box)
                        traffic_light_obj = obj
                        max_score = obj.score

        # if traffic_light_obj:
        #     self.last_5_scores.append(traffic_light_obj.score)
        #     sum_of_last_5_score = sum(list(self.last_5_scores))
        #     # print("sum of last 5 score = ", sum_of_last_5_score)

        #     if sum_of_last_5_score > self.LAST_5_SCORE_THRESHOLD:
        #         return traffic_light_obj
        #     else:
        #         print("Not reaching last 5 score threshold")
        #         return None
        # else:
        #     self.last_5_scores.append(0)
        #     return None

        return traffic_light_obj

    def draw_bounding_box(self, traffic_light_obj, img_arr):
        xmargin = (traffic_light_obj.bounding_box[1][0] - traffic_light_obj.bounding_box[0][0]) *0.1

        traffic_light_obj.bounding_box[0][0] = traffic_light_obj.bounding_box[0][0] + xmargin
        traffic_light_obj.bounding_box[1][0] = traffic_light_obj.bounding_box[1][0] - xmargin

        ymargin = (traffic_light_obj.bounding_box[1][1] - traffic_light_obj.bounding_box[0][1]) *0.05

        traffic_light_obj.bounding_box[0][1] = traffic_light_obj.bounding_box[0][1] + ymargin
        traffic_light_obj.bounding_box[1][1] = traffic_light_obj.bounding_box[1][1] - ymargin

        cv2.rectangle(img_arr, tuple(traffic_light_obj.bounding_box[0].astype(int)),
                        tuple(traffic_light_obj.bounding_box[1].astype(int)), (0, 255, 0), 2)

    def run(self, img_arr, throttle, debug=False):
        if img_arr is None:
            return throttle, img_arr

        # Detect traffic light object
        traffic_light_obj = self.detect_stop_sign(img_arr)

        if traffic_light_obj or self.is_reversing:
            if self.show_bounding_box and traffic_light_obj != None:
                self.draw_bounding_box(traffic_light_obj, img_arr)

            # Set the throttle to reverse within the max reverse count when detected the traffic light object
            if self.reverse_count < self.max_reverse_count:
                self.is_reversing = True
                self.reverse_count += 1
                return self.reverse_throttle, img_arr
            else:
                self.is_reversing = False
                return 0, img_arr
        else:
            self.is_reversing = False
            self.reverse_count = 0
            return throttle, img_arr


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap

class AdalineGD(object):
    """
    매개 변수
    ---------
    eta : float
        학습률 ( 0.0 ~ 1.0)
    n_iter : int
        훈련 데이터셋 반복 횟수
    random_state : int
        가중치 무작위 초기화를 위한 난수 생성 시드

    속성
    ---------
    w_ :1d-array
        학습된 가중치
    errors_ : list
        에포크마다 누정된 분류 오류
    """
    def  __init__(self, eta = 0.01, n_iter = 50, random_state = 1):
        self.eta = eta
        self.n_iter = n_iter
        self.random_state = random_state

    "훈련 데이터 학습"
    def fit(self, X, y):
        """
        매개변수
        ----------
        X : {array-like}, shape = [n_samples, n_features]
            n_sample개의 샘플과 n_features개의 특성으로 이루어진 훈련 데이터
        y : array-like, shape = [n_samples]
            타켓 값

        반환값
        ----------
        self : object
        """
        rgen = np.random.RandomState(self.random_state)
        self.w_ = rgen.normal(loc = 0.0, scale = 0.01, size = 1 + X.shape[1])
        self.cost_ = []

        "최종입력 -> 활성화 -> 출력 순으로 진행"
        for i in range(self.n_iter):
            net_input = self.net_input(X)               #"최종 입력 계산"
            output = self.activation(net_input)         #"선형 활성화 계산"
            errors = ( y - output )                     #"오차 계산 (실제 값 - 예측 값)"
            self.w_[1:] += self.eta * X.T.dot(errors)   #"배열의 T 속성 : 2차원 배열의 전치(transpose) 연산이며 행과 열을 바꾸는 작업이다."
                                                        #"가중치 변화량 : 학습률 * 비용 함수의 기울기"
                                                        #"X.T.dot(errors) : 특성 행렬과 오차 백터 간의 행렬-백터 곱"
            self.w_[0] += self.eta * errors.sum()       #"절편에 errors수를 더한다."
            cost = (errors ** 2).sum() / 2.0            #"비용 함수 =  ½Σ(실제 값 - 계산한 값)^2"
            self.cost_.append(cost)                     #"현제 시도에서의 비용 함수 값 저장"
        return self

    "최종 입력 계산"
    def net_input(self, X):
        return np.dot(X, self.w_[1:]) + self.w_[0]

    "선형 활성화 계산, "
    def activation(self, X):
        return X    #"선형 활성화 단계를 보여주기 위함"

    "단위 계단 함수를 사용하여 클레스 레이블을 반환"
    def predict(self, X):
        return np.where(self.net_input(X) >= 0.0, 1, -1)

"pandas 라이브러리를 사용하여 UCI 머신 러닝 저장소에서 붓꽃 데이터 셋을 로드"
"df = pd.read_csv('https://archive.ics.uci.edu/ml' 'machine-learning-databases/iris/iris.data', header = None)"
df = pd.read_csv('../iris.data', header = None)

"100개의 훈련 샘플에서 첫 번째 열과 세 번째 열을 추출하여 특성 행렬 X에 저장"
y = df.iloc[0:100, 4].values
y = np.where(y == 'Iris-setosa', -1, 1)

X = df.iloc[0:100, [0, 2]].values

plt.scatter(X[:50, 0], X[:50, 1], color = 'red', marker = 'o', label = 'setosa')
plt.scatter(X[50:100, 0], X[50:100, 1], color = 'blue', marker = 'x', label = 'versicolor')
plt.xlabel('sepal length [cm]')
plt.ylabel('petal length [cm]')
plt.legend(loc = 'upper left')
plt.show()

"Adaline 알고리즘 훈련"
"epoch 대비 잘못 분류된 오차를 그래프로 그린다"
fig, ax = plt.subplots(nrows = 1, ncols = 2, figsize = (10, 4))
ada1 = AdalineGD(eta = 0.01, n_iter=10).fit(X, y)
ax[0].plot(range(1, len(ada1.cost_) + 1), np.log10(ada1.cost_), marker = 'o')
ax[0].set_xlabel('Epochs')
ax[0].set_ylabel('log(Sum-squared-error)')
ax[0].set_title('Adaline - Leaning rate 0.01')

ada2 = AdalineGD(eta = 0.00001, n_iter=10).fit(X, y)
ax[1].plot(range(1, len(ada2.cost_) + 1), np.log10(ada2.cost_), marker = 'x')
ax[1].set_xlabel('Epochs')
ax[1].set_ylabel('log(Sum-squared-error)')
ax[1].set_title('Adaline - Leaning rate 0.00001')
plt.show()
"학습률이 너무 크면 비용 전역 최소값을 지나치키 떄문에 함수를 최소화 하지 못하고 비용을 매 시도 마다 커진다."
"학습률이 너무 작으면 전역 최소값에 수렴하기 위해서는 많은 시도가 필요하다."

"데이터 표준화 ( 특성 스케일을 조정 하기 위해 )"
"경사 하강법은 특성 스케일을 조정하여 빠르게 전역 최소값으로 수렴하도록 할 수 있다."
"X_std : 표준화된 데이터"
X_std = np.copy(X)
X_std[:, 0] = (X[:,0] - X[:,0].mean()) / X[:,0].std()
X_std[:, 1] = (X[:,1] - X[:,1].mean()) / X[:,1].std()

"데이터셋의 결정 경계 시각화"
def plot_decision_regions(S, y, classifier, resolution = 0.02):
    markers = ('s', 'x', 'o', '^', 'v')
    colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
    cmap = ListedColormap(colors[:len(np.unique(y))])
    x1_min, x1_max = S[:, 0].min() - 1, S[:, 0].max() + 1
    x2_min, x2_max = S[:, 1].min() - 1, S[:, 1].max() + 1
    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution), np.arange(x2_min, x2_max, resolution))

    Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
    Z = Z.reshape(xx1.shape)
    plt.contourf(xx1, xx2, Z, alpha = 0.3, cmap = cmap)
    plt.xlim(xx1.min(), xx1.max())
    plt.ylim(xx2.min(), xx2.max())

    for idx, cl in enumerate(np.unique(y)):
        plt.scatter(x = S[y == cl, 0], y = S[y == cl, 1], alpha=0.8, c=colors[idx], marker=markers[idx], label=cl, edgecolors='black')

ada3 = AdalineGD(eta = 0.01, n_iter=15)
ada3.fit(X_std, y)

plot_decision_regions(X_std, y, classifier = ada3)
plt.title('Adaline - Gradient Descent')
plt.xlabel('sepal length [standardized]')
plt.ylabel('petal length [standardized]')
plt.legend(loc = 'upper left')
plt.tight_layout()
plt.show()

plt.plot(range(1, len(ada3.cost_) + 1), np.log10(ada3.cost_), marker = 'o')
plt.xlabel('Epochs')
plt.ylabel('Sum-squared-error')
plt.show()


from account import Account
from transaction import Transaction
import csv

class ATM:
    def __init__(self):
        self.accounts = {}
        self.transactions = []
        self.load_accounts()

    def add_account(self, account):
        self.accounts[account.name] = account

    def remove_account(self, name):
        del self.accounts[name]

    def get_account(self, name):
        return self.accounts[name] if name in self.accounts else None

    def get_accounts(self, name=None):
        if name:
            return [self.get_account(name)]
        else:
            return list(self.accounts.values())

    def deposit(self, name, pin, amount):
        account = self.get_account(name)
        if account and account.check_pin(pin):
            account.deposit(amount)
            transaction = Transaction(name, amount, "deposited")
            self.transactions.append(transaction)
            self.save_accounts()
        else:
            print("Account not found or incorrect PIN")

    def withdraw(self, name, pin, amount):
        account = self.get_account(name)
        if not account:
            return "Account not found"
        elif not account.check_pin(pin):
            return "Invalid PIN"
        elif account.withdraw(amount, pin):
            account.balance -= amount
            transaction = Transaction(name, -amount, "withdrawn")
            self.transactions.append(transaction)
            self.save_accounts()
            return "Transaction successful"
        else:
            return "Insufficient balance"

    def check_balance(self, name, pin):
        account = self.get_account(name)
        if account and account.check_pin(pin):
            return account.check_balance()
        else:
            print("Account not found or incorrect PIN")

    def print_transactions(self):
        for transaction in self.transactions:
            print(f"{transaction.account_name}: {transaction.amount} "
                  f"({transaction.transaction_type}) on {transaction.timestamp}")

    def save_accounts(self):
        with open("database.csv", mode="w", newline="") as file:
            writer = csv.writer(file)
            for account in self.get_accounts():
                writer.writerow([account.name, account.pin, account.balance])

    def load_accounts(self):
        try:
            with open("database.csv") as file:
                reader = csv.DictReader(file)
                for row in reader:
                    if "balance" in row:
                        self.add_account(
                            Account(row["name"], int(row["pin"]),
                                    float(row["balance"])))
                    else:
                        self.add_account(Account(row["name"], row))
        except FileNotFoundError:
            print("File not found.")
        except ValueError:
            print("Error loading accounts from file.")

    def check_pin(self, name, pin):
        account = self.get_account(name)
        if account and account.check_pin(pin):
            return True
        else:
            return False


from django.shortcuts import render, redirect
from django.http import HttpResponseRedirect
from django.urls import reverse
from EBA.models import Location_Restaurant, Restaurant_Food_New
from .forms import Location
from django.contrib.auth.forms import UserCreationForm
from .forms import UserForm,CustomerForm

# VIEW is the core of django, if there is no view, there will be no web page in django

#Taking input from user about what restaurants are all needed to show up
def get_location(request):
    if request.method == 'POST':
        form = Location(request.POST)
        loc = form['location'].value()

        if form.is_valid():
            # return redirect('rlist',{'location':loc})
            rd_url = reverse('rlist', kwargs={'loc': loc})
            print(rd_url)
            return HttpResponseRedirect(rd_url)
    else:
        form = Location()

    return render(request, 'location.html', {'form': form})

#Showing up restaurants based on the input given by user from FORM Location
def Restaurant_List(request, loc):
  RL = Location_Restaurant.objects.filter(Location=loc)
  return render(request,'res_list.html',{'rl':RL})

#After showing up location based restaurants, a particular restaurant was shown and food they are having will be shown up
def Food_List(request, r_id):
  FL = Restaurant_Food_New.objects.filter(Restaurant_Id__Restaurant_Id=r_id)
  return render(request,'food.html',{'fl':FL})

#User Details getting registered using this view
def register(request):
  if request.method == 'POST':
    user_form = UserForm(request.POST)
    customer_form = CustomerForm(request.POST)

    if user_form.is_valid() and customer_form.is_valid():
      user_form.save()
      customer_form.save()
      return redirect('location')

  else:
    user_form = UserForm()
    customer_form = CustomerForm()

  context = {
    'user_form': user_form,
    'customer_form': customer_form
  }

  return render(request, 'register.html', context)


"""Convert COLMAP-style SfM results to NeRF input format

Ref: https://github.com/NVlabs/instant-ngp/blob/master/scripts/colmap2nerf.py

This is a truncated version edited by Ren Liu.
"""

import argparse
import json
import math
import os
from typing import Tuple

import cv2
import numpy as np

def parse_args() -> argparse.Namespace:
    """Parse arguments from user input
    Returns:
        parsed arguments
    """
    parser = argparse.ArgumentParser(
        description="convert a text colmap export to nerf format transforms.json; optionally convert video to images, \
            and optionally run colmap in the first place"
    )

    parser.add_argument("--images", default="images", help="input path to the images")
    parser.add_argument(
        "--text",
        default="colmap_text",
        help="input path to the colmap text files (set automatically if run_colmap is used)",
    )
    parser.add_argument(
        "--aabb_scale",
        default=16,
        choices=["1", "2", "4", "8", "16"],
        help="large scene scale factor. 1=scene fits in unit cube; power of 2 up to 16",
    )
    parser.add_argument("--skip_early", default=0, help="skip this many images from the start")
    parser.add_argument("--out", default=".", help="output path")
    return parser.parse_args()

def variance_of_laplacian(image: cv2.Mat) -> float:
    """compute the variance of laplacian of the input image

    Args:
        image: input image, in shape of (H, W)
    Returns:
        the variance of laplacian
    """
    return cv2.Laplacian(image, cv2.CV_64F).var()

def sharpness(imagePath: str) -> float:
    """compute the sharpness of the input image

    Args:
        imagePath: input image path
    Returns:
        the sharpness of laplacian
    """
    image = cv2.imread(imagePath)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    fm = variance_of_laplacian(gray)
    return fm

def qvec2rotmat(qvec: np.ndarray) -> np.ndarray:
    """Convert quaternion rotation vector to 3x3 rotation matrix

    Args:
        qvec: a quaternion rotation vector, in shape of (4,)

    Returns:
        the corresponding 3x3 rotation matrix
    """
    return np.array(
        [
            [
                1 - 2 * qvec[2] ** 2 - 2 * qvec[3] ** 2,
                2 * qvec[1] * qvec[2] - 2 * qvec[0] * qvec[3],
                2 * qvec[3] * qvec[1] + 2 * qvec[0] * qvec[2],
            ],
            [
                2 * qvec[1] * qvec[2] + 2 * qvec[0] * qvec[3],
                1 - 2 * qvec[1] ** 2 - 2 * qvec[3] ** 2,
                2 * qvec[2] * qvec[3] - 2 * qvec[0] * qvec[1],
            ],
            [
                2 * qvec[3] * qvec[1] - 2 * qvec[0] * qvec[2],
                2 * qvec[2] * qvec[3] + 2 * qvec[0] * qvec[1],
                1 - 2 * qvec[1] ** 2 - 2 * qvec[2] ** 2,
            ],
        ]
    )

def rotmat(a: np.ndarray, b: np.ndarray) -> np.ndarray:
    """calculate the 3x3 rotation matrix from vector a to vector b

    Args:
        a: orginal vector, in shape of (3,)
        b: target vector, in shape of (3,)

    Returns:
        result rotation matrix, in shape of (3, 3)
    """
    a, b = a / np.linalg.norm(a), b / np.linalg.norm(b)
    v = np.cross(a, b)
    c = np.dot(a, b)
    s = np.linalg.norm(v)
    kmat = np.array([[0, -v[2], v[1]], [v[2], 0, -v[0]], [-v[1], v[0], 0]])
    return np.eye(3) + kmat + kmat.dot(kmat) * ((1 - c) / (s ** 2 + 1e-10))

def closest_point_2_lines(oa: np.ndarray, da: np.ndarray, ob: np.ndarray, db: np.ndarray) -> Tuple[np.ndarray, float]:
    """returns point closest to both rays of form o+t*d, and a weight factor that goes to 0 if the lines are parallel

    Args:
        oa: origin of the first ray, in shape of (3, )
        da: direction of the first ray, in shape of (3, )
        ob: origin of the second ray, in shape of (3, )
        db: direction of the second ray, in shape of (3, )

    Returns:
        1. the point closest to both rays of form o+t*d, in shape of (3, )
        2. a weight factor that goes to 0 if the lines are parallel
    """
    da = da / np.linalg.norm(da)
    db = db / np.linalg.norm(db)
    c = np.cross(da, db)
    denom = np.linalg.norm(c) ** 2
    t = ob - oa
    ta = np.linalg.det([t, db, c]) / (denom + 1e-10)
    tb = np.linalg.det([t, da, c]) / (denom + 1e-10)
    if ta > 0:
        ta = 0
    if tb > 0:
        tb = 0
    return (oa + ta * da + ob + tb * db) * 0.5, denom

if __name__ == "__main__":
    args = parse_args()

    AABB_SCALE = int(args.aabb_scale)
    SKIP_EARLY = int(args.skip_early)
    IMAGE_FOLDER = args.images
    TEXT_FOLDER = args.text
    OUT_PATH = args.out
    print(f"outputting to {OUT_PATH}...")
    with open(os.path.join(TEXT_FOLDER, "cameras.txt"), "r") as f:
        angle_x = math.pi / 2
        for line in f:
            # 1 SIMPLE_RADIAL 2048 1536 1580.46 1024 768 0.0045691
            # 1 OPENCV 3840 2160 3178.27 3182.09 1920 1080 0.159668 -0.231286 -0.00123982 0.00272224
            # 1 RADIAL 1920 1080 1665.1 960 540 0.0672856 -0.0761443
            if line[0] == "#":
                continue
            els = line.split(" ")
            w = float(els[2])
            h = float(els[3])
            fl_x = float(els[4])
            fl_y = float(els[4])
            k1 = 0
            k2 = 0
            p1 = 0
            p2 = 0
            cx = w / 2
            cy = h / 2
            if els[1] == "SIMPLE_PINHOLE":
                cx = float(els[5])
                cy = float(els[6])
            elif els[1] == "PINHOLE":
                fl_y = float(els[5])
                cx = float(els[6])
                cy = float(els[7])
            elif els[1] == "SIMPLE_RADIAL":
                cx = float(els[5])
                cy = float(els[6])
                k1 = float(els[7])
            elif els[1] == "RADIAL":
                cx = float(els[5])
                cy = float(els[6])
                k1 = float(els[7])
                k2 = float(els[8])
            elif els[1] == "OPENCV":
                fl_y = float(els[5])
                cx = float(els[6])
                cy = float(els[7])
                k1 = float(els[8])
                k2 = float(els[9])
                p1 = float(els[10])
                p2 = float(els[11])
            else:
                print("unknown camera model ", els[1])
            # fl = 0.5 * w / tan(0.5 * angle_x);
            angle_x = math.atan(w / (fl_x * 2)) * 2
            angle_y = math.atan(h / (fl_y * 2)) * 2
            fovx = angle_x * 180 / math.pi
            fovy = angle_y * 180 / math.pi

    print(f"camera:\n\tres={w,h}\n\tcenter={cx,cy}\n\tfocal={fl_x,fl_y}\n\tfov={fovx,fovy}\n\tk={k1,k2} p={p1,p2} ")

    with open(os.path.join(TEXT_FOLDER, "images.txt"), "r") as f:
        i = 0
        bottom = np.array([0.0, 0.0, 0.0, 1.0]).reshape([1, 4])
        out = {
            "camera_angle_x": angle_x,
            "camera_angle_y": angle_y,
            "fl_x": fl_x,
            "fl_y": fl_y,
            "k1": k1,
            "k2": k2,
            "p1": p1,
            "p2": p2,
            "cx": cx,
            "cy": cy,
            "w": w,
            "h": h,
            "aabb_scale": AABB_SCALE,
            "frames": [],
        }

        up = np.zeros(3)
        for line in f:
            line = line.strip()
            if line[0] == "#":
                continue
            i = i + 1
            if i < SKIP_EARLY * 2:
                continue
            if i % 2 == 1:
                elems = line.split(
                    " "
                )  # 1-4 is quat, 5-7 is trans, 9ff is filename (9, if filename contains no spaces)
                # name = str(PurePosixPath(Path(IMAGE_FOLDER, elems[9])))
                # why is this requireing a relitive path while using ^
                image_rel = os.path.relpath(IMAGE_FOLDER)
                name = str(f"./{image_rel}/{'_'.join(elems[9:])}")
                b = sharpness(name)
                print(name, "sharpness=", b)
                image_id = int(elems[0])
                qvec = np.array(tuple(map(float, elems[1:5])))
                tvec = np.array(tuple(map(float, elems[5:8])))
                R = qvec2rotmat(-qvec)
                t = tvec.reshape([3, 1])
                m = np.concatenate([np.concatenate([R, t], 1), bottom], 0)
                c2w = np.linalg.inv(m)
                c2w[0:3, 2] *= -1  # flip the y and z axis
                c2w[0:3, 1] *= -1
                c2w = c2w[[1, 0, 2, 3], :]  # swap y and z
                c2w[2, :] *= -1  # flip whole world upside down

                up += c2w[0:3, 1]

                frame = {"file_path": name, "sharpness": b, "transform_matrix": c2w}
                out["frames"].append(frame)
    nframes = len(out["frames"])
    up = up / np.linalg.norm(up)
    print("up vector was", up)
    R = rotmat(up, [0, 0, 1])  # rotate up vector to [0,0,1]
    R = np.pad(R, [0, 1])
    R[-1, -1] = 1

    for f in out["frames"]:
        f["transform_matrix"] = np.matmul(R, f["transform_matrix"])  # rotate up to be the z axis

    # find a central point they are all looking at
    print("computing center of attention...")
    totw = 0.0
    totp = np.array([0.0, 0.0, 0.0])
    for f in out["frames"]:
        mf = f["transform_matrix"][0:3, :]
        for g in out["frames"]:
            mg = g["transform_matrix"][0:3, :]
            p, w = closest_point_2_lines(mf[:, 3], mf[:, 2], mg[:, 3], mg[:, 2])
            if w > 0.01:
                totp += p * w
                totw += w
    totp /= totw
    print(totp)  # the cameras are looking at totp
    for f in out["frames"]:
        f["transform_matrix"][0:3, 3] -= totp

    avglen = 0.0
    for f in out["frames"]:
        avglen += np.linalg.norm(f["transform_matrix"][0:3, 3])
    avglen /= nframes
    print("avg camera distance from origin", avglen)
    for f in out["frames"]:
        f["transform_matrix"][0:3, 3] *= 4.0 / avglen  # scale to "nerf sized"

    for f in out["frames"]:
        f["transform_matrix"] = f["transform_matrix"].tolist()
    print(nframes, "frames")
    print(f"writing {OUT_PATH}/transforms.json")
    if not os.path.exists(OUT_PATH):
        os.makedirs(OUT_PATH)
    with open(os.path.join(OUT_PATH, "transforms.json"), "w") as outfile:
        json.dump(out, outfile, indent=2)


#pressing button or in case applying high voltage to any of this outputs can run its function
#this is a sound player that gives you ability to play, next, previus, stop, pause, unpause the sound.
#Only .wav files can be handeled
# we are supposed to use it to give surgery instructions.
import pygame.mixer
from time import sleep
import RPi.GPIO as GPIO
from sys import exit
import glob
import os
GPIO.setmode(GPIO.BCM)
#previous button
GPIO.setup(23, GPIO.IN)
#play button
GPIO.setup(24, GPIO.IN)
#next button
GPIO.setup(25, GPIO.IN)
#pause button
GPIO.setup(13, GPIO.IN)
#Unpause button
GPIO.setup(19, GPIO.IN)
#stop button
GPIO.setup(16, GPIO.IN)
#buzzer button
GPIO.setup(12, GPIO.IN)

pygame.mixer.init(48000, -16, 1, 1024)

soundChannelA = pygame.mixer.Channel(1)
soundChannelBuzzer = pygame.mixer.Channel(2)

dirname="/home/pi/Documents/sound_sample/"
print("Sampler Ready.")
pattern = '*.wav'
files = glob.glob(os.path.join(dirname, pattern))
files = sorted(files) # sort in alphabetical order
print(files)
count=0
#btnPlay = Button("Play", 23, __onPlayButtonChanged) # GPIO header pin 22
#btnPrevious = Button("Previous", 24, __onPreviousButtonChanged) # GPIO header pin 16
#btnNext = Button("Next", 25, __onNextButtonChanged) # GPIO header pin 18

input_pin = 23
GPIO.setmode(GPIO.BCM)
GPIO.setup(input_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
def my_function_play(channel):
    global count
    if GPIO.input(24)==GPIO.HIGH:
        print("I was called Play!")

        print("count",count)
        if count>0 and count <len(files):
         print("index",count)
         soundChannelA.play(pygame.mixer.Sound(files[count]))
        else:
          count=0
          print("index",count)
          soundChannelA.play(pygame.mixer.Sound(files[count]))

input_pin = 24
GPIO.setmode(GPIO.BCM)
GPIO.setup(input_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
def my_function_previous(channel):
    global count
    if GPIO.input(23)==GPIO.HIGH:
        global count
        print("I was called Previous!")
        print("count",count)
        if count>0:
                  count=count-1
        else:
                  count=0
        print("index",count)
        soundChannelA.play(pygame.mixer.Sound(files[count]))

input_pin = 25
GPIO.setmode(GPIO.BCM)
GPIO.setup(input_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
def my_function_Next(channel):
    global count
    if GPIO.input(25)==GPIO.HIGH:

        print("I was called Next!")
        print("count",count)
        if count<len(files):
              count=count+1

        else:
              count=0
        print("index",count)
        soundChannelA.play(pygame.mixer.Sound(files[count]))

def paused(channel):
    if GPIO.input(13)==GPIO.HIGH:
        ############
        print("I was called pause!")
        pygame.mixer.pause()
        #############
def unpause(channel):
    if GPIO.input(19)==GPIO.HIGH:
        global pause
        print("I was called unpause!")
        #################
        pygame.mixer.unpause()
        #################
        #pause = False
def stoped(channel):
    if GPIO.input(16)==GPIO.HIGH:
        print("I was called stop!")
        global pause
        #################
        pygame.mixer.stop()
    #################
    #pause = False
GPIO.setup(21,GPIO.OUT)
def buzzer_play(channel):
        if GPIO.input(12)==GPIO.HIGH:
            print("I was called buzzer!")
            soundChannelBuzzer.play(pygame.mixer.Sound("/home/pi/Documents/sound_sample/Buzzer-Sound.wav"))
            GPIO.output(21,GPIO.HIGH)
        else:
            GPIO.output(21,GPIO.LOW)
GPIO.setmode(GPIO.BCM)
GPIO.setup(13, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setmode(GPIO.BCM)
GPIO.setup(19, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setmode(GPIO.BCM)
GPIO.setup(16, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setmode(GPIO.BCM)
GPIO.setup(12, GPIO.IN, pull_up_down=GPIO.PUD_UP)
#while True:
##    #GPIO.add_event_detect(12, GPIO.RISING, callback=lambda x:buzzer_play(count), bouncetime=2)
#GPIO.add_event_detect(23, GPIO.FALLING, callback=lambda x: my_function_previous(count), bouncetime=200)
#GPIO.add_event_detect(24, GPIO.FALLING, callback=lambda x:my_function_play(count), bouncetime=20)
#GPIO.add_event_detect(25, GPIO.FALLING, callback=lambda x:my_function_Next(count), bouncetime=200)
#GPIO.add_event_detect(13, GPIO.FALLING, callback=lambda x:paused(count), bouncetime=200)
#GPIO.add_event_detect(19, GPIO.FALLING, callback=lambda x:unpause(count), bouncetime=200)
#GPIO.add_event_detect(16, GPIO.FALLING, callback=lambda x:stoped(count), bouncetime=200)
##GPIO.add_event_detect(12, GPIO.FALLING, callback=lambda x:buzzer_play(count), bouncetime=200)
#GPIO.add_event_detect(12, GPIO.FALLING, callback=lambda x:buzzer_play(count), bouncetime=2)
#    if GPIO.input(23)==GPIO.HIGH:
GPIO.add_event_detect(23, GPIO.RISING, callback=lambda x: my_function_previous(count), bouncetime=200)

#        my_function_previous(count)

#    if GPIO.input(24)==GPIO.HIGH:
GPIO.add_event_detect(24, GPIO.RISING, callback=lambda x:my_function_play(count), bouncetime=20)

#    if GPIO.input(25)==GPIO.HIGH:
#        my_function_Next(count)
GPIO.add_event_detect(25, GPIO.RISING, callback=lambda x:my_function_Next(count), bouncetime=200)

#    if GPIO.input(13)==GPIO.HIGH:
GPIO.add_event_detect(13, GPIO.RISING, callback=lambda x:paused(count), bouncetime=200)

#    if GPIO.input(19)==GPIO.HIGH:
GPIO.add_event_detect(19, GPIO.RISING, callback=lambda x:unpause(count), bouncetime=200)

#    if GPIO.input(16)==GPIO.HIGH:
GPIO.add_event_detect(16, GPIO.RISING, callback=lambda x:stoped(count), bouncetime=200)

while True:

#    GPIO.add_event_detect(12, GPIO.FALLING, callback=lambda x:buzzer_play(count), bouncetime=2)
    if GPIO.input(12)==GPIO.HIGH:
        buzzer_play(12)
    else:
            GPIO.output(21,GPIO.LOW)

print("done")
    #while True:
#
#
#        #GPIO.cleanup()
##drill sound clip
##https://www.soundsnap.com/tags/drill
#
#


from flask import Flask, render_template, request
from bin.archive_downloader import download_archive
from bin.xml_reader import read_xml_file
from bin.create_year_data import create_raw_array
from bin.create_year_averages import yearly_average_constructor
from bin.sorting import *
from bin.generate_statistics import *
from dotenv import load_dotenv
import calendar, json, time, os, requests
import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration

load_dotenv()

sentry_sdk.init(
    dsn="https://" + os.getenv("SENTRY_DSN_URL"),
    integrations=[FlaskIntegration()]
)

app = Flask(__name__)

@app.route('/')
def home():
   return render_template('input.html', key = os.getenv("GOOGLE_MAPS_API_KEY"))

@app.route('/results',methods = ['POST', 'GET'])
def result():
   start = time.time()
   months_abbr = []
   months_full = []
   essence_types = ['gazole', 'sp98', 'e10', 'e85', 'gplc']

   for i in range(1, 13):
      months_abbr.append(calendar.month_abbr[i])
      months_full.append(calendar.month_name[i])

   if request.method == 'POST':
      location = request.form['location']

      key = os.getenv("GOOGLE_MAPS_API_KEY")

      postcode_request_url = "https://maps.googleapis.com/maps/api/geocode/json?address=" + str(location) + "&key=" + key

      postcode_geosearch = requests.get(postcode_request_url)
      data = postcode_geosearch.json()

      postcode = [int(address["long_name"]) for address in data['results'][0]["address_components"] if "postal_code" in address["types"]][0]

      # files = download_archive(os.getenv("DATA_ARCHIVE_NAME"), os.getenv("S3_BUCKET_NAME"))

      xml_data = read_xml_file(os.getenv("PATH_TO_DATA") + os.getenv("DATA_ARCHIVE_NAME") + '.xml')

      raw_array = create_raw_array(xml_data, postcode, location, key)

      pumps_infos = build_pump_list_infos(raw_array)

      now_time = time.strftime('%d/%m/%Y @ %T')

      results_length = len(raw_array)
      essence_types_length = len(essence_types)

      avg_minimums_by_essence_type = avg_minimums(raw_array)
      average_by_essence_type = avg_by_essence_type(raw_array)
      average_by_essence_type_totalb = avg_by_essence_type_totalb(raw_array)
      sorted_by_essence_type = sort_by_essence_type(raw_array)
      sorted_by_essence_type_totalb = sort_by_essence_type_totalb(raw_array)
      totalb_average = get_total_monthly_average(raw_array)
      non_totalb_average = get_non_total_monthly_average(raw_array)
      getback = yearly_average_constructor(raw_array)

      del raw_array
      # getback_json = json.dumps(getback)

      end = time.time()
      process_time = end - start
      return render_template("results.html",
                             getback = getback,
                             months_abbr = months_abbr,
                             months_full = months_full,
                             pumps_infos = pumps_infos,
                             totalb_average = totalb_average,
                             non_totalb_average = non_totalb_average,
                             sorted_by_essence_type = sorted_by_essence_type,
                             sorted_by_essence_type_totalb = sorted_by_essence_type_totalb,
                             postcode = postcode,
                             time = now_time,
                             address = location,
                             results_length = results_length,
                             essence_types_length = essence_types_length,
                             essence_types = essence_types,
                             average_by_essence_type = average_by_essence_type,
                             average_by_essence_type_totalb = average_by_essence_type_totalb,
                             avg_minimums_by_essence_type = avg_minimums_by_essence_type,
                             process_time = process_time
                             )

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


#In[]
'''
LeNet,上世纪80年代的产物,最初为了手写识别设计
'''

import torch
from torch import nn
from torch.nn.modules.loss import CrossEntropyLoss

from torch.utils import data
import torchvision
from torchvision import transforms

import Common_functions

'''
LeNet:
两个卷积层,两个池化层,三个线性层
假定为MNIST设计,输入为(batch_size,1,28,28)
'''
net = nn.Sequential(
    nn.Conv2d(in_channels=1,out_channels=6,kernel_size=(5,5),padding=2),nn.Sigmoid(), #输出:(6,28,28)
    nn.AvgPool2d(kernel_size=(2,2)), #不指定stride默认不重叠 输出(6,14,14)
    nn.Conv2d(6,16,kernel_size=(5,5)),nn.Sigmoid(),#输出(16,10,10)
    nn.AvgPool2d(kernel_size=(2,2)),#输出(16,5,5)
    nn.Flatten(),
    nn.Linear(16*5*5,120),nn.Sigmoid(),#
    nn.Linear(120,84),nn.Sigmoid(),
    nn.Linear(84,10)
)

#In[]

#加载数据
trans = transforms.ToTensor() #class,将PIL图片或numpy.ndarray格式转为tensor的类

mnist_train = torchvision.datasets.FashionMNIST('datasets/FashionMnist/',train=True,transform=trans,download=False)
mnist_test = torchvision.datasets.FashionMNIST('datasets/FashionMnist/',train=False,transform=trans,download=False)

batch_size = 256

train_iter = data.DataLoader(mnist_train,batch_size,shuffle=True)
test_iter = data.DataLoader(mnist_test,batch_size,shuffle=True)

#训练
if torch.cuda.is_available():
    device = "cuda:0"
else:
    device = "cpu"
device = torch.device(device)

Common_functions.train_device(net,train_iter,test_iter,lr=0.9,device=device)
# %%


import datetime
from datetime import timedelta

import numpy as np

__author__ = "Marcelo Ferreira da Costa Gomes"
"""
Return Brazilian epidemiological week from passed date
"""

def extractweekday(x=datetime.datetime):
    # Extract weekday as [Sun-Sat] |-> [0-6]
    # isoweekday() returns weekday with [Mon-Sun] as [1-7]
    w = x.isoweekday() % 7
    return w

def firstepiday(year=int):
    day = datetime.datetime.strptime("%s-01-01" % year, "%Y-%m-%d")

    day_week = extractweekday(day)

    # Whe want day1 to correspond to the first day of the first epiweek.
    # That is, we need the Sunday corresponding to epiweek=%Y01
    # If first day of the year is between Sunday and Wednesday,
    # epiweek 01 includes it. Otherwise, it is still the last epiweek
    # of the previous year
    if day_week < 4:
        day = day - datetime.timedelta(days=day_week)
    else:
        day = day + datetime.timedelta(days=(7 - day_week))

    return day

def lastepiday(year=int):
    day = datetime.datetime.strptime("%s-12-31" % year, "%Y-%m-%d")

    day_week = extractweekday(day)

    # Whe want day to correspond to the last day of the last epiweek.
    # That is, we need the corresponding Saturday
    # If the last day of the year is between Sunday and Tuesday,
    # epiweek 01 of the next year includes it.
    # Otherwise, it is still the last epiweek of the current year
    if day_week < 3:
        day = day - datetime.timedelta(days=(day_week + 1))
    else:
        day = day + datetime.timedelta(days=(6 - day_week))

    return day

def episem(x, sep="W", out="YW"):

    """
    Return Brazilian corresponding epidemiological week from x.

    :param x: Input date. Can be a string in the format %Y-%m-%d or
      datetime.datetime
    :param sep: Year and week separator.
    :param out: Output format. 'YW' returns sep.join(epiyear,epiweek).
     'Y' returns epiyear only. 'W' returns epiweek only.
    :return: str
    """

    def out_format(year, week, out, sep="W"):
        if out == "YW":
            return "%s%s%02d" % (year, sep, week)
        if out == "Y":
            return "%s" % (year)
        if out == "W":
            return "%02d" % week

    if type(x) != datetime.datetime:
        if str(x) == "" or x is None or (type(x) != str and np.isnan(x)):
            return None
        x = datetime.datetime.strptime(x, "%Y-%m-%d")

    epiyear = x.year
    epiend = lastepiday(epiyear)

    if x > epiend:
        epiyear += 1
        return out_format(epiyear, 1, out, sep)

    epistart = firstepiday(epiyear)

    # If current date is before its year first epiweek,
    # then our base year is the previous one
    if x < epistart:
        epiyear -= 1
        epistart = firstepiday(epiyear)

    epiweek = int(((x - epistart) / 7).days) + 1

    return out_format(epiyear, epiweek, out, sep)

def episem2date(epi_year_week: str, weekday: int = 0):
    r"""
    Function to obtain first day of corresponding Brazilian epidemiological
    week provided

    Function \code{episem2date} uses the Brazilian definition of
    epidemiological
    week and returns the date of the corresponding o the provided epi. week,
    using week day requested. Uses Sunday as default, the first week day by
    Brazilian epi.
    week definition.
    @see https://github.com/marfcg/leos.opportunity.estimator/
        blob/master/R/episem2date.R

    @name episem2date
    @param epiyearweek Epidemiological week in the format "%Y\[*\]%W"
        where Y and W defined by the Brazilian epidemiological week system.
        The separator between Y and W is irrelevant. Ex.: 2014W02
    @param weekday Week day to be used as representative of the epi. week.
        Uses Date week day classification. 0: Sunday, 6:Saturday. Default: 0

    @return Date corresponding to the Sunday of epiyearweek
    @export

    @examples
    epiyearweek <- '2014W02'
    episem2date(epiyearweek)

    Test:

    dt = datetime.datetime.now()

    yw1 = int(episem(dt, sep=''))
    dt1 = episem2date(yw1)
    yw2 = int(episem(dt1, sep=''))

    assert yw1 == yw2

    :param epi_year_week:
    :param weekday:
    :return:
    """
    # force str format
    epi_year_week = str(epi_year_week)
    # Separate year and week:
    if len(epi_year_week) not in [6, 7]:
        raise Exception("Epi Year Week not valid.")

    epiyear = int(epi_year_week[:4])
    epiweek = int(epi_year_week[-2:])

    # Obtain sunday of first epiweek of epiyear
    # day.one
    date_1 = datetime.datetime.strptime("%s-01-01" % epiyear, "%Y-%m-%d")
    # day.one.week
    date_1_w = int(date_1.strftime("%w"))

    # Check wether week day of Jan 1st was before or after a Wednesday
    # and set the start of the epiyear accordingly
    epiweek_day_1 = (
        date_1 - timedelta(days=date_1_w)
        if date_1_w <= 3
        else date_1 + timedelta(days=7 - date_1_w)
    )
    return epiweek_day_1 + timedelta(days=7 * (epiweek - 1) + weekday)


import os
import subprocess
from tempfile import NamedTemporaryFile

from torch.distributed import get_rank
from torch.distributed import get_world_size
from torch.utils.data.sampler import Sampler
from torch.autograd import Variable
from torch.utils.data import DataLoader
from torch.utils.data import Dataset
import torch.nn as nn

import librosa
import numpy as np
import scipy.io.wavfile as wav
import torch
import torchaudio
import math

def get_spectrogram(wavs, audio_conf):
    window_size = audio_conf['window_size']
    sample_rate = audio_conf['sample_rate']
    window_stride = audio_conf['window_stride']
    n_fft = int(window_size * sample_rate)
    win_length = n_fft
    hop_length = int(sample_rate * window_stride)
    batch_size = len(wavs)
    spects = torch.zeros(batch_size,1,(1+n_fft/2),410) #what the hell is t????? okay I'm hardcoding it.
    for i in range(batch_size):
        wav = wavs[i]
        wav = wav.cpu().data
        wav = wav.numpy()
        spec_model = librosa.stft(wav, n_fft=n_fft, hop_length=hop_length, win_length=win_length)
        spect, phase = librosa.magphase(spec_model)
        spect = np.log1p(spect)
        spect = torch.FloatTensor(spect).cuda()
        mean = spect.mean()
        std = spect.std()
        spect = (spect - mean) / std
        spect = torch.unsqueeze(spect,0)
        #print('spect size:', spect.size())
        spects[i].copy_(spect)       #hello bug

    return spects

def _collate_fn(batch):
    batch_size = len(batch)
    audios = torch.zeros(batch_size,2**16)
    transcripts = []
    for i in range(batch_size):
        data = batch[i]
        audio = data[0]
        target = data[1]
        audios[i].copy_(audio)
        transcripts.extend(target)
    return audios, transcripts

class audioLoader(DataLoader):
    def __init__(self, *args, **kwargs):
        super(audioLoader,self).__init__(*args, **kwargs)
        self.collate_fn = _collate_fn

class audioDataset(Dataset):
    def __init__(self, filepath, audio_conf):
        self.path = filepath
        # if load timit dataset -> parse file first
        with open(self.path) as file:
            tokens = file.readlines()
        tokens = [x.strip().split(',') for x in tokens]
        self.tokens = tokens
        self.size = len(tokens)
        self.config = audio_conf
        super(audioDataset,self).__init__()

    def __getitem__(self, index):
        sample = self.tokens[index]
        audio_path, transcript_path = sample[0], sample[1]
        print('audio:' , audio_path, 'transcript:' , transcript_path)
        audio = self.get_audio(audio_path)
        audio = audio.unsqueeze(0)
        with open(transcript_path, 'r', encoding='utf8') as transcript_file:
            transcript = transcript_file.read().replace('\n', '')
        return audio, transcript

    def __len__(self):
        return self.size

    def get_audio(self, file_path):
        audio, sample_rate = torchaudio.load(file_path)
        audio = audio.squeeze()
        size = int(audio.size()[0])
        #print('original size: ', size)
        if size > 2**16:
            target = audio[:2**16]
        else:
            padding_left = (2**16 - size)//2
            padding_right = 2**16 - size - padding_left
            target = torch.zeros(2**16)
            target[padding_left:2**16-padding_right] = audio
        #pad = nn.ReplicationPad1d((padding_left,padding_right))
        #audio = pad(audio)
        #print('padded size: ', target.size())
        #audio = np.pad(audio, n_fft//2, mode='reflect')
        #audio = torch.from_numpy(audio)
        #audio = audio.unsqueeze(0)
        return Variable(target)


import numpy as np
from scipy import stats

N = int(input())
x = [float(inp) for inp in input().split()]

mean = np.mean(x)
median = np.median(x)
mode = int(stats.mode(x)[0][0])

print( "%.1f" % mean );
print( "%.1f" % median );
print( mode );


import os
import yaml
import inspect

class Schema:

    def __new__(cls, *args, **kwargs):
        # Create a new instance of Schema
        return super().__new__(cls)

    def __init__(self):
        # Initialise
        here = os.path.dirname(os.path.abspath(inspect.getfile(Schema)))
        print(here)
        with open(here + "/schema/schema.yml", "r") as stream:
            try:
                self._yaml = yaml.safe_load(stream)
            except yaml.YAMLError as exc:
                print(exc)
                sys.exit()

    def subterms(self, term):
        terms = []
        for t in sorted(self._yaml['terms'], key = lambda pos: self._yaml['terms'][pos]['_position']):
            o = self._yaml['terms'][t]
            if o['scope'] == term['scope'] and 'super-term' in o.keys() and term['term'] == o['super-term']:
                terms.append(o)
        return terms

    def termsFor(self, typee):
        isContainer = False
        if typee == 'Container' or typee in map(lambda o:o['type'], self.containers()):
            isContainer = True
        terms = []
        for t in sorted(self._yaml['terms'], key = lambda pos: self._yaml['terms'][pos]['_position']):
            o = self._yaml['terms'][t]
            if 'super-term' not in o.keys() or o['super-term'] == '':
                if o['scope'] == 'Container' and isContainer:
                    terms.append(o)
                if o['scope'] == 'Component' and not isContainer:
                    terms.append(o)
        return terms

    def subtypes(self, typee):
        types = []
        for t in sorted(self._yaml['types'], key = lambda pos: self._yaml['types'][pos]['_position']):
            o = self._yaml['types'][t]
            if 'supertype-id' in o.keys() and typee == o['supertype-id']:
                types.append(o)
        return types

    def allsubtypes(self, typee):
        all = []
        types = self.subtypes(typee)
        all = all + types
        for t in types:
           all = all + self.allsubtypes(t['type'])
        return all

    def containers(self):
        return self.allsubtypes('Container')

    def components(self):
        return self.allsubtypes('Component')

    def types(self):
        types = []
        #sorted(student_Dict, key = lambda name: student_Dict[name].age)
        for t in sorted(self._yaml['types'], key = lambda pos: self._yaml['types'][pos]['_position']):
            o = self._yaml['types'][t]
            ks = ['type', 'label', 'supertype-id']
            t = {}
            for k in ks:
                if k in o:
                    t[k] = o[k]
            types.append(t)
        return types

    def terms(self):
        terms = []
        for t in sorted(self._yaml['terms'], key = lambda pos: self._yaml['terms'][pos]['_position']):
            o = self._yaml['terms'][t]
            terms.append(o)
        return terms
    def licences(self):
        licences = []
        for t in sorted(self._yaml['licences'], key = lambda pos: self._yaml['licences'][pos]['_position']):
            o = self._yaml['licences'][t]
            licences.append(o)
        return licences

    def asString(self, item, key):
        if key in item.keys():
            return item[key]
        else:
            return ''

# class MD:
#     def isComponent(self):
#         return True

# if __name__ == '__main__':
    # reeco = Schema()
    #     print(reeco.types())
    # out = eval("{ 'key': 1}")
#     out = eval("Schema()")
#     print(out, type(out))


import requests
import json

url = 'https://api.github.com'
user = 'SergeyOS'

response = requests.get(f'{url}/users/{user}/repos')

for i in response.json():
    print(i['name'])

with open('lesson_1.json', 'w') as j:
    json.dump(response.json(), j)


import requests #line:1
def send_message (O000OOOOOOOO0OO0O ,O0000O0O0O00O000O ):#line:3
    OO00000OOOOOO0O00 =requests .post (O000OOOOOOOO0OO0O ,json ={"content":O0000O0O0O00O000O })#line:4
    if OO00000OOOOOO0O00 .status_code ==204 :#line:5
        print ("Message sent successfully!")#line:6
    else :#line:7
        print ("Failed to send the message with status code:",OO00000OOOOOO0O00 .status_code )#line:8
def delete_webhook (OOO0OOO0O00O0O0O0 ):#line:10
    O0OO0O0OOO0OO0000 =requests .delete (OOO0OOO0O00O0O0O0 )#line:11
    if O0OO0O0OOO0OO0000 .status_code ==204 :#line:12
        print ("Webhook deleted successfully!")#line:13
    else :#line:14
        print ("Failed to delete the webhook with status code:",O0OO0O0OOO0OO0000 .status_code )#line:15
def main ():#line:17
    O00O000OOOO0OO0OO =input ("Enter the webhook URL: ")#line:18
    OOO0OOOO00O00O00O =input ("Do you want to send a last message? (y/n): ")#line:19
    if OOO0OOOO00O00O00O .lower ()=="y":#line:21
        O0O00O0O0000OOO00 =input ("Enter the message you want to send: ")#line:22
        send_message (O00O000OOOO0OO0OO ,O0O00O0O0000OOO00 )#line:23
    delete_webhook (O00O000OOOO0OO0OO )#line:25

    input("Press any key to quit.")

if __name__ == "__main__":
    main()


# coding=utf-8
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

import argparse
import os
import re
from pathlib import Path
from shutil import which
from typing import (
    List,
    Optional,
)

from .config import config
from .exceptions import Error
from .helpers import parse_config, which_path
from .subprocess_wrapper import check_call, check_output

class GitCommand:
    def __init__(self):
        """Check if Git is available, set initial values."""
        self.command = config.git_command.copy()
        if not which_path(self.command[0]):
            raise Error("Failed to find Git executable ({})".format(self.command[0]))

        # `self._env` is a dict representing environment used in all git commands.
        self._env = os.environ.copy()

        self.extensions = []
        self._cinnabar_installed = None
        self.safe_mode = config.safe_mode
        self.email = ""

    def call(self, git_args: List[str], **kwargs):
        unicode_args = [
            "-c",
            "i18n.logOutputEncoding=UTF-8",
            "-c",
            "i18n.commitEncoding=UTF-8",
        ]
        check_call(self.command + unicode_args + git_args, env=self._env, **kwargs)

    def output(
        self, git_args: List[str], extra_env: Optional[dict] = None, **kwargs
    ) -> str:
        env = dict(self._env)
        if extra_env:
            env.update(extra_env)

        unicode_args = [
            "-c",
            "i18n.logOutputEncoding=UTF-8",
            "-c",
            "i18n.commitEncoding=UTF-8",
        ]
        return check_output(self.command + unicode_args + git_args, env=env, **kwargs)

    def set_args(self, args: argparse.Namespace):
        """Read and set the configuration."""
        git_config = parse_config(self.output(["config", "--list"], never_log=True))

        safe_options = []

        # Need to use the correct username.
        if "user.email" not in git_config:
            raise Error("user.email is not configured in your gitconfig")

        self.email = git_config["user.email"]
        safe_options.extend(["-c", "user.email=%s" % git_config["user.email"]])

        if "user.name" in git_config:
            safe_options.extend(["-c", "user.name=%s" % git_config["user.name"]])

        if "cinnabar.helper" in git_config:
            self.extensions.append("cinnabar")
            safe_options.extend(
                ["-c", "cinnabar.helper=%s" % git_config["cinnabar.helper"]]
            )

        if args.safe_mode or self.safe_mode:
            # Ignore the user's Git config
            # To make Git not read the `~/.gitconfig` we need to temporarily change the
            # `$HOME` variable.
            self._env["HOME"] = ""
            self._env["XDG_CONFIG_HOME"] = ""
            self.command.extend(safe_options)

    @property
    def is_cinnabar_installed(self) -> bool:
        """Check if Cinnabar extension is callable."""
        if self._cinnabar_installed is None:
            # Unfortunately we cannot use --list-cmds as it requires git v2.18+

            # Normally cinnabar will be listed in the 'External commands' section.
            for line in self.output(["help", "--all"]):
                if re.search(r"^\s+cinnabar\b", line):
                    self._cinnabar_installed = True
                    break

            # Cinnabar might be installed in git's exec-path, which won't be
            # included in the `git help --all` output, nor is it necessarily
            # on the path.
            if not self._cinnabar_installed:
                exec_path = Path(self.output(["--exec-path"], split=False))
                if (exec_path / "git-cinnabar").exists():
                    self._cinnabar_installed = True

            # Finally check on the system path.
            if not self._cinnabar_installed:
                self._cinnabar_installed = which("git-cinnabar") is not None

        return self._cinnabar_installed


import redis
import json

redis_client = redis.StrictRedis(host='redis', port=6379, db=0)

def get_previous_searched_clothes_in_redis(tag) -> list:

    if redis_client.exists(tag):
        data = redis_client.lrange(tag, 0, -1)
        result_list = [json.loads(item) for item in data]
        return result_list

    return []

def add_clothes_to_list(tag, result):
        # Redis에 저장할 데이터를 JSON 형태로 직렬화
    result_json = json.dumps(result, ensure_ascii=False).encode('utf-8')

    # Redis에 데이터 추가
    if redis_client.exists(tag):
        # 기존 데이터에 추가
        redis_client.rpush(tag, result_json)
    else:
        # 새로운 리스트 생성
        redis_client.rpush(tag, result_json)
        # 만료 시간 설정 (5분)
        redis_client.expire(tag, 300)


import streamlit as st
import pandas as pd
import numpy
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots

from sklearn.linear_model import LinearRegression
import numpy as np
import math

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

st.set_page_config(layout="wide")

def make_charts_Bull(df, ticker, showchannel = True):
    fig = make_subplots(rows=2, cols=1, vertical_spacing=0.012, subplot_titles=(ticker,"Stochastic Oscillator"), shared_xaxes=True, row_heights=[0.6, 0.1])

    fig.add_trace(go.Candlestick(x=df['Date'],
                open=df['Open'],
                high=df['High'],
                low=df['Low'],
                close=df['Close'], name='Rainbow') ,row=1, col=1)
    fig.add_trace(go.Scatter(x=df.Date, y=df['EMA_8'], line=dict(color='red', width=1), name="EMA8") , row=1, col=1)
    fig.add_trace(go.Scatter(x=df.Date, y=df['EMA_21'], line=dict(color='orange', width=1), name="EMA21"), row=1, col=1)
    fig.add_trace(go.Scatter(x=df.Date, y=df['EMA_34'], line=dict(color='yellow', width=1), name="EMA34") , row=1, col=1)
    fig.add_trace(go.Scatter(x=df.Date, y=df['SMA_50'], line=dict(color='green', width=1), name="SMA50"), row=1, col=1)
    fig.add_trace(go.Scatter(x=df.Date, y=df['SMA_100'], line=dict(color='blue', width=1), name="SMA100"), row=1, col=1)
    fig.add_trace(go.Scatter(x=df.Date, y=df['SMA_200'], line=dict(color='violet', width=2), name="SMA200"), row=1, col=1)

    if showchannel == 'Yes':
        dtest = df.iloc[-84:]
        mindate = dtest[dtest['Low'] == dtest['Low'].min()]['Date'].iloc[0]
        mindateloc = dtest[dtest['Low'] == dtest['Low'].min()].index[0]
        lastdate = dtest['Date'].iloc[-1]

        dreg = dtest.loc[mindateloc:].drop(columns='Date')
        dreg = dreg.reset_index()
        X = dreg['index'].values.reshape(-1, 1)
        Y = dreg['Close'].values.reshape(-1, 1)
        linear_regressor = LinearRegression()
        linear_regressor.fit(X, Y)
        Y_pred = linear_regressor.predict(X)
        RSS = np.sum(np.square(Y - Y_pred))
        rse = math.sqrt(RSS / (len(Y) - 2))

        fig.add_trace(go.Scatter(x=[mindate,lastdate], y=[Y_pred[0][0], Y_pred[-1][0]], line=dict(color='gray', width=1)) , row=1, col=1)
        fig.add_trace(go.Scatter(x=[mindate,lastdate], y=[Y_pred[0][0]+2*rse, Y_pred[-1][0]+2*rse], line=dict(color='black', width=1)) , row=1, col=1)
        fig.add_trace(go.Scatter(x=[mindate,lastdate], y=[Y_pred[0][0]-2*rse, Y_pred[-1][0]-2*rse], line=dict(color='black', width=1)) , row=1, col=1)
        #fig.add_trace(go.Scatter(x=[mindate,lastdate], y=[Y_pred[0][0]-1.5 *rse,Y_pred[-1][0]-1.5 *rse], line=dict(color='gray', width=1), fill='tonexty') , row=1, col=1)

    fig.add_trace(go.Scatter(
             x=df.Date,
             y=df["%D"], line=dict(color='orange', width=2), name="%K (Slow)"), row=2, col=1)
    fig.add_hline(y=60, line_width=2, line_dash="dash", line_color="red",row=2, col=1)
    fig.add_hline(y=40, line_width=2, line_dash="dash", line_color="green",row=2, col=1)

    fig.update_layout(height=800)
    fig.update_xaxes(rangebreaks=[dict(bounds=["sat", "mon"])])

    fig.update_layout(
        xaxis=dict(
            rangeselector=dict(
                buttons=[
                    dict(count=6,
                         label="6m",
                         step="month",
                         stepmode="backward"),
                    dict(count=1,
                         label="YTD",
                         step="year",
                         stepmode="todate"),
                    dict(count=1,
                         label="1y",
                         step="year",
                         stepmode="backward"),
                    dict(step="all")
                ]),
            type="date"),#end xaxis  definition

        xaxis1_rangeslider_visible=False,
        xaxis2_rangeslider_visible=False,
        xaxis2_type="date"
        );

    return fig

showchannel = st.radio("Show trend:",('Yes', 'No'))

df = pd.read_csv('SLF.csv', index_col=0)
df = df[-200:]
df.reset_index(inplace=True)
ticker = 'SLF'
fig = make_charts_Bull(df, ticker, showchannel = showchannel)
st.plotly_chart(fig,theme=None, use_container_width=True)


import sys
from itertools import permutations

def happiness(scores, people):
    def score(perm):
        return scores[(perm[-1], perm[0])] + sum(
            scores[(p1, p2)] for p1, p2 in zip(perm[:-1], perm[1:])
        )

    return max(score(perm) + score(list(reversed(perm))) for perm in permutations(people))

def parse_input(input):
    scores = {}
    people = set()
    for instruction in input:
        p1, _, gain_or_lose, n, _, _, _, _, _, _, p2 = instruction.rstrip()[:-1].split(" ")
        scores[(p1, p2)] = int(n) if gain_or_lose == "gain" else -int(n)
        people.add(p1)
        people.add(p2)
    return scores, people

def main1(input):
    return happiness(*parse_input(input))

def main2(input):
    scores, people = parse_input(input)
    people.add("me")
    for person in people:
        scores[("me", person)] = 0
        scores[(person, "me")] = 0
    return happiness(scores, people)

if __name__ == "__main__":
    input = sys.stdin
    main = main2 if "--two" in sys.argv else main1
    print(main(input), file=sys.stdout)


#!/usr/bin/python3
#description     : This script automates the breaks on shift
#author		     : Florin Badea for SiteGround
#date            : 18.10.2017
#usage		     : ./break.py $NO where $NO is the time you wish to break for
#requirements    : install pip3 and pyautogui
#=============================================================================

import time
import pyautogui
import sys
import datetime

breakTime = int(sys.argv[1])
now       = datetime.datetime.now()
diff      = datetime.timedelta(seconds=breakTime*60)
beBackAt  = now + diff

print("Starting break for {} min.".format(breakTime))
#print time at the break start and when to be back
#print("Current time is: {}".format(time.strftime('%X %x %Z')))
print("Current time is: {}".format(now.strftime('%H:%M:%S')), '\n')
print("Be back at: {}".format(beBackAt.strftime('%H:%M:%S')), '\n')
#focus chrome browser
pyautogui.click(800, 1065)
#focus the helpdesk window
pyautogui.click(2016, 0)

#scroll up
pyautogui.press('pageup')
pyautogui.press('pageup')

#click the SiteGround logo to go to the homepage
#pyautogui.click(2051, 148)

#wait for the page to load
#time.sleep(3)
#click break
pyautogui.click(2997, 164)
time.sleep(2)
#click the dialog box
pyautogui.click(3039, 161)

#move mouse away from the break button
pyautogui.moveTo(2697, 515)

#wait for the amount of time passed as the argument (breakTime)
time.sleep(breakTime * 60)

#end break
pyautogui.click(2997, 164)
time.sleep(2)
pyautogui.click(3039, 161)

#move mouse away from the break button
pyautogui.moveTo(2697, 515)

print("{} min break ended.".format(breakTime))


from youtube_transcript_api import YouTubeTranscriptApi
from transformers import pipeline
from flask import Flask, request, jsonify,render_template
from flask_cors import CORS
import requests
import transformers

app = Flask(__name__)

cors = CORS(app)

def generate_transcript(url):
    id = url[url.index("=")+1:]

    transcript = YouTubeTranscriptApi.get_transcript(id)
    script = ""

    for text in transcript:
        t = text["text"]
        if t != '[Music]':
            script += t + " "

    return script

@app.route("/post", methods=["POST"])
def getME():
    url = request.get_json()['mes']
    print(url)
    API_URL = "https://api-inference.huggingface.co/models/sshleifer/distilbart-cnn-12-6"
    def query(payload):
        response = requests.post(API_URL, json=payload)
        return response.json()

    output = query({
        "inputs": generate_transcript(url),
    })

    res = output[0]['summary_text']
    print(res)

    return jsonify(res)

@app.route("/rec", methods=["GET","POST"])
def postME():
    summarization = pipeline(model='sshleifer/distilbart-cnn-12-6')
    res = summarization(generate_transcript('https://www.youtube.com/watch?v=0oBi8OmjLIg'), truncation=True)[0]['summary_text']
    return res

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


import random
import string

from tornado.httpclient import HTTPClient, HTTPRequest
import simplejson as json

from gemstone.discovery.base import BaseDiscoveryStrategy

class HttpDiscoveryStrategy(BaseDiscoveryStrategy):
    """
    A discovery strategy that uses the HTTP protocol as transport. Each ``ping`` and ``locate``
    calls translate to HTTP requests.

    """
    def __init__(self, registry_location):
        self.registry = registry_location

    def make_jsonrpc_call(self, url, method, params):
        client = HTTPClient()
        body = json.dumps({
            "jsonrpc": "2.0",
            "method": method,
            "params": params,
            "id": "".join([random.choice(string.ascii_letters) for _ in range(10)])
        })

        request = HTTPRequest(url, method="POST", headers={"content-type": "application/json"},
                              body=body)
        result = client.fetch(request)
        return result

    def ping(self, name, location, **kwargs):
        self.make_jsonrpc_call(self.registry, "ping",
                               {"name": name, "url": location})

    def locate(self, name):
        response = self.make_jsonrpc_call(self.registry, "locate_service", {"name": name})
        resp_as_dict = json.loads(response.body.decode())
        return resp_as_dict["result"]


# -*- coding: utf-8 -*-
import datetime
import os
from subprocess import call
from multiprocessing import Process
import time
import codecs
import jinja2
import traceback
import sys

from visual import show as pg_show
from visual import plot

PY_INTERFACE = 'py_interface.dat'
OUT_FILE = 'out' + os.path.sep + 'out_{0}_{1}.dat'
PERIOD = 0.004
ENERGY_COEFF = 278

TABLE_TEMPLATE = 'table_template.html'
EMPTY_TEMPLATE = 'empty_template.html'
TEAMS_TEMPLATE = 'teams_template.html'
PRICE_TEMPLATE = 'price_template.html'
SHOW_TEMPLATE = 'new_show_template.html'
MAX_POWER_TEMPLATE = 'max_power_template.html'
MIN_COST_TEMPLATE = 'min_cost_template.html'
TOP_PROFIT_TEMPLATE = 'top_profit_template.html'

MAX_POWER = 0.03
POWER_PRICE = 40
PODSTAVA = 1.5

PG_DATA_FILE = os.path.join(os.path.dirname(__file__), 'visual', 'config')

IDLE = False

DEBUG = False

TEAMS = {
    '1': {
        'name': u'Китайская установка «Мао Цзедун»',
        'cost': 5000,
        'power': 53.4,
    },
    '2': {
        'name': u'Тестовая команда 2',
        'cost': 5050,
        'power': 1130,
    },
    '3': {
        'name': u'Тестовая команда 3',
        'cost': 3000,
        'power': 910,
    },
    '4': {
        'name': u'foobar',
        'cost': 3000,
        'power': 910,
    },
    '5': {
        'name': u'Тестовая команда 5',
        'cost': 3000,
        'power': 910,
    },
    '6': {
        'name': u'Тестовая команда 6',
        'cost': 3000,
        'power': 910,
    },
    # '7': {
    #     'name': u'Тестовая команда 3',
    #     'cost': 3000,
    #     'power': 910,
    # },
    # '8': {
    #     'name': u'Тестовая команда 3',
    #     'cost': 3000,
    #     'power': 910,
    # },
    # '9': {
    #     'name': u'Тестовая команда 3',
    #     'cost': 3000,
    #     'power': 910,
    # },
    # '10': {
    #     'name': u'Тестовая команда 3',
    #     'cost': 3000,
    #     'power': 910,
    # },
}

RESISTANCE =1.2
        #На прошлом запуске RESISTANCE=0.47

def get_profit(power, cost):
    return round(power * POWER_PRICE - cost, 2)

def render_template(template, **kwargs):
    loader = jinja2.FileSystemLoader(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'templates'))
    env = jinja2.Environment(loader=loader)
    template = env.get_template(template)

    with codecs.open(
            os.path.join(os.path.dirname(os.path.realpath(__file__)), 'output', 'hardcode.html'), 'wb', 'utf-8') as f:
        f.write(template.render(**kwargs))

def render_table(team_name, power, cost, time):
    print(time)
    render_template(TABLE_TEMPLATE, team_name=team_name, power=power, cost=cost, time=time)

def render_empty():
    render_template(EMPTY_TEMPLATE)

def run_cpp():
    call('ReadData.exe')

def _show():
    pg_show.main()

def battery_picture(team, val):
    with open(PG_DATA_FILE, 'w') as f:
        f.write('\n'.join([team.encode('utf8'), str(val)]))

def read_data(team_id='dry', podstava=False):
    pointer = 0
    power = 0

    points = []
    cumulative = []

    if os.path.isfile(PY_INTERFACE):
        os.remove(PY_INTERFACE)
    # if os.path.isfile(OUT_FILE.format(team_id)):
        # os.remove(OUT_FILE.format(team_id))

    with open(PY_INTERFACE, 'w'):
        pass
    cpp = Process(target=run_cpp)
    now = datetime.datetime.now().strftime('%d-%m-%y %X').replace(':', '-')
    try:
        with open(OUT_FILE.format(team_id, now), 'w') as outf:
            outf.write('count\tvoltage\tpower\tenergy\n')
            cpp.start()
            now = time.time() + 10
            start_time = None
            update_time = None
            point_energy = 0
            while True:
                with open(PY_INTERFACE, 'r') as f:
                    info = f.readlines()
                    info = info[2:]
                    if len(info) > pointer + 1:
                        curinfo = info[pointer:-1]
                        for i, volt in enumerate(curinfo):
                            point_energy = (float(volt) ** 2 / RESISTANCE) * PERIOD * ENERGY_COEFF
                            if podstava:
                                point_energy *= PODSTAVA
                            power += point_energy
                            battery_picture(TEAMS[team_id]['name'], power)
                            points.append(point_energy)
                            cumulative.append(power)
                            outf.write('{p}\t{v}\t{pe}\t{power}\n'.format(p=(pointer + i + 1), v=volt.strip(), pe=point_energy, power=power))
                        pointer = len(info) - 1
                        now = time.time()
                    cur_time = time.time()
                    if point_energy > 0.001:
                        if start_time is None:
                            start_time = time.time()
                            update_time = time.time()
                    if update_time is not None:
                        if cur_time - update_time >= 1:
                            update_time = cur_time
                            render_table(TEAMS[team_id]['name'], power, TEAMS[team_id]['cost'], int(cur_time - start_time))
                    if cur_time - now > 1:
                        break
    except Exception as e:
        print('Fuck you')
        print(traceback.print_exc())
    finally:
        print('======================')
        print(power)
        cpp.join()
        # raw_input('<>')
        plot.plot(points, cumulative, TEAMS[team_id]['name'])
        return(power)

def show():
    while True:
        comm = raw_input('show --> ')
        if comm == '0':
            render_template(PRICE_TEMPLATE, cost=POWER_PRICE)
        elif comm == '1':
            rows = [{'place': '', 'name': v['name'], 'cost': round(v['cost'], 2), 'power': '', 'id': k, 'profit_string': ''} for k, v in TEAMS.iteritems()]
            rows = sorted(rows, key=lambda me: int(me['id']), reverse=False)
            render_template(SHOW_TEMPLATE, rows=rows)
        elif comm == '2':
            rows = [{'place': '', 'name': v['name'], 'cost': round(v['cost'], 2), 'power': round(v['power'], 2), 'id': k, 'profit_string': ''} for k, v in TEAMS.iteritems()]
            rows = sorted(rows, key=lambda me: int(me['id']), reverse=False)
            render_template(SHOW_TEMPLATE, rows=rows)
        elif comm == '3':
            rows = [{'place': '', 'name': v['name'], 'cost': round(v['cost'], 2), 'power': round(v['power'], 2), 'id': k, 'profit_string': ''} for k, v in TEAMS.iteritems()]
            for row in rows:
                row['profit'] = get_profit(row['power'], row['cost'])
                row['profit_string'] = str(row['profit']) + u' руб'

            rows = sorted(rows, key=lambda me: me['profit'], reverse=True)
            place = 1
            for row in rows:
                row['place'] = place
                place += 1
            render_template(SHOW_TEMPLATE, rows=rows)
        elif comm == 'clear':
            render_empty()
        elif comm == 'fi':
            return
        else:
            print('Unknown command.')

def main(dry_run=False):
    if not os.path.isdir('out'):
        os.makedirs('out')
    if not dry_run:
        s = Process(target=_show)
        s.start()
        battery_picture('', '0')
    try:
        while True:
            try:
                comm = raw_input('--> ')
                if comm == 'restart':
                    s.join()
                    del(s)
                    s = Process(target=_show)
                    s.start()
                elif comm.startswith('r'):
                    team_params = comm.split(' ')
                    if len(team_params) < 2:
                        print('Tell me the team id.')
                        continue
                    team_id = team_params[1]
                    if team_id not in TEAMS:
                        print('No such team.')
                        continue
                    render_table(TEAMS[team_id]['name'], 0, TEAMS[team_id]['cost'], 0)
                    battery_picture(TEAMS[team_id]['name'], '0')
                    raw_input('Press ENTER:')
                    power = read_data(team_id, podstava=('!' in team_params))
                    TEAMS[team_id]['power'] = power

                elif comm == 'show':
                    render_empty()
                    show()
                elif comm == 'clear':
                    battery_picture('', '0')
                    render_empty()
                elif comm == 'fi':
                    battery_picture('fi', '0')
                    return
                else:
                    print('Unknown command.')
            except Exception as e:
                print('Something is wrong.')
                print(e)
                print(traceback.print_exc())
    finally:
        if not dry_run:
            s.join()

if __name__ == '__main__':
    dry_run = 'dry-run' in sys.argv
    main(dry_run)


""" script to get the basic tuning curve """

import os
import sys
import numpy as np
import scipy as sp
import pandas as pd         # pandas tabular DataFrame for task/behavioral data
import matplotlib as mpl    # plot
import matplotlib.pyplot as plt
import re                   # regular expression
import time                 # time code execution

import dg2df                # for DLSH dynamic group (behavioral data)
import neo                  # data structure for neural data
import quantities as pq
import signal_align         # in this package: align neural data according to task
import PyNeuroAna as pna    # in this package: analysis
import PyNeuroPlot as pnp   # in this package: plot
import df_ana
import misc_tools           # in this package: misc

import data_load_DLSH       # package specific for DLSH lab data

from scipy import signal
from scipy.signal import spectral
from PyNeuroPlot import center2edge

dir_tdt_tank = '/shared/lab/projects/encounter/data/TDT'
dir_dg = '/shared/lab/projects/analysis/shaobo/data_dg'

[blk, data_df, name_tdt_blocks] = data_load_DLSH.load_data(
    '.*MT', '.*Thor.*U16.*180224.*',
    dir_tdt_tank=dir_tdt_tank, dir_dg=dir_dg,
    tf_interactive=True)

""" some settings for saving figures  """
filename_common = misc_tools.str_common(name_tdt_blocks)
dir_temp_fig = './temp_figs'

""" make sure data field exists """
data_df = data_load_DLSH.standardize_data_df(data_df, filename_common)
blk     = data_load_DLSH.standardize_blk(blk)

""" Get StimOn time stamps in neo time frame """
ts_StimOn = data_load_DLSH.get_ts_align(blk, data_df, dg_tos_align='stimon')

""" sort and plot """
window_offset = [-0.05, 0.500]
data_neuro=signal_align.blk_align_to_evt(blk, ts_StimOn, window_offset,
                                         type_filter='spiketrains.*', name_filter='.*Code[1-9]$',
                                         spike_bin_rate=1000, chan_filter=range(1,32+1))

# srv
grpby = 'stim_sname'
df_group = df_ana.DfGroupby(data_df, groupby=grpby, tf_aggregate=False)
for i_signal in range(len(data_neuro['signal_info'])):
    signal_name = data_neuro['signal_info'][i_signal]['name']
    h_fig, h_axes = pnp.CreateSubplotFromGroupby(df_group['order'], tf_title=False)
    plt.gcf().set_size_inches([10, 8])
    tf_legend = True
    for cdtn in df_group['idx']:
        plt.axes(h_axes[cdtn])
        pnp.PsthPlot(data_neuro['data'][:, :, i_signal], ts=data_neuro['ts'],
                     cdtn=data_df['mask_opacity_int'], limit=df_group['idx'][cdtn], sk_std=0.005,
                     tf_legend=tf_legend)
        tf_legend = False
        plt.title(cdtn, fontsize='small')
    plt.suptitle('{} {}, by {}'.format(filename_common, signal_name, grpby))
    plt.savefig('./temp_figs/{}_{}.png'.format(filename_common, signal_name))
    plt.close()

# MT mapping
num_signals = len(data_neuro['signal_info'])
h_fig, h_axes = pnp.SubplotsAutoRowCol(num_signals, figsize=(10, 8))
for i_signal in range(num_signals):
    plt.axes(h_axes[i_signal])
    signal_name = data_neuro['signal_info'][i_signal]['name']
    pnp.PsthPlot(data_neuro['data'][:, :, i_signal], ts=data_neuro['ts'],
                 cdtn=data_df['rotationDirections'], limit=None, sk_std=0.015,
                 tf_legend=tf_legend, color_style='continuous')
    plt.title(signal_name)
plt.savefig('./temp_figs/direction_tuning_{}.png'.format(filename_common))

# RF spot mapping
window_offset = [0.0, 0.2]
data_neuro=signal_align.blk_align_to_evt(blk, ts_StimOn, window_offset,
                                         type_filter='spiketrains.*', name_filter='.*Code[1-9]$',
                                         spike_bin_rate=1000, chan_filter=range(1,32+1))
data_neuro=signal_align.neuro_sort(data_df, ['stim_pos_x','stim_pos_y'], [], data_neuro)
num_signals = len(data_neuro['signal_info'])
h_fig, h_axes = pnp.SubplotsAutoRowCol(num_signals, figsize=[8,8])
for i_signal in range(num_signals):
    plt.axes(h_axes[i_signal])
    pnp.RfPlot(data_neuro, sk_std=0.01, indx_sgnl=i_signal)
    plt.axis('equal')
    plt.axis('square')
plt.savefig('./temp_figs/RF_mapping_{}.png'.format(filename_common))

""" spike waveforms """
pnp.SpkWfPlot(blk.segments[0], sortcode_min=1)
plt.savefig('{}/{}_spk_waveform.png'.format(dir_temp_fig, filename_common))

""" ERP plot """
t_plot = [-0.100, 0.500]

data_neuro=signal_align.blk_align_to_evt(blk, ts_StimOn, t_plot, type_filter='ana.*', name_filter='LFPs.*')
ERP = np.mean(data_neuro['data'], axis=0).transpose()
pnp.ErpPlot(ERP, data_neuro['ts'])
plt.savefig('{}/{}_ERP_all.png'.format(dir_temp_fig, filename_common))

""" ERP by recording depth from diffent files """

[blk, data_df, name_tdt_blocks] = data_load_DLSH.load_data(
    '.*srv', '.*Thor.*S4.*180227.*',
    dir_tdt_tank=dir_tdt_tank, dir_dg=dir_dg,
    tf_interactive=True)

file_depth = {2: 10100, 3: 11400, 4: 12300,
              5: 13900, 6: 14400,
              7: 16300, 8: 16800, 9: 17000, 10: 17600, 13: 18150, 14: 18400}

# signal = 'spk'
signal = 'LFP'

data_df['depth'] = [file_depth[file] for file in data_df['file']]

filename_common = misc_tools.str_common(name_tdt_blocks)
dir_temp_fig = './temp_figs'

data_df = data_load_DLSH.standardize_data_df(data_df, filename_common)
blk     = data_load_DLSH.standardize_blk(blk)

ts_StimOn = data_load_DLSH.get_ts_align(blk, data_df, dg_tos_align='stimon')

window_offset = [-0.05, 0.500]
if signal == 'LFP':
    data_neuro=signal_align.blk_align_to_evt(blk, ts_StimOn, window_offset,
                                             type_filter='ana.*', name_filter='LFP.*',
                                             spike_bin_rate=1000, chan_filter=[1])
elif signal == 'spk':
    data_neuro=signal_align.blk_align_to_evt(blk, ts_StimOn, window_offset,
                                             type_filter='spiketrains*', name_filter='.*Code[1-9]$',
                                             spike_bin_rate=1000, chan_filter=[1])

# combine different sortcodes
data_neuro['data'][:,:,0] = np.sum(data_neuro['data'], axis=2)

pnp.PsthPlot(data_neuro['data'][:, :, 0], ts=data_neuro['ts'],
             cdtn=data_df['depth'], limit=None, sk_std=0.010,
             tf_legend=True, color_style='continuous')
plt.title('response by depth, {}'.format(filename_common))

# plot traces by depth
data_neuro = signal_align.neuro_sort(data_df, grpby='depth', neuro=data_neuro)
ERPs_by_depth = pna.GroupAve(data_neuro)

colors = pnp.gen_distinct_colors(len(ERPs_by_depth), style='continuous')
if signal == 'LFP':
    ERPs_by_depth = ERPs_by_depth*10**6
    scale = 100  # 10 uV/mm in axis
    scale_unit = 'mV/mm'
elif signal == 'spk':
    ERPs_by_depth = pna.SmoothTrace(ERPs_by_depth, sk_std=0.005, ts=data_neuro['ts'])
    scale = 100  # 10 uV/mm in axis
    scale_unit = 'spk/sec /mm'

plt.figure(figsize=[6,8])
for i, cdtn in enumerate(data_neuro['cdtn']):
    plt.plot(data_neuro['ts'],  ERPs_by_depth[i,:,0]/scale - cdtn/1000.0, color=colors[i])
    plt.plot(data_neuro['ts'][0], -cdtn/1000.0, 'o', color=colors[i])
plt.xlabel('time form stimulus onset, in sec')
plt.ylabel('depth in mm, {} {}'.format(scale, scale_unit))
plt.title('ERP by depth, {}'.format(filename_common))
plt.savefig('./temp_figs/ERP_by_depth_{}.png'.format(filename_common))

""" below is legacy code """

""" PSTH plot by condition """
# align
window_offset = [-0.100, 0.6]
data_neuro=signal_align.blk_align_to_evt(blk, ts_StimOn, window_offset, type_filter='spiketrains.*', name_filter='.*Code[1-9]$', spike_bin_rate=1000, chan_filter=range(1,32+1))

window_offset = [-0.100, 0.6]
""" GM32 spike by condition  """
# align
data_neuro=signal_align.blk_align_to_evt(blk, ts_StimOn, window_offset, type_filter='spiketrains.*', name_filter='.*Code[1-9]$', spike_bin_rate=1000, chan_filter=range(1,32+1))
# group
data_neuro=signal_align.neuro_sort(data_df, ['stim_familiarized','mask_opacity_int'], [], data_neuro)
# plot
pnp.NeuroPlot(data_neuro, sk_std=0.010, tf_legend=True, tf_seperate_window=False)
plt.suptitle('spk_GM32    {}'.format(filename_common), fontsize=20)
plt.savefig('{}/{}_spk.png'.format(dir_temp_fig, filename_common))

"""" psth plot """
pnp.PsthPlotCdtn(data_neuro, data_df, i_signal=0, grpby=['stim_sname'], sk_std=0.01)

pnp.PsthPlot(data_neuro['data'][:,:,0], ts=data_neuro['ts'],
                 cdtn=data_df['mask_opacity_int'], sk_std=0.005)

import df_ana; import importlib; importlib.reload(df_ana); importlib.reload(misc_tools); df_group = df_ana.DfGroupby(data_df, 'stim_categories', limit=range(100,200), tf_aggregate=True, tf_linearize=False)
importlib.reload(pnp); pnp.CreateSubplotFromGroupby(df_group['order'])


"""
venvs creates virtualenvs.

By default it places them in the appropriate data directory for your platform
(See `appdirs <https://pypi.python.org/pypi/appdirs>`_), but it will also
respect the :envvar:`WORKON_HOME` environment variable for compatibility with
:command:`mkvirtualenv`.
"""

from functools import partial

from filesystems import Path
from packaging.requirements import Requirement
import click

from venvs import _config
from venvs.common import _FILESYSTEM, _LINK_DIR, _ROOT

_INSTALL = click.option(
    "-i",
    "--install",
    "installs",
    multiple=True,
    help=(
        "install the given specifier (package) into the "
        "virtualenv with pip after it is created"
    ),
)
_REQUIREMENTS = click.option(
    "-r",
    "--requirement",
    "requirements",
    multiple=True,
    help=(
        "install the given requirements file into the "
        "virtualenv with pip after it is created"
    ),
)

@_FILESYSTEM
@_LINK_DIR
@_ROOT
@_INSTALL
@_REQUIREMENTS
@click.option(
    "-l",
    "--link",
    "links",
    multiple=True,
    help=(
        "After installing any specified packages, link the specified "
        "binaries into the directory they would have been installed into "
        "globally."
    ),
)
@click.option(
    "-R",
    "--recreate",
    flag_value=True,
    help="recreate the virtualenv if it already exists",
)
@click.option(
    "--persist/--no-persist",
    "-p",
    is_flag=True,
    default=False,
    help="Add to config file when installing.",
)
@click.argument("name", required=False)
@click.argument("virtualenv_args", nargs=-1, type=click.UNPROCESSED)
def main(
    filesystem,
    link_dir,
    name,
    locator,
    installs,
    links,
    requirements,
    recreate,
    virtualenv_args,
    persist,
):
    """
    Create a new ad hoc virtualenv.
    """
    if name:
        virtualenv = locator.for_name(name=name)
    elif len(installs) == 1:
        # When there's just one package to install, default to using that name.
        (requirement,) = installs
        name = Requirement(requirement).name
        virtualenv = locator.for_name(name=name)
    elif installs:
        raise click.BadParameter("A name is required.")
    elif len(links) == 1:
        # When there's just one binary to link, go for the gold.
        (name,) = installs = links
        virtualenv = locator.for_name(name=name)
    else:
        virtualenv = locator.for_directory(directory=Path.cwd())

    if recreate:
        act = partial(virtualenv.recreate_on, filesystem=filesystem)
    else:
        act = virtualenv.create

    act(arguments=virtualenv_args)
    virtualenv.install(packages=installs, requirements=requirements)

    for link in links:
        filesystem.link(
            source=virtualenv.binary(name=link),
            to=link_dir.descendant(link),
        )

    if persist:
        _config.add_virtualenv(
            filesystem=filesystem,
            locator=locator,
            installs=installs,
            links=links,
            name=name,
        )


from pyspark.sql import DataFrame, SparkSession

from batch_jobs.util.args_parser import DatePartition

def extract_csv_from_s3(spark: SparkSession, bucket: str, path: str) -> DataFrame:
    path = f"s3a://{bucket}/{path}"

    return spark.read.option("header", True).csv(path)

def extract_parquet_from_s3(
        spark: SparkSession,
        bucket: str,
        path: str,
        partition: DatePartition,
) -> DataFrame:
    path = f"s3a://{bucket}/{path}/{partition}/"

    return spark.read.parquet(path)


import torch

class Corpus():
    """ Transform words to index then to tensors."""
    def __init__(self, path):
        self.encoding = Encoding()
        self.train = self.process(path + 'train.txt')
        self.val = self.process(path + 'valid.txt')
        self.test = self.process(path + 'test.txt')

    def process(self, path):
        with open(path, 'r') as f:
            all = []
            for line in f:
                words = line.split() + ['<eos>']
                ids = []
                for w in words:
                    ids.append(self.encoding.encode(w))
                all.append(torch.tensor(ids).type(torch.int64))
            res = torch.cat(all)

        return res

class Encoding():
    """ Encode word to index"""
    def __init__(self):
        self.word2index = {}
        self.index2word = []

    def encode(self, word):
        if word not in self.word2index:
            self.index2word.append(word)
            self.word2index[word] = len(self.index2word) - 1

        return self.word2index[word]


"""
the sun rgb d depth images are converted to point cloud and then further converted to
DHS images. We have the following components
- DHS images
- 2D bboxes:
the 2D bbox is saved in 009290_gt_unnormalized_xmin_y_min_w_hs_sunrgbd80.txt, it has the pixel value of top left x and y, also the
width and height information.
such as
```bash
1.000000000000000000e+00 1.940000000000000000e+02 1.240000000000000000e+02 2.470000000000000000e+02
1.000000000000000000e+00 3.130000000000000000e+02 1.390000000000000000e+02 1.280000000000000000e+02
2.840000000000000000e+02 4.030000000000000000e+02 3.300000000000000000e+01 3.800000000000000000e+01
```
- 2D lables
We have 80 categories and those labels are saved in such as "009290_gt_class_ids_sunrgbd80.txt" file.
```bash
2.800000000000000000e+01
1.700000000000000000e+01
5.700000000000000000e+01
```
Some frame works need to use the 2D masks, since our system does not need 2D mask as an output, we will use dummy mask to train the model (set the mask branch loss weight as 0).
"""
import os, glob, json
import mmcv
import numpy as np

info = {
    "description": "SUN RGBD coco styple DHS images",
    "url": "",
    "version": "1.0",
    "year": 2022,
    "contributor": "Sun RGBD dataset creators, computer vision lab, Hunter College, CUNY",
    "date_created": "2022/01/01",
}

sunrgbd80_classsnames_ids_list = [
    ["person", 1],
    ["table", 2],
    ["desk", 3],
    ["sofa_chair", 4],
    ["pillow", 5],
    ["box", 6],
    ["garbage_bin", 7],
    ["cabinet", 8],
    ["drawer", 9],
    ["shelf", 10],
    ["kitchen_counter", 11],
    ["kitchen_cabinet", 12],
    ["cpu", 13],
    ["bench", 14],
    ["file_cabinet", 15],
    ["whiteboard", 16],
    ["lamp", 17],
    ["endtable", 18],
    ["bookshelf", 19],
    ["coffee_table", 20],
    ["dresser", 21],
    ["paper", 22],
    ["printer", 23],
    ["monitor", 24],
    ["back_pack", 25],
    ["night_stand", 26],
    ["door", 27],
    ["picture", 28],
    ["ottoman", 29],
    ["stool", 30],
    ["outlet", 31],
    ["towel", 32],
    ["tray", 33],
    ["bag", 34],
    ["stove", 35],
    ["bathtub", 36],
    ["scanner", 37],
    ["cubby", 38],
    ["mirror", 39],
    ["bottle", 40],
    ["rack", 41],
    ["cup", 42],
    ["thermos", 43],
    ["island", 44],
    ["counter", 45],
    ["bowl", 46],
    ["plate", 47],
    ["organizer", 48],
    ["switch", 49],
    ["pen", 50],
    ["coffee_maker", 51],
    ["cart", 52],
    ["tv_stand", 53],
    ["poster", 54],
    ["soap_dispenser", 55],
    ["toy", 56],
    ["chair", 57],
    ["sofa", 58],
    ["plant", 59],
    ["bed", 60],
    ["dining_table", 61],
    ["toilet", 62],
    ["tv", 63],
    ["laptop", 64],
    ["mouse", 65],
    ["basket", 66],
    ["keyboard", 67],
    ["telephone", 68],
    ["microwave", 69],
    ["oven", 70],
    ["paper_towel_dispenser", 71],
    ["sink", 72],
    ["fridge", 73],
    ["book", 74],
    ["clock", 75],
    ["vase", 76],
    ["fire_extinguisher", 77],
    ["blinds", 78],
    ["podium", 79],
    ["others", 80],
]

def get_categories_info():
    """
    "categories": [
        {"supercategory": "person","id": 1,"name": "person"},
        {"supercategory": "vehicle","id": 2,"name": "bicycle"},
        {"supercategory": "vehicle","id": 3,"name": "car"},
        {"supercategory": "vehicle","id": 4,"name": "motorcycle"},
        {"supercategory": "vehicle","id": 5,"name": "airplane"},
        ...
        {"supercategory": "indoor","id": 89,"name": "hair drier"},
        {"supercategory": "indoor","id": 90,"name": "toothbrush"}
    ]
    """
    categories = [
        {"supercategory": "sunrgbd", "id": idx, "name": cat}
        for cat, idx in sunrgbd80_classsnames_ids_list
    ]
    print(categories)
    return categories

def get_images_info(img_files):
    """
    The image file has the format of "007663_dhs.png". For the coco style
    [
     {
        "license": 4, # we don't need this one
        "file_name": "000000397133.jpg",
        "coco_url": "http://images.cocodataset.org/val2017/000000397133.jpg",
        "height": 427,
        "width": 640,
        "date_captured": "2013-11-14 17:02:52",
        "flickr_url": "http://farm7.staticflickr.com/6116/6255196340_da26cf2c9e_z.jpg",
        "id": 397133
     },
     ...
    ]
    """
    assert len(img_files) > 0, "Image files are empty"

    def extract_info_(img_fn):
        file_name = img_fn.split("/")[-1]
        img_id = int(file_name.split("_")[0])
        image = mmcv.imread(img_fn)
        height, width = image.shape[:2]
        # print("image height, width", height, width)
        return {"file_name": file_name, "height": height, "width": width, "id": img_id}

    ret = [extract_info_(img_fn) for img_fn in img_files]
    return ret

def get_annotations_info(img_files, label_folder):
    """
    the coco style annotation has the following format. The annotation contains all the
    objects from the images. The id is the annotation id. We set it as image_id * 100 +
    the object index within this image. Segmentation will use the same as the bbox to
    generate a FAKE image segmentation. In the coco style, segmentation list of vertices
      (x, y pixel positions). COCO bounding box format is
      [top left x position, top left y position, width, height].
    [
     {
        "segmentation": [[510.66,423.01,511.72,420.03,...,510.45,423.01]],
        "area": 702.1057499999998,
        "iscrowd": 0,
        "image_id": 289343,
        "bbox": [473.07,395.93,38.65,28.67],
        "category_id": 18,
        "id": 1768
     },
     ...
    ]
    """
    assert len(img_files) > 0, "Image files are empty"

    def extract_label_info_(img_fn):
        file_name = img_fn.split("/")[-1]
        img_id = int(file_name.split("_")[0])
        bbox_fn = (
            label_folder
            + "sunrgbd80_bbox/"
            + str(img_id).zfill(6)
            + "_gt_unnormalized_xmin_y_min_w_hs_sunrgbd80.npy"
        )
        label_fn = (
            label_folder
            + "sunrgbd80_bbox/"
            + str(img_id).zfill(6)
            + "_gt_class_ids_sunrgbd80.npy"
        )
        bboxes, labels = np.load(bbox_fn), np.load(label_fn)
        if bboxes.size == 0:
            return []
        bboxes = bboxes.tolist()
        ret = []
        for i in range(len(bboxes)):
            bbox = bboxes[i]
            category_id = int(labels[i])
            # add point x1 y1 x2 y2 x1 y1 to avoid the problem mentioned here
            # https://github.com/cocodataset/cocoapi/issues/139
            segmentation = [bbox + bbox[:2]]
            area = bbox[2] * bbox[3]
            anno_id = img_id * 100 + i
            ret.append(
                {
                    "segmentation": segmentation,
                    "area": area,
                    "iscrowd": 0,
                    "image_id": img_id,
                    "bbox": bbox,
                    "category_id": category_id,
                    "id": anno_id,
                }
            )
        return ret

    ret = []
    for fn in img_files:
        ret += extract_label_info_(fn)
    return ret

def generate_annotation(img_folder, label_folder, annotation_filename):
    """
    COCO annotation json file has the following keys
    dict_keys(['info', 'licenses', 'images', 'annotations', 'categories'])
    we only need generate "images" and "annotations"
    The creation follows this article
    https://www.immersivelimit.com/tutorials/create-coco-annotations-from-scratch
    """
    img_files = sorted(glob.glob(img_folder + "*.png"))
    print(f"len of img_files {len(img_files)}")
    images_info = get_images_info(img_files)
    annotations_info = get_annotations_info(img_files, label_folder)
    categories_info = get_categories_info()
    final_annotations = {
        "info": info,
        "licenses": "none",
        "images": images_info,
        "annotations": annotations_info,
        "categories": categories_info,
    }
    fn = label_folder + annotation_filename
    with open(fn, "w") as f:
        json.dump(final_annotations, f)

def convert_data_to_coco_style(dataset_folder, img_type="rgb"):
    """
    Convert our SUN RGBD dataset to coco style
    """
    # For train
    img_folder = dataset_folder + "train/" + img_type + "/"
    label_folder = dataset_folder + "train/gts/raw_gts/"
    generate_annotation(img_folder, label_folder, "det_train"+img_type + ".json")
    # For test
    img_folder = dataset_folder + "val/"+ img_type + "/"
    label_folder = dataset_folder + "val/gts/raw_gts/"
    generate_annotation(img_folder, label_folder, "det_val"+img_type + ".json")

if __name__ == "__main__":
    sunrgbd_folder = "/data/sophia/a/Xiaoke.Shen54/DATASET/sunrgbd_DO_NOT_DELETE/"
    convert_data_to_coco_style(sunrgbd_folder, "rgb")