#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import pandas as pd
import numpy as np
from sklearn.discriminant_analysis import QuadraticDiscriminantAnalysis as QDA

training_data = pd.read_csv("training-part-2.csv")
test_data = pd.read_csv("test-part-2.csv")

class NB:
    def hot_encoding(self, y):
        for i in range(len(y)):
            if y[i] == "smile":
                y[i] = 1
            else:
                y[i] = 0
        return y

    def fit(self, x, y, K):
        n, d = x.shape #number of data elements/rows
        self.K = K #number of classes
        self.props = np.zeros([self.K,d])
        self.classes = np.zeros([self.K])
        y = self.hot_encoding(y)
        for k in range(self.K):
            X_k = x[y == k]
            self.props[k] = np.mean(X_k, axis = 0)
            self.classes[k] = X_k.shape[0]/float(n)

    def predict(self, x):
        n, d = x.shape
        x = np.reshape(x, (1, n, d))
        self.props = np.reshape(self.props, (self.K, 1, d))
        #prevent underflow
        self.props = self.props.clip(1e-12, 1-1e-12)
        #compute probabilities
        log_py = np.log(np.tile(self.classes.reshape((self.K, 1)), (1,n)).reshape([self.K, n, 1]))
        log_pxy = x * np.log(self.props) + (1-x) * np.log(1-self.props)
        log_pyx = (log_pxy + log_py).sum(axis=2)

        return log_pyx.argmax(axis=0).flatten()

X_train = training_data.iloc[:, 0:17].values
y_train = training_data.iloc[:, 17].values

X_test = test_data.iloc[:, 0:17].values
y_test = test_data.iloc[:, 17].values

#nb = NB()
#nb.fit(X_train, y_train, 2) #Fit the training data
#pred_test = nb.predict(X_train) #Performing Prediction

clf = QDA()
clf.fit(X_train, y_train)
pred = clf.predict(X_test)
print(pred)

'''
for i in range(len(y_train)):
    if y_train[i] == 0:
        y_train[i] = "frown"
    else:
        y_train[i] = "smile"

#Converting predicted output in the form of class values (0/1 to frown/smile)
pred_test_var = []
for i in range(len(pred_test)):
    if pred_test[i] == 0:
        pred_test_var.append("frown")
    else:
        pred_test_var.append("smile")

pred_df = pd.DataFrame()
pred_df["Predicted"] = pred_test_var
pred_df["Actual"] = y_train

print(pred_df)

y_test = nb.hot_encoding(y_train)
'''
pred_sum = 0
for i in range(len(y_test)):
    if y_test[i] == pred[i]:
        pred_sum += 1

err_percent = 1 - (pred_sum/len(y_test))
print("Error Rate:", err_percent*100)


#!/bin/python
# python2.7
# Train and evaluate (audio-visual) model for the prediction of arousal / valence / liking
#
# The performance on the development set in terms of CCC, PCE, and MSE is appended to corresponding text files (results.txt, results_pcc.txt, results_mse.txt).
# The predicitions on the test set are written into the folder specified by the variable 'path_test_predictions'.
#
# Arguments (all optional):
#  argv[1]: Delay (in seconds, shift features to the back to compensate delay of annotations)
#  argv[2] argv[3] argv[4]: Each of these arguments is either 0 or 1 and determines if audio, video, and/or text features are taken into account
#  Default is: 0.0 1 1 1
#
# modified from run_baseline.py (Contact: maximilian.schmitt@uni-passau.de)

import os
import fnmatch
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable
from sys     import argv
from sklearn import svm

from load_features     import load_all
from calc_scores       import calc_scores
from write_predictions import write_predictions

from os.path import join as pjoin
from makeXs import makeX
from plot_models import *

from datetime import datetime

start = datetime.now()
# ================= Load features =================

# Set folders here
path_test_predictions = "test_predictions/"
# If the test labels are not available, the predictions on
# test are written into the folder 'path_test_predictions'
b_test_available      = False
data_dir = "../data/AVEC_17_Emotion_Sub-Challenge"

hidden_size = 10 #4000
h2_size = 10 #50
batch_size = 1
num_epochs = 2
rnn_type = nn.GRU
nonlinearity = F.relu
num_layers = 1
learning_rate = 0.001
regularization = 0
seed=123

torch.manual_seed(seed)

rnn_parameter_dict = {'hidden_size': hidden_size, 'h2_size': h2_size, 'batch_size':batch_size, 'num_epochs':num_epochs,
                        'rnn_type':rnn_type, 'nonlinearity':nonlinearity, 'num_layers':num_layers, 'learning_rate':learning_rate,
                        'regularization':regularization, 'seed':seed}

# # random input
# X_np = np.random.rand(1756, 1, 8962)

class DataLoader():
    def __init__(self, data_dir, split="train", length_of_timestep=100,
                 useAudio=True, useVideo=True, useText=True):

        self.labelDict = {'arousal': 1, 'valence': 2, 'liking': 3}
        self.Y_np, self.X_np = makeX(data_dir=data_dir, split=split,
                                     length_of_timestep=length_of_timestep,
                                     useAudio=useAudio, useVideo=useVideo,
                                     useText=useText)

    def read_data(self, labelType):
        # label_num = 1, 2 or 3.
        assert (labelType in self.labelDict)

        label_num = self.labelDict[labelType]

        x_variables = []
        y_variables = []

        for i in range(len(self.X_np)):
            X_np = self.X_np[i][:, 1:]
            Y_np = self.Y_np[i][:, label_num]

            X_np = X_np.reshape(X_np.shape[0], 1, X_np.shape[1])
            Y_np = Y_np.reshape(Y_np.shape[0], 1, 1)

            num_features = X_np.shape[2]

            X_tensor = torch.from_numpy(X_np).float()
            X = Variable(X_tensor)
            x_variables.append(X)

            # Y_np = np.random.rand(1756, 1, 1) # do later
            Y_tensor = torch.from_numpy(Y_np).float()
            Y = Variable(Y_tensor)
            y_variables.append(Y)

        return x_variables, y_variables, num_features

# real input
trainLoader = DataLoader(data_dir=data_dir, useAudio=True,
    useVideo=False, useText=False)
X, Y, num_features = trainLoader.read_data('arousal')

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.rnn1 = rnn_type(input_size=num_features,
                           hidden_size=hidden_size,
                           num_layers=num_layers)
        self.W1 = nn.Linear(hidden_size, h2_size)
        self.W2 = nn.Linear(h2_size, 1)

    def forward(self, x, hidden):
        x, hidden = self.rnn1(x, hidden)

        h1 = x.view(-1, hidden_size)
        h2 = nonlinearity(self.W1(h1))

        y = self.W2(h2)

        return y, hidden

    def init_hidden(self, batch_size=batch_size):
        weight = next(self.parameters()).data
        return Variable(weight.new(num_layers*1, batch_size, hidden_size).zero_())
        # return Variable(torch.from_numpy(np.random.rand(1,1,hidden_size)))

labelTypes = ["arousal", "valence", "liking"]
models = {labelType: Net() for labelType in labelTypes}

criterion = nn.MSELoss()

# ================= Run our model =================

#...
def train(labelType):
    X_batches, Y_batches, num_features = trainLoader.read_data(labelType)

    model = models[labelType]
    optimizer = torch.optim.Adam(model.parameters(),
                                 lr = learning_rate,
                                 weight_decay=regularization)
    model.train()
    hidden = model.init_hidden()

    all_losses = []

    for epoch in range(num_epochs):
        for batch_index in range(len(X_batches)):
            X = X_batches[batch_index]
            Y = Y_batches[batch_index]
            model.zero_grad()
            output, hidden = model.forward(X, hidden)
            loss = criterion(output, Y)
            print ('Epoch [%d/%d], Batch [%d], Loss: %.4f'
                       %(epoch+1, num_epochs, batch_index, loss.data[0]))
            all_losses.append([epoch, batch_index, loss.data[0]])
            loss.backward(retain_variables=True)
            optimizer.step()
    print(all_losses)
    plot_loss(loss_array = all_losses, labelType = labelType, rnn_parameter_dict = rnn_parameter_dict)

for labelType in labelTypes:
    train(labelType)

# try this?:
# https://discuss.pytorch.org/t/rnn-for-sequence-prediction/182/15

testLoader = DataLoader(data_dir=data_dir, split="devel",
                        useAudio=True, useVideo=False, useText=False)

def test(labelType):
    X_batches, Y_batches, num_features = testLoader.read_data(labelType)

    model = models[labelType]

    output_predictions = []
    for batch_index in range(len(X_batches)):
        hidden = model.init_hidden()
        output, hidden = model.forward(X_batches[batch_index], hidden)
        output_predictions.append(output.data.numpy())

    predicted_labels = np.concatenate(output_predictions, 0)
    true_labels = np.concatenate([Y.data.numpy() for Y in Y_batches], 0)

    plot_test(predicted_labels, true_labels, labelType=labelType, rnn_parameter_dict= rnn_parameter_dict)

    return calc_scores(predicted_labels, true_labels)

# arousal scores
scores_devel_A = np.array([test("arousal")])
# valence scores
scores_devel_V = np.array([test("valence")])
# liking scores
scores_devel_L = np.array([test("liking")])

end_html()

## what follows is unchanged from baseline

ind_opt_A = np.argmax(scores_devel_A[:,0])
ind_opt_V = np.argmax(scores_devel_V[:,0])
ind_opt_L = np.argmax(scores_devel_L[:,0])

#  ================= Print scores  =================
# (CCC, PCC, RMSE) on the development set for our model

print("Arousal devel (CCC,PCC,RMSE):")
print(scores_devel_A[ind_opt_A,:])
print("Valence devel (CCC,PCC,RMSE):")
print(scores_devel_V[ind_opt_V,:])
print("Liking  devel (CCC,PCC,RMSE):")
print(scores_devel_L[ind_opt_L,:])

if b_test_available:
    result_ccc  = [ scores_devel_A[ind_opt_A,0], score_test_A[0], scores_devel_V[ind_opt_V,0], score_test_V[0], scores_devel_L[ind_opt_L,0], score_test_L[0] ]
    result_pcc  = [ scores_devel_A[ind_opt_A,1], score_test_A[1], scores_devel_V[ind_opt_V,1], score_test_V[1], scores_devel_L[ind_opt_L,1], score_test_L[1] ]
    result_rmse = [ scores_devel_A[ind_opt_A,2], score_test_A[2], scores_devel_V[ind_opt_V,2], score_test_V[2], scores_devel_L[ind_opt_L,2], score_test_L[2] ]
    print("Arousal test (CCC,PCC,RMSE):")
    print(score_test_A)
    print("Valence test (CCC,PCC,RMSE):")
    print(score_test_V)
    print("Liking  test (CCC,PCC,RMSE):")
    print(score_test_L)
else:
    # Write only the scores for the development set
    result_ccc  = [ scores_devel_A[ind_opt_A,0], scores_devel_V[ind_opt_V,0], scores_devel_L[ind_opt_L,0] ]
    result_pcc  = [ scores_devel_A[ind_opt_A,1], scores_devel_V[ind_opt_V,1], scores_devel_L[ind_opt_L,1] ]
    result_rmse = [ scores_devel_A[ind_opt_A,2], scores_devel_V[ind_opt_V,2], scores_devel_L[ind_opt_L,2] ]

# Write scores into text files
with open("results_ccc.txt", 'a') as myfile:
    myfile.write("Arousal Valence Liking\n")
    myfile.write(str(result_ccc) + '\n')
with open("results_pcc.txt", 'a') as myfile:
    myfile.write("Arousal Valence Liking\n")
    myfile.write(str(result_pcc) + '\n')
with open("results_rmse.txt", 'a') as myfile:
    myfile.write("Arousal Valence Liking\n")
    myfile.write(str(result_rmse) + '\n')

print("%d seconds" %(datetime.now() - start).seconds)


from mrjob.job import MRJob
import csv
import math

from mrjob.step import MRStep

dictionary = []
all_label = ['content', 'invalid', 'other', 'action', 'engineering']
pc_sum = 0

class Classification(MRJob):
    def mapper1(self, key, line):
        index, title, true_label, set_type = line.split(',')
        if set_type == 'test':
            title = title.split(' ')
            pxc_count = 0
            for id in range(len(dictionary)):
                if dictionary[id][0] == 'WORDCOUNT':
                    pxc_count = pxc_count + int(dictionary[id][2])
            for guess_label in all_label:
                pc, pxc_all, pxc1 = 0, 0, 0
                for id in range(len(dictionary)):
                    if dictionary[id][0] == guess_label.upper():
                        pc = int(dictionary[id][2]) / pc_sum
                        break
                for id in range(len(dictionary)):
                    if dictionary[id][0] == 'ALL' and dictionary[id][1] == guess_label:
                        pxc_all = int(dictionary[id][2])
                        break
                pcx = math.log(pc)
                for word in title:
                    for id in range(len(dictionary)):
                        if dictionary[id][0] == word and dictionary[id][1] == guess_label:
                            pxc1 = int(dictionary[id][2])
                            break
                    pcx = pcx + math.log((pxc1 + 1) / (pxc_all + pxc_count))
                yield (index, true_label), (pcx, guess_label)

    def combiner1(self, tag, counts):
        yield tag, max(counts)

    def reducer1(self, tag, counts):
        yield tag, max(counts)

    def mapper2(self, tag, counts):
        index, true_label = tag
        _, guess_label = counts
        if true_label == guess_label:
            yield (true_label, 'correct'), 1
        yield (true_label, 'all'), 1

    def combiner2(self, tag, counts):
        yield tag, sum(counts)

    def reducer2(self, tag, counts):
        yield tag, sum(counts)

    def steps(self):
        return [
            MRStep(mapper=self.mapper1,
                   combiner=self.combiner1,
                   reducer=self.reducer1),
            MRStep(mapper=self.mapper2,
                   combiner=self.combiner2,
                   reducer=self.reducer2)
        ]

if __name__ == '__main__':
    # open the CSV file in read mode
    with open('result.csv', 'r', encoding="utf-16le") as file:
        # create a CSV reader object
        reader = csv.reader(file, delimiter='\t')
        # iterate over the rows of the file
        for row in reader:
            # row[0] contains the list, row[1] contains the number
            data_list_string = row[0]
            data_number = row[1]
            # remove the square brackets and quotes from the list string
            data_list = data_list_string.strip('[]').replace('"', '').replace(' ', '').replace('[', '').replace(
                '\ufeff', '').split(',')
            # assign the variables
            var_1 = data_list[0]
            var_2 = data_list[1]
            var_3 = data_number
            temp = [var_1, var_2, var_3]
            dictionary.append(temp)

    for i in range(len(dictionary)):
        if dictionary[i][1].upper() == dictionary[i][0]:
            pc_sum = pc_sum + int(dictionary[i][2])

    Classification.run()


def binary_search(arr, x):
    low = 0
    high = len(arr) - 1
    mid = 0
    if x not in arr:
        return -1
    if x == arr[low]:
        return low
    elif x == arr[high]:
        return high
    else:
        while low <= high:
            mid = (high + low) // 2
            # jika x lebih besar, abaikan sebelah kiri
            if arr[mid] < x:
                low = mid + 1
            # jika x lebih keci;, abaikan sebelah kanan
            elif arr[mid] > x:
                high = mid + 1
            # berarti x ada di tengah
            else:
                return mid
        return -1

arr = [2,3,4,10,40]
x = 19

result = binary_search(arr, x)

if result != -1:
    print(f'Elemen ada di indeks {result}')
else:
    print('Elemen tidak ada dalam array')


RATIOPIXEL_CM = 40

class AlignementIle():
    def __init__(self):
        self.terminer = False
        self.ajustements = []

    def calculerAjustement(self, distance_x, distance_y):

        if (abs(distance_x) > RATIOPIXEL_CM):
            ajustements_x = self.ajusterPositionX(distance_x)
            self.ajustements.append(ajustements_x)
        if (abs(distance_y) > RATIOPIXEL_CM):
            ajustements_y = self.ajusterPositionY(distance_y)
            self.ajustements.append(ajustements_y)

        return self.ajustements

    def ajusterPositionX(self, distance_x):
        if (distance_x < 0):
            commande = 'left'
        elif (distance_x > 0):
            commande = 'right'

        return commande, abs(distance_x / RATIOPIXEL_CM)

    def ajusterPositionY(self, distance_y):
        if (distance_y < 0):
            commande = 'backward'
        elif (distance_y > 0):
            commande = 'forward'

        return commande, abs(distance_y / RATIOPIXEL_CM)


from math import *
import logging

# add local modules folder
# file_path = os.path.join('..', 'Python_Modules')
# sys.path.append(file_path)

from osgeo import gdal, ogr, osr
# from subprocess import Popen, PIPE

LOGGER = logging.getLogger(__name__)

def spatialOverlap(bboxA, bboxB):
    # get Boundingboxes as Geometries
    boxA = _generateGeometryFromBbox(bboxA)
    boxB = _generateGeometryFromBbox(bboxB)

    areaA = boxA.GetArea()
    areaB = boxB.GetArea()

    if areaA == 0:
        bufferDist = 500
        boxA = boxA.Buffer(bufferDist)
        areaA = boxA.GetArea()

    if areaB == 0:
        bufferDist = 500
        boxB = boxB.Buffer(bufferDist)
        areaB = boxB.GetArea()

    largerArea = areaA if areaA >= areaB else areaB

    print(boxA)
    print(boxB)

    intersection = boxA.Union(boxB)
    intersectGeometry = ogr.CreateGeometryFromWkt(intersection.ExportToWkt())

    intersectArea = intersectGeometry.GetArea()

    print(intersectArea)

    reachedPercentArea = intersectArea/largerArea

    reachedPercentArea = floor(reachedPercentArea * 100)/100
    # print(reachedPercentArea)
    return reachedPercentArea

def similarArea(bboxA, bboxB):
    boxA = _generateGeometryFromBbox(bboxA)
    boxB = _generateGeometryFromBbox(bboxB)

    areaA = boxA.GetArea()
    areaB = boxB.GetArea()

    reachedPercentArea = 0

    if areaA == areaB:
        reachedPercentArea = 1
    else:
        if areaA >= areaB:
            reachedPercentArea = areaB/areaA
        else:
            reachedPercentArea = areaA/areaB

    reachedPercentArea = floor(reachedPercentArea*100)/100
    return reachedPercentArea

def spatialDistance(bboxA, bboxB):
    distBetweenCenterPoints = None
    longerDistance = None
    if (bboxA[0] == bboxA[2]) and (bboxB[0] == bboxB[2]) and (bboxA[1] == bboxA[3]) and (bboxB[1] == bboxB[3]):
        distBetweenCenterPoints = _getDistance((bboxA[0], bboxA[1]), (bboxB[0], bboxB[1]))
        longerDistance = 5

    else:
        if (bboxA[0] == bboxA[2]) and (bboxA[1] == bboxA[3]):
            centerA = ogr.CreateGeometryFromWkt("POINT (%f %f)" % (bboxA[0], bboxA[1]))
        else:
            centerA = _getMidPoint(bboxA)

        if (bboxB[0] == bboxB[2]) and (bboxB[1] == bboxB[3]):
            centerB = ogr.CreateGeometryFromWkt("POINT (%f %f)" % (bboxB[0], bboxB[1]))
        else:
            centerB = _getMidPoint(bboxB)

        type1 = centerA.GetGeometryName()
        type2 = centerB.GetGeometryName()
        # print(type1, type2)

        distA = _getDistance((bboxA[1], bboxA[0]), (bboxA[3], bboxA[2]))
        distB = _getDistance((bboxB[1], bboxB[0]), (bboxB[3], bboxB[2]))

        # print(distA, distB)

        longerDistance = distA if distA >= distB else distB

        # print(longerDistance)

        distBetweenCenterPoints = _getDistance((centerA.GetY(), centerA.GetX()),(centerB.GetY(), centerB.GetX()))
        # print(distBetweenCenterPoints)

    if distBetweenCenterPoints is not None and longerDistance is not None:
        distPercentage = (1 - (distBetweenCenterPoints/longerDistance))
        distPercentage = floor(distPercentage * 100)/100
        # print(distPercentage if distPercentage>0 else 0)
        return distPercentage if distPercentage>0 else 0
    else:
        print("Error while processing")
        return 0

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

def _generateGeometryFromBbox(bbox):

    import pyproj

    source = pyproj.Proj(init='epsg:4326')
    target = pyproj.Proj(init='epsg:25832')
    minx1, miny1 = bbox[0], bbox[1]
    maxx1, maxy1 = bbox[2], bbox[3]
    minx2, miny2 = pyproj.transform(source, target, minx1, miny1)
    maxx2, maxy2 = pyproj.transform(source, target, maxx1, maxy1)

    boxA = ogr.CreateGeometryFromGML("""
    <gml:Polygon xmlns:gml="http://www.opengis.net/gml" srsName="http://www.opengis.net/def/crs/EPSG/0/25832">
        <gml:outerBoundaryIs>
            <gml:LinearRing>
                <gml:coordinates>
                    %(minX)f,%(minY)f %(minX)f,%(maxY)f %(maxX)f,%(maxY)f %(maxX)f,%(minY)f %(minX)f,%(minY)f
                </gml:coordinates>
            </gml:LinearRing>
        </gml:outerBoundaryIs>
    </gml:Polygon>
    """ % ({'minX':minx2, 'minY':miny2, 'maxX':maxx2, 'maxY':maxy2}))

    return boxA

def _getDistance(startingpoint, endpoint):
    """
    input: in WGS84 - startingpoint[lat, lon], endpoint[lat, lon]
    @see http://www.movable-type.co.uk/scripts/latlong.html
    """
    radius = 6371
    radLat1 = (startingpoint[0] * pi) / 180
    radLat2 = (endpoint[0] * pi) / 180
    deltLat = ((endpoint[0] - startingpoint[0]) * pi ) / 180
    deltLon = ((endpoint[1] - startingpoint[1]) * pi ) / 180

    a = sin(deltLat / 2) * sin(deltLat / 2) + cos(radLat1) * cos(radLat2) * sin(deltLon / 2) * sin(deltLon / 2)
    c = 2 * atan2(sqrt(a), sqrt(1-a))
    d = radius * c
    return d

def _getMidPoint(bbox):
    line1 = "LINESTRING (%f %f, %f %f)" % (bbox[0], bbox[1], bbox[2], bbox[3])
    line2 = "LINESTRING (%f %f, %f %f)" % (bbox[2], bbox[1], bbox[0], bbox[3])

    line1 = ogr.CreateGeometryFromWkt(line1)
    line2 = ogr.CreateGeometryFromWkt(line2)

    intersectionPoint = line1.Intersection(line2)
    intersectGeometry = ogr.CreateGeometryFromWkt(intersectionPoint.ExportToWkt())

    datatype = intersectGeometry.GetGeometryName()

    if str.upper(datatype) == "LINESTRING":
        if bbox[1] == bbox[3]:
            line1 = "LINESTRING (%f %f, %f %f)" % (bbox[0], bbox[1]-0.001, bbox[2], bbox[3]+0.001)
            line2 = "LINESTRING (%f %f, %f %f)" % (bbox[2], bbox[1]-0.001, bbox[0], bbox[3]+0.001)

        elif bbox[0] == bbox[2]:
            line1 = "LINESTRING (%f %f, %f %f)" % (bbox[0]-0.001, bbox[1], bbox[2]+0.001, bbox[3])
            line2 = "LINESTRING (%f %f, %f %f)" % (bbox[2]-0.001, bbox[1], bbox[0]+0.001, bbox[3])

        line1 = ogr.CreateGeometryFromWkt(line1)
        line2 = ogr.CreateGeometryFromWkt(line2)

        intersectionPoint = line1.Intersection(line2)
        intersectGeometry = ogr.CreateGeometryFromWkt(intersectionPoint.ExportToWkt())

    return intersectGeometry

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

# # Geometry
# print("\n Geometry \n")
# bbox1 = [13.0078125, 50.62507306341435, 5.44921875, 45.82879925192134]
# bbox2 = [17.7978515625, 52.09300763963822, 7.27294921875, 46.14939437647686]
# print(spatialDistance(bbox1, bbox2))
# print(spatialOverlap(bbox1, bbox2))
# print(similarArea(bbox1, bbox2))

# # Points
# print("\n Points \n")
# bbox1 = [13.0078125, 50.62507306341435, 13.0078125, 50.62507306341435]
# bbox2 = [13.0082125, 50.62513301341435, 13.0082125, 50.62513301341435]
# print(spatialDistance(bbox1, bbox2))
# print(spatialOverlap(bbox1, bbox2))
# print(similarArea(bbox1, bbox2))

# # Line and Point
# print("\n Line and Point \n")
# bbox1 = [10.0078125, 50.62507306341435, 13.0078125, 50.62507306341435]
# bbox2 = [13.0082125, 50.62513301341435, 13.0082125, 50.62513301341435]
# print(spatialDistance(bbox1, bbox2))
# print(spatialOverlap(bbox1, bbox2))
# print(similarArea(bbox1, bbox2))

# # Polygon and Point
# print("\n Polygon and Point \n")
# bbox1 = [13.0078125, 50.62507306341435, 5.44921875, 45.82879925192134]
# bbox2 = [13.0082125, 50.62513301341435, 13.0082125, 50.62513301341435]
# print(spatialDistance(bbox1, bbox2))
# print(spatialOverlap(bbox1, bbox2))
# print(similarArea(bbox1, bbox2))

# # Same BoundingBox
# print("\n Same BoundingBox \n")
# bbox1 = [124.99553571, 67.99553636, 165.00445788, 72.00446429]
# bbox2 = [124.99553571, 67.99553636, 165.00445788, 72.00446429]
# print(spatialDistance(bbox1, bbox2))
# print(spatialOverlap(bbox1, bbox2))
# print(similarArea(bbox1, bbox2))

# # Ähnliche BoundingBox, die nah beieinander liegt
# print("\n Similar Bounding Box which are close to each other \n")
# bbox1 = [7.596703,51.950402,7.656441,51.978536]
# bbox2 = [7.588205,51.952412,7.616014,51.967644]
# print(spatialDistance(bbox1, bbox2))
# print(spatialOverlap(bbox1, bbox2))
# print(similarArea(bbox1, bbox2))

# # Weit entfernte Boundingboxen
# print("\n Not so related Bounding Box \n")
# bbox1 = [7.596703,51.950402,7.656441,51.978536]
# bbox2 = [-96.800194,32.760085,-96.796353,32.761385]
# print(spatialDistance(bbox1, bbox2))
# print(spatialOverlap(bbox1, bbox2))
# print(similarArea(bbox1, bbox2))

# Geometry

# 0.74
# 0.41
# 0.58

#  Points

# 0.99
# 0.81
# 1.0

#  Line and Point

# 0.49
# 0.0
# 1.0

#  Polygon and Point

# 0.5
# 0.0
# 0.0

#  Same BoundingBox

# 1.0
# 1.0
# 1.0

#  Similar Bounding Box which are close to each other

# 0.66
# 0.17
# 0.25

#  Not so related Bounding Box

# 0
# 0.0
# 0.0

# Geometry

# 0.74
# 0.41
# 0.57

#  Points

# 0.99
# 0.99
# 1.0

#  Line and Point

# 0.49
# 0.99
# 1.0

#  Polygon and Point

# 0.5
# 0.0
# 0.0

#  Same BoundingBox

# 1.0
# 1.0
# 1.0

#  Similar Bounding Box which are close to each other

# 0.66
# 0.17
# 0.25

#  Not so related Bounding Box

# 0
# 0.0
# 0.0


from django.urls import path, include
from . import views
from rest_framework.routers import DefaultRouter

app_name = 'bank'
router = DefaultRouter()
router.register('bank', views.BankViewset, basename='bank-viewset')
router.register('branch', views.BranchViewset, basename='branch-viewset')
router.register('atm', views.ATMViewset, basename='atm-viewset')
router.register('annon-atm', views.AnnonViewset, basename='annon-atm-viewset')

urlpatterns = [
    path('', include(router.urls))
]


import metomi.rose.macro
import metomi.rose.variable

class FibonacciChecker(metomi.rose.macro.MacroBase):

    """Class to check if an array matches a Fibonacci sequence."""

    BAD_SEQUENCE = "not the Fibonacci sequence"

    def validate(self, config, meta_config, starts_at_zero=False):
        """Validate an array containing integer elements."""
        self.reports = []
        if starts_at_zero:
            seq = [0, 1]
        else:
            seq = [1, 1]
        section = "env"
        option = "INVALID_SEQUENCE"
        node = config.get([section, option])
        if node is None:
            return []
        value = node.value
        elems = metomi.rose.variable.array_split(value)
        if all([w.isdigit() for w in elems]) and len(elems) > 1:
            int_elems = [int(w) for w in elems]
            if len(int_elems) >= 2 and int_elems[:2] != seq:
                self.add_report(section, option, value, self.BAD_SEQUENCE)
            else:
                for i, element in enumerate(int_elems):
                    if i < 2:
                        continue
                    if element != int_elems[i - 1] + int_elems[i - 2]:
                        self.add_report(
                            section, option, value, self.BAD_SEQUENCE
                        )
                        break
        else:
            self.add_report(section, option, value, self.BAD_SEQUENCE)
        return self.reports


import os
import pkgutil
import argparse
import importlib

PLUGINS_IGNORE = ()
PLUGINS_PATH = [os.path.join(os.path.dirname(__file__), 'plugins')]

def discover_plugins():
    """ Import all modules from PLUGINS_PATH.
        Except plugins in PLUGINS_IGNORE """
    plugins = dict()

    for _, name, _ in pkgutil.iter_modules(PLUGINS_PATH):
        if not name in PLUGINS_IGNORE:
            plugins[name] = importlib.import_module('plugins.' + name)

    return plugins

def main():
    cli = argparse.ArgumentParser()
    cli.add_argument('--devmode', action='store_true')
    sub = cli.add_subparsers()
    sub.require = True

    plugins = discover_plugins()

    for _, plugin in plugins.items():
        plugin.register_parser(sub)

    args = cli.parse_args()
    args.func(args)

if __name__ == '__main__':
    main()


import os, sys, re
import ipdb

import numpy as np
import imageio

import torch
import torch.nn as nn
import torch.nn.functional as F
from tqdm import tqdm, trange
import cv2

from internal.mask_utils.load_llff import load_llff_data
from internal.mask_utils.load_blender import load_blender_data, load_blender_view_data
from internal.mask_utils.load_dtu import load_dtu_data

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

np.random.seed(0)

def read_pfm(filename):
    file = open(filename, 'rb')
    color = None
    width = None
    height = None
    scale = None
    endian = None

    header = file.readline().decode('utf-8').rstrip()
    if header == 'PF':
        color = True
    elif header == 'Pf':
        color = False
    else:
        raise Exception('Not a PFM file.')

    dim_match = re.match(r'^(\d+)\s(\d+)\s$', file.readline().decode('utf-8'))
    if dim_match:
        width, height = map(int, dim_match.groups())
    else:
        raise Exception('Malformed PFM header.')

    scale = float(file.readline().rstrip())
    if scale < 0:  # little-endian
        endian = '<'
        scale = -scale
    else:
        endian = '>'  # big-endian

    data = np.fromfile(file, endian + 'f')
    shape = (height, width, 3) if color else (height, width)

    data = np.reshape(data, shape)
    data = np.flipud(data)
    file.close()
    return data, scale

def get_rays_ref(directions, c2w):
    """
    Get ray origin and normalized directions in world coordinate for all pixels in one image.
    Reference: https://www.scratchapixel.com/lessons/3d-basic-rendering/
               ray-tracing-generating-camera-rays/standard-coordinate-systems
    Inputs:
        directions: (H, W, 3) precomputed ray directions in camera coordinate
        c2w: (3, 4) transformation matrix from camera coordinate to world coordinate
    Outputs:
        rays_o: (H*W, 3), the origin of the rays in world coordinate
        rays_d: (H*W, 3), the normalized direction of the rays in world coordinate
    """
    # Rotate ray directions from camera coordinate to the world coordinate
    rays_d = directions @ c2w[:3, :3].T  # (H, W, 3)
    # rays_d = rays_d / torch.norm(rays_d, dim=-1, keepdim=True)
    # The origin of all rays is the camera origin in world coordinate
    rays_o = c2w[:3, 3].expand(rays_d.shape)  # (H, W, 3)

    rays_d = rays_d.view(-1, 3)
    rays_o = rays_o.view(-1, 3)

    return rays_o, rays_d

def get_ref_rays(w2c_ref, c2w_ref, intrinsic_ref, point_samples, img, depths_h=None):
    '''
        point_samples [N_rays N_sample 3]
    '''

    device = img.device

    B, N_rays, N_samples = point_samples.shape[:3] # [B ray_samples N_samples 3]
    point_samples = point_samples.reshape(B, -1, 3)

    N, C, H, W = img.shape
    inv_scale = torch.tensor([W-1, H-1]).to(device)

    # wrap to ref view
    if w2c_ref is not None:
        # R = w2c_ref[:3, :3]  # (3, 3)
        # T = w2c_ref[:3, 3:]  # (3, 1)
        # point_samples = torch.matmul(point_samples, R.t()) + T.reshape(1,3)
        R = w2c_ref[:, :3, :3]  # (B, 3, 3)
        T = w2c_ref[:, :3, 3:]  # (B, 3, 1)
        transform = torch.FloatTensor([[1,0,0],[0,-1,0], [0,0,-1]])[None]
        point_samples = (point_samples @ R.permute(0,2,1) + T.reshape(B, 1, 3)) @ transform # [B, ray_samples*N_samples, 3] [5, 131072, 3]

    if intrinsic_ref is not None:
        # using projection
        # point_samples_pixel = point_samples @ intrinsic_ref.t()
        point_samples_pixel = point_samples @ intrinsic_ref.permute(0,2,1) # [B, ray_samples*N_samples, 3]

        point_samples_pixel_x = (point_samples_pixel[:, :, 0] / point_samples_pixel[:, :, 2] + 0.0).round().detach()  # [B, ray_samples*N_samples]
        point_samples_pixel_y = (point_samples_pixel[:, :, 1] / point_samples_pixel[:, :, 2] + 0.0).round().detach()  # [B, ray_samples*N_samples]

        point_samples_pixel_x_norm = point_samples_pixel_x / inv_scale[0] # [B, ray_samples*N_samples]
        point_samples_pixel_y_norm = point_samples_pixel_y / inv_scale[1] # [B, ray_samples*N_samples]

    # mask
    mask_x = ((point_samples_pixel_x_norm > 0.0) * (point_samples_pixel_x_norm < 1.0)) # [B, N_rays]
    mask_y = ((point_samples_pixel_y_norm > 0.0) * (point_samples_pixel_y_norm < 1.0))  # [B, N_rays]
    mask = mask_x * mask_y

    cent = [intrinsic_ref[0, 0, 2], intrinsic_ref[0, 1, 2]]
    focal = [intrinsic_ref[0, 0, 0], intrinsic_ref[0, 1, 1]]

    directions = torch.stack([(point_samples_pixel_x[mask] - cent[0]) / focal[0], (point_samples_pixel_y[mask] - cent[1]) / focal[1], torch.ones_like(point_samples_pixel_x[mask])], -1)  # (H, W, 3)

    rays_o, rays_d = get_rays_ref(directions, c2w_ref[0])  # both (h*w, 3)

    rgb_ref = img[:, :, point_samples_pixel_y[mask].type(torch.LongTensor), point_samples_pixel_x[mask].type(torch.LongTensor)]
    if depths_h is not None:
        depth_h_ref = depths_h.unsqueeze(1)[:, :, point_samples_pixel_y[mask].type(torch.LongTensor),point_samples_pixel_x[mask].type(torch.LongTensor)]
        return rgb_ref, depth_h_ref, point_samples, rays_o, rays_d, mask
    else:
        return rgb_ref, point_samples, rays_o, rays_d, mask

def get_rays(H, W, K, c2w):
    i, j = torch.meshgrid(torch.linspace(0, W-1, W), torch.linspace(0, H-1, H))  # pytorch's meshgrid has indexing='ij'
    i = i.t()
    j = j.t()
    dirs = torch.stack([(i-K[0][2])/K[0][0], -(j-K[1][2])/K[1][1], -torch.ones_like(i)], -1)
    # Rotate ray directions from camera frame to the world frame
    rays_d = torch.sum(dirs[..., np.newaxis, :] * c2w[:3,:3], -1)  # dot product, equals to: [c2w.dot(dir) for dir in dirs]
    # Translate camera frame's origin to the world frame. It is the origin of all rays.
    rays_o = c2w[:3,-1].expand(rays_d.shape)
    return rays_o, rays_d

def get_hard_masks(dataset_name, path, scene, nb_views = 3):

    K = None

    if dataset_name == 'llff':

        llff_path = path
        factor = 4
        spherify = False
        no_ndc = True

        datadir = os.path.join(llff_path, scene)
        images, poses, bds, render_poses, i_test = load_llff_data(datadir, factor,
                                                                  recenter=True, bd_factor=.75,
                                                                  spherify=spherify)

        hwf = poses[0,:3,-1]
        poses = poses[:,:3,:4]
        print('Loaded llff', images.shape, render_poses.shape, hwf, datadir)

        scene = os.path.basename(datadir)
        depth_files = [os.path.join('./data/nerf_llff_data_depth/', scene, f) for f in sorted(os.listdir(os.path.join('./data/nerf_llff_data_depth/', scene))) \
                if f.endswith('pfm')]

        depths_cas = [cv2.resize(np.array(read_pfm(filename)[0], dtype=np.float32), (1008, 756)) for filename in depth_files]
        depths_cas = np.stack(depths_cas[:images.shape[0]], axis=0)

        name = os.path.basename(datadir)
        i_train = torch.load('configs/pairs.th')[f'{name}_train'][:nb_views]
        i_test = torch.load('configs/pairs.th')[f'{name}_val']

        print('DEFINING BOUNDS')
        if no_ndc:
            near = np.ndarray.min(bds) * .9
            far = np.ndarray.max(bds) * 1.
        else:
            near = 0.
            far = 1.
        print('NEAR FAR', near, far)

    elif dataset_name == 'blender':

        nerf_path = path
        white_bkgd = True

        datadir = os.path.join(nerf_path, scene)
        images, poses, render_poses, hwf, i_split, depths_cas = load_blender_view_data(datadir, False, 8, train_view_num=nb_views)
        print('Loaded blender', images.shape, depths_cas.shape, render_poses.shape, hwf, datadir)
        name = os.path.basename(datadir)
        i_train, i_val, i_test = i_split

        near = 2.
        far = 6.

        if white_bkgd:
            images = images[...,:3]*images[...,-1:] + (1.-images[...,-1:])
        else:
            images = images[...,:3]

    elif dataset_name == 'dtu':

        dtu_path = path

        datadir = os.path.join(dtu_path, scene)
        images, poses, bds, render_poses, hwf, depths_cas, depths = load_dtu_data(datadir, train_view_num = nb_views)

        poses = poses[:,:3,:4]
        print('Loaded llff', images.shape, render_poses.shape, hwf, datadir)

        i_train = torch.load('configs/pairs.th')[f'dtu_train'][:nb_views]
        i_test = torch.load('configs/pairs.th')[f'dtu_val']

        print('DEFINING BOUNDS')

        near = np.ndarray.min(bds)
        far = np.ndarray.max(bds)

        print('NEAR FAR', near, far)

    else:
        print('Unknown dataset type', dataset_name, 'exiting')
        return

#====================================================================================================================================
    # Cast intrinsics to right types
    H, W, focal = hwf
    H, W = int(H), int(W)
    hwf = [H, W, focal]

    if K is None:
        K = np.array([
            [focal, 0, 0.5*W],
            [0, focal, 0.5*H],
            [0, 0, 1]
        ])

    # Create log dir and copy the config file
    basedir = 'other'
    expname = f'masks/{dataset_name}/{scene}'

    # generate mask information
    mask_all = []
    scene = os.path.basename(datadir)

    os.makedirs(f'{basedir}/{expname}/', exist_ok=True)
    for tgt_index in range(images.shape[0]):
        if tgt_index in i_train:

            #目标视角深度与ray
            pose_tgt = poses[tgt_index, :3, :4]
            rays_o_tgt, rays_d_tgt = get_rays(H, W, K, torch.Tensor(pose_tgt))  # (H, W, 3), (H, W, 3)
            depth_cas_tgt = torch.Tensor(depths_cas[tgt_index])
            rays_o_tgt, rays_d_tgt = rays_o_tgt.reshape(-1, 3), rays_d_tgt.reshape(-1, 3)
            depth_cas_tgt = depth_cas_tgt.reshape(-1)
            mask_tgt = torch.zeros_like(depth_cas_tgt)

            #遍历其他视角作ref
            for ref_index in i_train:
                if ref_index != tgt_index:
                    mask_tgt_mid = torch.zeros_like(depth_cas_tgt)
                    c2w_ref = torch.eye(4)
                    c2w_ref[:3, :4] = torch.Tensor(poses[ref_index, :3, :4])
                    w2c_ref = torch.inverse(c2w_ref)
                    for chunk_idx in range(depth_cas_tgt.shape[0] // 5120 + int(depth_cas_tgt.shape[0] % 5120 > 0)):

                        #从目标视角中取出像素点对应三维点坐标
                        point_samples_w = rays_o_tgt[chunk_idx * 5120:(chunk_idx + 1) * 5120] + \
                                        depth_cas_tgt[chunk_idx * 5120:(chunk_idx + 1) * 5120,None] * rays_d_tgt[chunk_idx * 5120:(chunk_idx + 1) * 5120]  # [N_rays, 3]

                        #计算这些点在ref视角下颜色与深度
                        rgb_target_ref, rays_depth_ref, point_samples_c_ref, rays_o_ref, rays_d_ref, mask_bound = get_ref_rays(
                            w2c_ref.unsqueeze(0), c2w_ref.unsqueeze(0), torch.Tensor(K).unsqueeze(0), point_samples_w[None, :, None, :],
                            torch.Tensor(images[ref_index]).unsqueeze(0).permute(0, 3, 1, 2),
                            torch.Tensor(depths_cas[ref_index]).unsqueeze(0))

                        #计算mask_tgt_mid，意义为tgt视角中与当前ref视角匹配点的像素mask
                        if mask_bound.sum() != 0:
                            mask = torch.ones(rgb_target_ref.shape[2], 1).cuda() < 0
                            occlusion_threshold = 0.1
                            while mask.sum() == 0:
                                depth_diff = point_samples_c_ref[mask_bound][...,-1].unsqueeze(-1)-rays_depth_ref.squeeze(0).squeeze(0)[:, None]
                                mask = (abs(depth_diff)<occlusion_threshold)
                                occlusion_threshold = 2 * occlusion_threshold

                            mask_bound_new = mask_bound.clone()
                            mask_bound_new[mask_bound] = mask.squeeze()
                            mask_tgt_mid[chunk_idx * 5120:(chunk_idx + 1) * 5120] = mask_bound_new.squeeze()
                            del mask_bound_new
                        else:
                            mask_tgt_mid[chunk_idx * 5120:(chunk_idx + 1) * 5120] = False

                    #注意true + true = true, false + false = false, true + false = true
                    mask_tgt += mask_tgt_mid
            mask_all.append(np.array((mask_tgt>0).cpu().reshape(H, W)))
            #保存mask
            imageio.imwrite(f'{basedir}/{expname}/{tgt_index}_mask_{nb_views}view.jpg', (mask_all[-1].reshape(H, W) * 255).astype(np.uint8))
        else:
            if dataset_name != 'blender':
                mask_all.append(np.zeros((hwf[0],hwf[1])))

    masks_cas = np.stack(mask_all, 0)

    return masks_cas


from tempfile import NamedTemporaryFile
from textwrap import wrap

# Testing context manager
class FileOp:
    def __init__(self, file_name, method):
        self.file_name = file_name
        self.method = method

    def __enter__(self):
        self.file = open(self.file_name, self.method)
        return self.file

    def __exit__(self, type=None, value=None, traceback=None):
        self.file.close()

if __name__ == "__main__":
    with NamedTemporaryFile(mode="a+", delete=False) as temp_file:
        file_path = temp_file.name
        with FileOp(file_path, "w") as file:
            file.write("test")
        with open(file_path, "r") as f:
            assert f.read() == "test"


#inverse number
a=a1 =int(input("Enter the number you want to inverse = "))
f=0
while(a>0):
  b = a % 10
  f=f*10+b
  a=int(a//10)
print("inverse of",a1,"is >>>>",int(f))


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from utils import tfrecord_voc_utils as voc_utils
import tensorflow as tf
import numpy as np
import LH_RCNN as net
import os
# import matplotlib.pyplot as plt
# import matplotlib.patches as patches
# from skimage import io, transform
# from utils.voc_classname_encoder import classname_to_ids
# os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
# os.environ['CUDA_VISIBLE_DEVICES'] = '1'
lr = 0.003
batch_size = 32
buffer_size = 1024
epochs = 1500
reduce_lr_epoch = []
config = {
    'data_shape': [700, 1100, 3],
    'mode': 'train',                            # 'train' ,'test'
    'is_pretraining': False,
    'data_format': 'channels_last',             # 'channels_last' ,'channels_first'
    'num_classes': 20,
    'weight_decay': 1e-4,
    'keep_prob': 0.5,                           # not used
    'batch_size': batch_size,
    'rpn_first_step': 60000,                    # iters 0 - rpn_first_step train  rpn only
    'rcnn_first_step': 100000,                   # iters rpn_first_step - rcnn_first_step train  rcnn only
    'rpn_second_step': 160000,                   # iters rcnn_first_step - rpn_second_step train  rpn only
                                                # iters rpn_second_step - end train  rcnn only
    'nms_score_threshold': 0.5,
    'nms_max_boxes': 20,
    'nms_iou_threshold': 0.45,
    'post_nms_proposal': 500                    # when test, how many proposal are kept after nms
}

image_augmentor_config = {
    'data_format': 'channels_last',
    'output_shape': [700, 1100],
    'zoom_size': [720, 1120],
    'crop_method': 'random',
    'flip_prob': [0., 0.5],
    'fill_mode': 'BILINEAR',
    'keep_aspect_ratios': False,
    'constant_values': 0.,
    'color_jitter_prob': 0.5,
    'rotate': [0.5, -5., -5.],
    'pad_truth_to': 60,
}

data = os.listdir('./voc2007/')
data = [os.path.join('./voc2007/', name) for name in data]

train_gen = voc_utils.get_generator(data,
                                    batch_size, buffer_size, image_augmentor_config)
trainset_provider = {
    'data_shape': [700, 1100, 3],
    'num_train': 5011,
    'num_val': 0,                               # not used
    'train_generator': train_gen,
    'val_generator': None                       # not used
}
rcnn = net.LHRCNN(config, trainset_provider)
# rcnn.load_pretraining_weight('./rcnnpretrain/test-30000')
# rcnn.load_weight('./lhrcnn/test-44304')
for i in range(epochs):
    print('-'*25, 'epoch', i, '-'*25)
    if i in reduce_lr_epoch:
        lr = lr/10.
        print('reduce lr, lr=', lr, 'now')
    mean_loss = rcnn.train_one_epoch(lr)
    print('>> mean loss', mean_loss, )
    rcnn.save_weight('latest', './lhrcnn/test')    # 'latest' 'best'

# img = io.imread('000026.jpg')
# img = transform.resize(img, [700,1100])
# img = np.expand_dims(img, 0)
# result = ssd300.test_one_image(img)
# id_to_clasname = {k:v for (v,k) in classname_to_ids.items()}
# scores = result[0]
# bbox = result[1]
# class_id = result[2]
# print(scores, bbox, class_id)
# plt.figure(1)
# plt.imshow(np.squeeze(img))
# axis = plt.gca()
# for i in range(len(scores)):
#     rect = patches.Rectangle((bbox[i][1],bbox[i][0]), bbox[i][3]-bbox[i][1],bbox[i][2]-bbox[i][0],linewidth=2,edgecolor='b',facecolor='none')
#     axis.add_patch(rect)
#     plt.text(bbox[i][1],bbox[i][0], id_to_clasname[class_id[i]]+str(' ')+str(scores[i]), color='red', fontsize=12)
# plt.show()


import sys
input = sys.stdin.readline
time = []
answer = []
for i in range(int(input())):
    start,end = map(int, input().split())
    time.append([start,end])
time.sort()
time.sort(key=lambda x: x[1])
for i in time:
    if len(answer) == 0:
        answer.append(i)
    else:
        if i[0] >= answer[-1][1]:
            answer.append(i)
print(answer)


from setuptools import setup
import sys

install_requires = ["six"]

if sys.version_info < (2, 7):
    install_requires.append("ordereddict")

setup(
    name='django-choice-object',
    version='0.9',
    packages=['django_choice_object'],
    url='https://github.com/orf/django-choice-object',
    license='',
    author='Tom',
    author_email='tom@tomforb.es',
    description='A choice object for Django forms and models',
    install_requires=install_requires
)