import unittest
from bs4 import BeautifulSoup
from src import get_html_script as ghs
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from models.models import JobDataModel
from models import domain_db_mappings as dbm
from models.database_models import JobDataDbModel
import models.database_methods as db_ops
from src.email_generator import TextEmailContent, HtmlEmailContent, generate_full_email_content
from src.email_sender import send_email_to_user, get_data_and_send_email
from datetime import date

Base = declarative_base()

class TestScrapeMethods(unittest.TestCase):

    def test_successfully_scrapes_site(self):
        # Phil comes by, he wants to use this web scraper tool.
        # He plans to see if it can find data on mechanics jobs,
        # and he wants to move to tampa, so he checks monster.
        query = 'mechanic'
        location = 'Tampa'
        site = 'https://www.monster.com'
        #url = 'https://www.monster.com/jobs/search/?q=mechanic&where=Tampa'
        results = ghs.scrape_site(site, query, location)

        # Phil sees that he was able to get a successful response
        self.assertEqual(results.status_code, 200)

        # Phil sees that it did in fact search the site he wanted.
        self.assertTrue(site in results.url)

        # Phil sees that it definitely searched for the type of job he wanted.results
        self.assertTrue(query in results.url)

        # He also sees that it certainly searched the location he wanted.
        self.assertTrue(location in results.url)

    def test_successfully_parses_data(self):
        # Mary is a bit more discerning than Phil.
        # She wants to make sure her data makes sense.

        query = 'developer'
        location = 'New York'
        site = 'monster.com'
        location_names = ['New York', 'NY']

        results = ghs.scrape_full_page(site, query, location)

        # Results are not empty. Mary managed to scrape data from a site!
        self.assertTrue(results)

        # Mary does not see any html.
        results_names = [result.title for result in results]
        results_locations = [result.location for result in results]
        results_sites = [result.link for result in results]

        self.assertFalse(any(
            [
                bool(BeautifulSoup(results_name, "html.parser").find())
                for results_name in results_names
            ]
        ))

        self.assertFalse(any(
            bool(BeautifulSoup(results_location, "html.parser").find())
            for results_location in results_locations
        ))

        # Mary sees that she did get radiologist jobs in her results.
        self.assertTrue(any([(query in results_name) for results_name in results_names]))

        # Mary also sees that she got results in New York.
        self.assertTrue(any(
            [
                [loc in results_location for loc in location_names]
                for results_location in results_locations
            ]
        ))

        # Mary lastly sees that all of the job links are, in fact from monster.
        self.assertTrue(all([site in result_site for result_site in results_sites]))

        # Amazed at how far technology has come, a satisfied Mary goes to bed.

class EndToEndHtmlScrapeSaveToDbTest(unittest.TestCase):
    def setUp(self):
        self.engine = create_engine('sqlite:///:memory:')
        Session = sessionmaker(bind=self.engine)
        self.session = Session()
        Base.metadata.create_all(self.engine, tables=[JobDataDbModel.__table__])

    def tearDown(self):
        Base.metadata.drop_all(self.engine)

    def test_scrapes_and_saves_job_data(self):
        job_sites = ['monster.com']
        location = 'utah'
        query = 'hairdresser'

        before_data = self.session.query(JobDataDbModel).all()

        self.assertFalse(before_data)

        ghs.scrape_sites_and_save_jobs(job_sites, query, location, self.session)

        after_data = self.session.query(JobDataDbModel).all()

        self.assertTrue(after_data)

class StoresDataAndSendsEmailTest(unittest.TestCase):
    def setUp(self):
        self.engine = create_engine('sqlite:///:memory:')
        Session = sessionmaker(bind=self.engine)
        self.session = Session()
        Base.metadata.create_all(self.engine, tables=[JobDataDbModel.__table__])

    def tearDown(self):
        Base.metadata.drop_all(self.engine)

    def test_emails_saved_job_data(self):
        # Larry is lazy. He doesn't want to have to keep checking everything himself, so
        # He wants the app to email him only results that haven't already been emailed to him yet.

        query = 'hairdresser'
        location = 'utah'
        site = 'monster.com'

        class_data = ghs.scrape_full_page(site, query, location)

        # His data is saved to the database. It is the exact same data that he had before.
        mapped_data = dbm.map_job_data_models_to_db_models(class_data)

        for data_point in mapped_data:
            self.session.add(data_point)

        self.session.commit()

        saved_data = self.session.query(JobDataDbModel).all()

        response = get_data_and_send_email(self.session)

        # Larry has received the email after a short amount of time has passed.
        self.assertDictEqual(response, {})

        # All of the items that were sent are now marked as having been sent.
        # Because of this, none of them should show if we filter out sent items in the DB.
        updated_data = self.session.query(JobDataDbModel).filter(JobDataDbModel.has_been_emailed == False).all()
        self.assertTrue(len(updated_data) == 0)

        # Satisfied that it works as expected, Larry goes to bed.

if __name__ == '__main__':
    unittest.main()


from tensorflow.keras.backend import clear_session
from tensorflow.keras.models import load_model
from tensorflow.keras.callbacks import ModelCheckpoint, Callback as keras_callback
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import numpy as np
from static.models.unet_model import unet
from scipy.io import loadmat
import json
import random
import logging

# This script uses a set of training data assembled into a .mat file consisting of a stack of images
#    and a corresponding set of binary masks that label the pixels in the image stacks into two classes.
#    The script then initializes a randomized U-NET (using the topology defined in the file model.py).
#    It then initiates training using a given batch size and # of epochs, saving the best net at each
#    step to the given .hdf5 file path.
#
# Written by Teja Bollu, documented and modified by Brian Kardon

def createDataAugmentationParameters(rotation_range=None, width_shift_range=0.1,
    height_shift_range=0.3, zoom_range=0.4, horizontal_flip=True,
    vertical_flip=True):
    # Create dictionary of data augmentation parameter
    return {
        "rotation_range":rotation_range,
        "width_shift_range":width_shift_range,
        "height_shift_range":height_shift_range,
        "zoom_range":zoom_range,
        "horizontal_flip":horizontal_flip,
        "vertical_flip":vertical_flip
    }

class PrintLogger:
    def __init__(self):
        pass
    def log(lvl, msg):
        print(msg)

def trainNetwork(trained_network_path, training_data_path, start_network_path=None,
    augment=True, batch_size=10, epochs=512, image_field_name='imageStack',
    mask_field_name='maskStack', data_augmentation_parameters={},
    epoch_progress_callback=None, logger=None):
    # Actually train the network, saving the best network to a file after each epoch.
    # augment = boolean flag indicating whether to randomly augment training data
    # batch_size = Size of training batches (size of batches that dataset is divided into for each epoch):
    # epochs = Number of training epochs (training runs through whole dataset):
    # training_data_path = .mat file containing the training data (image data and corresponding manually created mask target output):
    # image_field_name = Field within .mat file that contains the relevant images:
    # mask_field_name = Field within .mat file that contains the relevant masks:
    # trained_network_path = File path to save trained network to:
    # data_augmentation_parameters = to use for data augmentation:
    # epoch_progress_callback = a function to call at the end of each epoch,
    #   which takes a progress argument which will be a dictionary of progress
    #   indicators

    if logger is None:
        logger = PrintLogger()

    # Reset whatever buffers or saved state exists...not sure exactly what that consists of.
    # This may not actually work? Word is you have to restart whole jupyter server to get this to work.
    clear_session()

    # Convert inter-epoch progress callback to a tf.keras.Callback object
    epoch_progress_callback = TrainingProgressCallback(epoch_progress_callback)

    # Load training data
    print('Loading images and masks...')
    data = loadmat(training_data_path)
    img = data[image_field_name]
    mask = data[mask_field_name]

    # Process image and mask data into the proper format
    img_shape = img.shape;
    num_samples = img_shape[0]
    img_size_x = img_shape[1]
    img_size_y = img_shape[2]
    img = img.reshape(num_samples, img_size_x, img_size_y, 1)
    mask = mask.reshape(num_samples, img_size_x, img_size_y, 1)

    print("...image and mask data loaded.")
    print("Image stack dimensions:", img.shape)
    print(" Mask stack dimensions:", mask.shape)
    print('start path:', start_network_path)
    print('train path:', trained_network_path)

    if augment:
        imgGen = ImageDataGenerator(**data_augmentation_parameters)
        maskGen = ImageDataGenerator(**data_augmentation_parameters)

    if start_network_path is None:
        # Randomize new network structure using architecture in model.py file
        lickbot_net = unet(net_scale = 1)
    else:
        # Load previously trained network from a file
        lickbot_net = load_model(start_network_path)

    # Instruct training algorithm to save best network to disk whenever an improved network is found.
    model_checkpoint = ModelCheckpoint(str(trained_network_path), monitor='loss', verbose=1, save_best_only=True)
    callback_list = [model_checkpoint]
    if epoch_progress_callback is not None:
        callback_list.append(epoch_progress_callback)

    if augment:
        print("Using automatically augmented training data.")
        # Train network using augmented dataset
        seed = random.randint(0, 1000000000)
        imgIterator = imgGen.flow(img, seed=seed, shuffle=False, batch_size=batch_size)
        maskIterator = maskGen.flow(mask, seed=seed, shuffle=False, batch_size=batch_size)

        steps_per_epoch = int(num_samples / batch_size)
        lickbot_net.fit(
            ((imgBatch, maskBatch) for imgBatch, maskBatch in zip(imgIterator, maskIterator)),
            steps_per_epoch=steps_per_epoch, # # of batches of generated data per epoch
            epochs=epochs,
            verbose=1,
            callbacks=callback_list
        )
    else:
        lickbot_net.fit(
            img,
            mask,
            epochs=epochs,
            verbose=1,
            callbacks=callback_list
        )

class TrainingProgressCallback(keras_callback):
    def __init__(self, progressFunction):
        super(TrainingProgressCallback, self).__init__()
        self.logs = []
        self.progressFunction = progressFunction

    def on_epoch_end(self, epoch, logs=None):
        # self.logs.append(logs)
        # keys = list(logs.keys())
        if 'loss' in logs:
            loss = logs['loss']
        else:
            loss = None
        if 'acc' in logs:
            accuracy = logs['acc']
        else:
            accuracy = None
        exitFlag = self.progressFunction(epoch=epoch, loss=loss, accuracy=accuracy)
        if exitFlag:
            self.model.stop_training = True
        # print("End epoch {} of training; got log keys: {}".format(epoch, keys))

def validateNetwork(trained_network_path, img=None, imgIterator=None, maskIterator=None):
    # Load trained network
    lickbot_net = load_model(trained_network_path)

    if augment:
        img_validate = imgIterator.next()
        mask_validate = maskIterator.next()
    else:
        print('Using original dataset for visualization')
        img_validate = img
        mask_validate = mask

    mask_pred = lickbot_net.predict(img_validate)
    mask_pred.shape

    # %matplotlib inline
    from matplotlib import pyplot as plt
    from matplotlib import gridspec

    numValidation = img_validate.shape[0]

    img_shape = img.shape;
    num_samples = img_shape[0]
    img_size_x = img_shape[1]
    img_size_y = img_shape[2]

    img_disp =                       img_validate.reshape(numValidation,img_size_x,img_size_y)
    mask_disp =                     mask_validate.reshape(numValidation,img_size_x,img_size_y)
    mask_pred = lickbot_net.predict(img_validate).reshape(numValidation,img_size_x,img_size_y)

    scaleFactor = 3

    plt.figure(figsize=(scaleFactor*3,scaleFactor*numValidation))
    plt.subplots_adjust(wspace=0, hspace=0)
    gs = gridspec.GridSpec(nrows=numValidation, ncols=3, width_ratios=[1, 1, 1],
             wspace=0.0, hspace=0.0, bottom=0, top=1, left=0, right=1)
    for k in range(numValidation):
        plt.subplot(gs[k, 0])
        plt.imshow(mask_disp[k])
        plt.subplot(gs[k, 1])
        plt.imshow(mask_pred[k])
        plt.subplot(gs[k, 2])
        plt.imshow(img_disp[k])


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

from openerp import models, fields, api

class purchase_order(models.Model):
    _inherit = 'purchase.order'

    @api.multi
    def action_picking_create(self):
        res = super(purchase_order, self).action_picking_create()
        if self.picking_ids:
            picking_ids = [x.id for x in self.picking_ids]
            self.env['sftp.more'].sftp_send(picking_ids)
        return res


# -*- coding: utf-8 -*- #
'''
--------------------------------------------------------------------------
# File Name:        PATH_ROOT/utils/signal_vis.py
# Author:           JunJie Ren
# Version:          v1.1
# Created:          2021/06/15
# Description:      — — — — — — — — — — — — — — — — — — — — — — — — — — —
                            --> DD信号识别（可解释）系列代码 <--
                    -- 可视化信号输入
                    — — — — — — — — — — — — — — — — — — — — — — — — — — —
# Module called:    <0> PATH_ROOT/config.py
                    <1> PATH_TOOT/dataset/RML2016.py
                    — — — — — — — — — — — — — — — — — — — — — — — — — — —
# Function List:    <0> drawAllOriSignal():
                        绘制所有信号输入样本的图像，并保存至相应标签的文件夹下
                    <1> showOriSignal():
                        绘制并展示一个样本信号的图像
                    <2> showImgSignal():
                        绘制并展示一个信号样本的二维可视化图像
                    <3> showCamSignal():
                        叠加信号与CAM图，可视化CAM解释结果，并按类型保存
                    <4> mask_image():
                        软阈值擦除CAM对应的判别性特征区域
                    — — — — — — — — — — — — — — — — — — — — — — — — — — —
# Class List:       None
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# History:
       |  <author>  | <version> |   <time>   |          <desc>
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   <0> | JunJie Ren |   v1.0    | 2020/06/15 |           creat
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   <1> | JunJie Ren |   v1.1    | 2020/07/09 | 优化无name的数据集调用问题
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   <2> | JunJie Ren |   v1.2    | 2020/07/13 |     增加CAM阈值擦除函数
--------------------------------------------------------------------------
'''

import sys
import os

import cv2
import torch
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt
import matplotlib; matplotlib.use('TkAgg')
from sklearn.metrics import confusion_matrix

sys.path.append("../")
from app.configs import cfgs
from app.dataset.RML2016 import loadNpy
# from app.dataset.RML2016_04c.classes import modName

def t2n(t):
    return t.detach().cpu().numpy().astype(np.int)

def fig2data(fig):
    """
    fig = plt.figure()
    image = fig2data(fig)
    @brief Convert a Matplotlib figure to a 4D numpy array with RGBA channels and return it
    @param fig a matplotlib figure
    @return a numpy 3D array of RGBA values
    """
    import PIL.Image as Image
    # draw the renderer
    fig.canvas.draw()

    # Get the RGBA buffer from the figure
    w, h = fig.canvas.get_width_height()
    buf = np.fromstring(fig.canvas.tostring_argb(), dtype=np.uint8)
    buf.shape = (w, h, 4)

    # canvas.tostring_argb give pixmap in ARGB mode. Roll the ALPHA channel to have it in RGBA mode
    buf = np.roll(buf, 3, axis=2)
    image = Image.frombytes("RGBA", (w, h), buf.tostring())
    image = np.asarray(image)
    return image

def showOriSignal(sample, mod_name, idx):
    ''' 绘制并展示一个样本信号的图像 '''
    signal_data = sample[0]

    figure = plt.figure(figsize=(9, 6))
    plt.title(str(idx)+" "+str(mod_name), fontsize=30)
    plt.xlabel('N', fontsize=20)
    plt.ylabel("Value", fontsize=20)

    plt.plot(signal_data[:, 0], label = 'I', linewidth=2.0)
    plt.plot(signal_data[:, 1], color = 'red', label = 'Q', linewidth=2.0)
    plt.legend(loc="upper right", fontsize=30)
    plt.close()
    image = fig2data(figure)
    image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
    return image

def showCamSignal(signal, CAM, mod):
    """
    Args:
        signal: numpy.ndarray(size=(1, 128, 2), dtype=np.float)
        CAM: numpy.ndarray(size=(128, 2), dtype=np.float)
    Funcs:
        叠加信号与CAM图，可视化CAM解释结果，并按类型保存
    """
    # 绘制信号

    signal_data = signal[0]
    sig_len, channel = signal_data.shape

    figure = plt.figure(figsize=(18, 12))
    plt.title(mod, fontsize=26)
    plt.xlabel('N', fontsize=20)
    plt.ylabel("Value", fontsize=20)

    plt.plot(signal_data[:, 0]*(sig_len//10), label = 'I' ,linewidth=4.0)
    plt.plot(signal_data[:, 1]*(sig_len//10), color = 'red', label = 'Q', linewidth=4.0)
    plt.legend(loc="upper right", fontsize=26)

    # 绘制CAM
    sig_min, sig_max = np.min(signal_data), np.max(signal_data)

    CAM = CAM.T                      # (2, 128)
    CAM = CAM - np.min(CAM)
    CAM = CAM / np.max(CAM)          # CAM取值归一化

    plt.imshow(CAM, cmap='jet', extent=[0., sig_len, (sig_min-0.5)*(sig_len//10), (sig_max+0.5)*(sig_len//10)])     # jet, rainbow
    # plt.colorbar()
    '''
    save_path = "figs_CAM_ACARS/{}".format(mod_name)
    if not os.path.exists(save_path):
        os.makedirs(save_path)
    plt.savefig(save_path + '/' + str(idx+1)+"_CAM")
    plt.close()
    '''
    # plt.savefig("figs/CAM_cur")
    # plt.show()
    image = fig2data(figure)
    image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
    plt.close()
    return image

def plot_confusion_matrix(y_true, y_pred, labels, title='Normalized confusion matrix', intFlag = 0):
    ''' 绘制混淆矩阵 '''
    cmap = plt.cm.Blues
    ''' 颜色参考http://blog.csdn.net/haoji007/article/details/52063168'''
    cm = confusion_matrix(y_true, y_pred)
    tick_marks = np.array(range(len(labels))) + 0.5
    np.set_printoptions(precision=2)
    if cm.sum(axis=1)[:, np.newaxis].all() != 0:
        cm_normalized = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
    else:
        intFlag = 1
    figure = plt.figure(figsize=(10, 9), dpi=360)
    ind_array = np.arange(len(labels))
    x, y = np.meshgrid(ind_array, ind_array)
    # intFlag = 0 # 标记在图片中对文字是整数型还是浮点型
    for x_val, y_val in zip(x.flatten(), y.flatten()):
        if (intFlag):
            c = cm[y_val][x_val]
            plt.text(x_val, y_val, "%d" % (c,), color='red', fontsize=12, va='center', ha='center')

        else:
            c = cm_normalized[y_val][x_val]
            if (c > 0.0001):
                #这里是绘制数字，可以对数字大小和颜色进行修改
                plt.text(x_val, y_val, "%0.2f" % (c*100,) + "%", color='red', fontsize=10, va='center', ha='center')
            else:
                plt.text(x_val, y_val, "%d" % (0,), color='red', fontsize=10, va='center', ha='center')
    if(intFlag):
        plt.imshow(cm, interpolation='nearest', cmap=cmap)
    else:
        plt.imshow(cm_normalized, interpolation='nearest', cmap=cmap)
    plt.gca().set_xticks(tick_marks, minor=True)
    plt.gca().set_yticks(tick_marks, minor=True)
    plt.gca().xaxis.set_ticks_position('none')
    plt.gca().yaxis.set_ticks_position('none')
    plt.grid(True, which='minor', linestyle='-')
    plt.gcf().subplots_adjust(bottom=0.15)
    plt.title('Confusion Matrix', fontsize=18)
    plt.colorbar()
    xlocations = np.array(range(len(labels)))
    plt.xticks(xlocations, labels, rotation=90)
    plt.yticks(xlocations, labels)
    plt.ylabel('Index of True Classes')
    plt.xlabel('Index of Predict Classes')
    plt.savefig('./app/figs/confusion_matrix.jpg', dpi=300)

    image = fig2data(figure)
    image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
    return image
    # plt.title(title)
    # plt.show()

def drawAllOriSignal(X, Y):
    """
    Args:
        X: numpy.ndarray(size = (bz, 1, 128, 2)), 可视化信号原始数据
        Y: numpy.ndarray(size = (bz,)), 可视化信号标签
    Returns:
        None
    Funcs:
        绘制所有信号输入样本的图像，并保存至相应标签的文件夹下
    """
    for idx in range(len(X)):
        if (idx+1)%50 == 0:
            print("{} complete!".format(idx+1))
        signal_data = X[idx][0]
        mod_name = str(modName[Y[idx]], "utf-8") \
            if cfgs.dataset_name == "RML2016.04c" else "label-"+str(t2n(Y[idx]))

        plt.figure(figsize=(6, 4))
        plt.title(mod_name)
        plt.xlabel('N')
        plt.ylabel("Value")

        plt.plot(signal_data[:, 0], label = 'I')
        plt.plot(signal_data[:, 1], color = 'red', label = 'Q')
        plt.legend(loc="upper right")

        save_path = "../figs/original_signal/{}".format(mod_name)
        if not os.path.exists(save_path):
            os.makedirs(save_path)
        plt.savefig(save_path + '/' + str(idx+1))
        plt.close()

    print(X.shape)
    print(Y.shape)
    print("Complete the drawing of all original signals !!!")

def showImgSignal(sample, label):
    ''' 绘制并展示一个信号样本的二维可视化图像 '''
    data = sample[0].T                      # 2*128
    data = data - np.min(data)
    data = data / np.max(data)
    mod_name = str(modName[label], "utf-8")\
            if cfgs.dataset_name == "RML2016.04c" else "label-"+str(t2n(label))
    # print(data.shape)
    h, sig_len = data.shape

    # 叠加信号，以便显示
    img_sig = np.empty([sig_len, sig_len], dtype = float)
    # for row in range(int(sig_len/h)):
    #     img_sig[row*h:row*h+h, :] = data
    for row in range(sig_len):
        if row<sig_len/2:
            img_sig[row:row+1, :] = data[0]
        else:
            img_sig[row:row+1, :] = data[1]
    img_sig = cv2.resize(img_sig, (sig_len*2,sig_len*2))
    cv2.imshow(mod_name, img_sig)
    cv2.waitKey(0)
    return img_sig

def mask_image(cam, image, reserveORerase):
    """
    Args:
        cam: numpy.ndarray(size=(4096, 2), dtype=np.float), 0-1
        image: torch.Tensor, torch.Size([1, 4096, 2])
        reserveORerase: bool 保留(0)或擦除(1)判别性区域
    Funcs:
        软阈值擦除/保留CAM对应的判别性特征区域
    """
    cam = torch.from_numpy(cam).cuda()
    mask = torch.sigmoid(cfgs.CAM_omega * (cam - cfgs.Erase_thr)).squeeze()
    masked_image = image - (image * mask)  if reserveORerase else image * mask

    return masked_image.float()

def mask_image_hard(cam, image, reserveORerase, thr):
    ''' 阈值硬擦除 '''
    mask = np.zeros_like(cam)
    mask[cam >= thr] = 1
    mask[cam < thr] = 0
    mask = torch.from_numpy(mask).cuda()
    # print(mask.shape, image.shape)
    masked_image = image - (image * mask)  if reserveORerase else image * mask
    return masked_image.float()

if __name__ == "__main__":
    x_train, y_train, x_test, y_test = loadNpy(cfgs.train_path, cfgs.test_path)
    print(x_train.shape, y_train.shape)
    # drawAllOriSignal(X=x_train, Y=y_train)
    for idx in range(len(x_train)):
        showImgSignal(x_train[idx], y_train[idx])
        showOriSignal(x_train[idx], y_train[idx])


## Archived on the 22/09/2021
## Original terrain.py lived at io_ogre/terrain.py

import bpy

def _get_proxy_decimate_mod( ob ):
    proxy = None
    for child in ob.children:
        if child.subcollision and child.name.startswith('DECIMATED'):
            for mod in child.modifiers:
                if mod.type == 'DECIMATE':
                    return mod

def bake_terrain( ob, normalize=True ):
    assert ob.collision_mode == 'TERRAIN'
    terrain = None
    for child in ob.children:
        if child.subcollision and child.name.startswith('TERRAIN'):
            terrain = child
            break
    assert terrain
    data = terrain.to_mesh(bpy.context.scene, True, "PREVIEW")
    raw = [ v.co.z for v in data.vertices ]
    Zmin = min( raw )
    Zmax = max( raw )
    depth = Zmax-Zmin
    m = 1.0 / depth

    rows = []
    i = 0
    for x in range( ob.collision_terrain_x_steps ):
        row = []
        for y in range( ob.collision_terrain_y_steps ):
            v = data.vertices[ i ]
            if normalize:
                z = (v.co.z - Zmin) * m
            else:
                z = v.co.z
            row.append( z )
            i += 1
        if x%2:
            row.reverse() # blender grid prim zig-zags
        rows.append( row )
    return {'data':rows, 'min':Zmin, 'max':Zmax, 'depth':depth}

def save_terrain_as_NTF( path, ob ): # Tundra format - hardcoded 16x16 patch format
    info = bake_terrain( ob )
    url = os.path.join( path, '%s.ntf' % clean_object_name(ob.data.name) )
    f = open(url, "wb")
    # Header
    buf = array.array("I")
    xs = ob.collision_terrain_x_steps
    ys = ob.collision_terrain_y_steps
    xpatches = int(xs/16)
    ypatches = int(ys/16)
    header = [ xpatches, ypatches ]
    buf.fromlist( header )
    buf.tofile(f)
    # Body
    rows = info['data']
    for x in range( xpatches ):
        for y in range( ypatches ):
            patch = []
            for i in range(16):
                for j in range(16):
                    v = rows[ (x*16)+i ][ (y*16)+j ]
                    patch.append( v )
            buf = array.array("f")
            buf.fromlist( patch )
            buf.tofile(f)
    f.close()
    path,name = os.path.split(url)
    R = {
        'url':url, 'min':info['min'], 'max':info['max'], 'path':path, 'name':name,
        'xpatches': xpatches, 'ypatches': ypatches,
        'depth':info['depth'],
    }
    return R

class OgreCollisionOp(bpy.types.Operator):
    '''Ogre Collision'''
    bl_idname = "ogre.set_collision"
    bl_label = "modify collision"
    bl_options = {'REGISTER'}
    MODE = StringProperty(name="toggle mode", maxlen=32, default="disable")

    @classmethod
    def poll(cls, context):
        if context.active_object and context.active_object.type == 'MESH':
            return True

    def get_subcollisions( self, ob, create=True ):
        r = get_subcollisions( ob )
        if not r and create:
            method = getattr(self, 'create_%s'%ob.collision_mode)
            p = method(ob)
            p.name = '%s.%s' %(ob.collision_mode, ob.name)
            p.subcollision = True
            r.append( p )
        return r

    def create_DECIMATED(self, ob):
        child = ob.copy()
        bpy.context.scene.collection.objects.link( child )
        child.matrix_local = mathutils.Matrix()
        child.parent = ob
        child.hide_select = True
        child.draw_type = 'WIRE'
        #child.select = False
        child.lock_location = [True]*3
        child.lock_rotation = [True]*3
        child.lock_scale = [True]*3
        decmod = child.modifiers.new('proxy', type='DECIMATE')
        decmod.ratio = 0.5
        return child

    def create_TERRAIN(self, ob):
        x = ob.collision_terrain_x_steps
        y = ob.collision_terrain_y_steps
        #################################
        #pos = ob.matrix_world.to_translation()
        bpy.ops.mesh.primitive_grid_add(
            x_subdivisions=x,
            y_subdivisions=y,
            size=1.0 )      #, location=pos )
        grid = bpy.context.active_object
        assert grid.name.startswith('Grid')
        grid.collision_terrain_x_steps = x
        grid.collision_terrain_y_steps = y
        #############################
        x,y,z = ob.dimensions
        sx,sy,sz = ob.scale
        x *= 1.0/sx
        y *= 1.0/sy
        z *= 1.0/sz
        grid.scale.x = x/2
        grid.scale.y = y/2
        grid.location.z -= z/2
        grid.data.show_all_edges = True
        grid.draw_type = 'WIRE'
        grid.hide_select = True
        #grid.select = False
        grid.lock_location = [True]*3
        grid.lock_rotation = [True]*3
        grid.lock_scale = [True]*3
        grid.parent = ob
        bpy.context.scene.objects.active = ob
        mod = grid.modifiers.new(name='temp', type='SHRINKWRAP')
        mod.wrap_method = 'PROJECT'
        mod.use_project_z = True
        mod.target = ob
        mod.cull_face = 'FRONT'
        return grid

    def invoke(self, context, event):
        ob = context.active_object
        game = ob.game
        subtype = None

        if ':' in self.MODE:
            mode, subtype = self.MODE.split(':')
            ##BLENDERBUG##ob.game.collision_bounds_type = subtype   # BUG this can not come before
            if subtype in 'BOX SPHERE CYLINDER CONE CAPSULE'.split():
                ob.draw_bounds_type = subtype
            else:
                ob.draw_bounds_type = 'POLYHEDRON'
            ob.game.collision_bounds_type = subtype  # BLENDERBUG - this must come after draw_bounds_type assignment
        else:
            mode = self.MODE
        ob.collision_mode = mode

        if ob.data.show_all_edges:
            ob.data.show_all_edges = False
        if ob.show_texture_space:
            ob.show_texture_space = False
        if ob.show_bounds:
            ob.show_bounds = False
        if ob.show_wire:
            ob.show_wire = False
        for child in ob.children:
            if child.subcollision and not child.hide_viewport:
                child.hide_viewport = True

        if mode == 'NONE':
            game.use_ghost = True
            game.use_collision_bounds = False
        elif mode == 'PRIMITIVE':
            game.use_ghost = False
            game.use_collision_bounds = True
            ob.show_bounds = True
        elif mode == 'MESH':
            game.use_ghost = False
            game.use_collision_bounds = True
            ob.show_wire = True
            if game.collision_bounds_type == 'CONVEX_HULL':
                ob.show_texture_space = True
            else:
                ob.data.show_all_edges = True
        elif mode == 'DECIMATED':
            game.use_ghost = True
            game.use_collision_bounds = False
            game.use_collision_compound = True
            proxy = self.get_subcollisions(ob)[0]
            if proxy.hide_viewport: proxy.hide_viewport = False
            ob.game.use_collision_compound = True  # proxy
            mod = _get_proxy_decimate_mod( ob )
            mod.show_viewport = True
            if not proxy.select:    # ugly (but works)
                proxy.hide_select = False
                proxy.select = True
                proxy.hide_select = True
            if game.collision_bounds_type == 'CONVEX_HULL':
                ob.show_texture_space = True
        elif mode == 'TERRAIN':
            game.use_ghost = True
            game.use_collision_bounds = False
            game.use_collision_compound = True
            proxy = self.get_subcollisions(ob)[0]
            if proxy.hide_viewport:
                proxy.hide_viewport = False
        elif mode == 'COMPOUND':
            game.use_ghost = True
            game.use_collision_bounds = False
            game.use_collision_compound = True
        else:
            assert 0 # unknown mode

        return {'FINISHED'}


from sense_hat import SenseHat
import time
import socket
import gyrodata
import sys

host = '10.44.15.35'
port = 5802

gyrodata.initGetGyroAngle()

gyro_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
gyro_socket.bind((host, port))
print('Socket created')
print('Listening...')
gyro_socket.listen(1)
conn, addr = gyro_socket.accept()
print ("Connected with " + addr[0] + ":" + str(addr[1]))

while 1:
	data = conn.recv(1024)
	print (str(data))
	if data == (b'Requesting Gyro\r\n'):
		gyrodata.sendGyroData(conn)

conn.close

#while 1:
#	data = conn.recv(1024)
#
#	robotAngle = bytes(gyroAngle, 'utf-8')
#	conn.send(robotAngle)
#	print('data sent: ' + gyroAngle)
#	if not data:
#		break

#conn.close


# coding: utf-8

"""Train an ESN with a recursive least squares filter."""

from __future__ import (
    absolute_import,
    division,
    print_function,
    unicode_literals,
)

import logging

import hyperopt
import hyperopt.mongoexp
import numpy as np

from esn import RlsEsn
from esn.activation_functions import lecun
from esn.preprocessing import add_noise
from . import SuperposedSinusoidExample

logger = logging.getLogger(__name__)

class RlsExample(SuperposedSinusoidExample):

    def __init__(self):
        super(RlsExample, self).__init__()

        self.num_training_samples = 10000
        self.num_test_samples = 500

        self.title = 'Superposed sine; RLS; {} samples'.format(
            self.num_training_samples
        )

        self.hyper_parameters = {
            'spectral_radius': 1.11,
            'leaking_rate': 0.75,
            'forgetting_factor': 0.99998,
            'autocorrelation_init': 0.1,
            'bias_scale': -0.4,
            'signal_scale': 1.2,
            'state_noise': 0.004,
            'input_noise': 0.007,
        }

        self.search_space = (
            hyperopt.hp.quniform('spectral_radius', 0, 1.5, 0.01),
            hyperopt.hp.quniform('leaking_rate', 0, 1, 0.01),
            hyperopt.hp.quniform('forgetting_factor', 0.98, 1, 0.0001),
            hyperopt.hp.qloguniform('autocorrelation_init', np.log(0.1), np.log(1), 0.0001),
            hyperopt.hp.qnormal('bias_scale', 1, 1, 0.1),
            hyperopt.hp.qnormal('signal_scale', 1, 1, 0.1),
            hyperopt.hp.quniform('state_noise', 1e-10, 1e-2, 1e-10),
            hyperopt.hp.quniform('input_noise', 1e-10, 1e-2, 1e-10),
        )

    def _load_data(self, offset=False):
        super(RlsExample, self)._load_data(offset)

        # remove every other label
        self.training_outputs[1::2] = np.nan

    def _train(
            self,
            spectral_radius,
            leaking_rate,
            forgetting_factor,
            autocorrelation_init,
            bias_scale,
            signal_scale,
            state_noise,
            input_noise,
    ):
        self.esn = RlsEsn(
            in_size=1,
            reservoir_size=1000,
            out_size=1,
            spectral_radius=spectral_radius,
            leaking_rate=leaking_rate,
            forgetting_factor=forgetting_factor,
            autocorrelation_init=autocorrelation_init,
            state_noise=state_noise,
            sparsity=0.95,
            initial_transients=300,
            squared_network_state=True,
            activation_function=lecun,
        )
        self.esn.W_in *= [bias_scale, signal_scale]

        # train
        self.esn.fit(
            np.array([self.training_inputs[0]]),
            np.array([self.training_outputs[0]])
        )
        for input_date, output_date in zip(
                add_noise(self.training_inputs[1:], input_noise),
                self.training_outputs[1:]
        ):
            if not np.isnan(output_date.item()):
                self.esn.partial_fit(
                    np.array([input_date]),
                    np.array([output_date])
                )
            else:
                # drive reservoir
                self.esn.predict(input_date)

        # test
        predicted_outputs = [self.esn.predict(self.test_inputs[0])]
        for i in range(len(self.test_inputs)-1):
            predicted_outputs.append(self.esn.predict(predicted_outputs[i]))

        return np.array(predicted_outputs)


#
# test_ab.py - generic tests for analysis programs
# repagh <rene.vanpaassen@gmail.com, May 2020

import pytest

from slycot import analysis
from slycot.exceptions import SlycotArithmeticError, SlycotResultWarning

from .test_exceptions import assert_docstring_parse

@pytest.mark.parametrize(
    'fun,              exception_class,       erange,         checkvars',
    ((analysis.ab05nd, SlycotArithmeticError, 1,              {'p1': 1}),
     (analysis.ab07nd, SlycotResultWarning,   2,              {'m': 1}),
     (analysis.ab09ad, SlycotArithmeticError, 3,              {'dico': 'C'}),
     (analysis.ab09ad, SlycotArithmeticError, (2,),           {'dico': 'D'}),
     (analysis.ab09ad, SlycotResultWarning,   ((1, 0), ),     {'nr': 3,
                                                               'Nr': 2}),
     (analysis.ab09ax, SlycotArithmeticError, 2,              {'dico': 'C'}),
     (analysis.ab09ax, SlycotResultWarning,   ((1, 0), ),     {'nr': 3,
                                                               'Nr': 2}),
     (analysis.ab09ad, SlycotArithmeticError, 3,              {'dico': 'C'}),
     (analysis.ab09ad, SlycotResultWarning,   ((1, 0), ),     {'nr': 3,
                                                               'Nr': 2}),
     (analysis.ab09md, SlycotArithmeticError, 3,              {'alpha': -0.1}),
     (analysis.ab09md, SlycotResultWarning,   ((1, 0), (2, 0)), {'nr': 3,
                                                               'Nr': 2,
                                                               'alpha': -0.1}),
     (analysis.ab09nd, SlycotArithmeticError, 3,              {'alpha': -0.1}),
     (analysis.ab09nd, SlycotResultWarning,   ((1, 0), (2, 0)), {'nr': 3,
                                                               'Nr': 2,
                                                               'alpha': -0.1}),
     (analysis.ab13bd, SlycotArithmeticError, 6,              {'dico': 'C'}),
     (analysis.ab13bd, SlycotResultWarning,   ((1, 0),),      {}),
     (analysis.ab13dd, SlycotArithmeticError, 4,              {}),
     (analysis.ab13ed, SlycotArithmeticError, 1,              {}),
     (analysis.ab13fd, SlycotArithmeticError, (2,),           {}),
     (analysis.ab13fd, SlycotResultWarning,   (1,),           {})))
def test_ab_docparse(fun, exception_class, erange, checkvars):
    assert_docstring_parse(fun.__doc__,  exception_class, erange, checkvars)


# Fn = F[n-1]+ F[n-2](n=>2)
def fib(n):
    if n==0 :
        return [0]
    elif n==1 :
        return [0,1]
    else:
        fibs=[0,1,1]
        for i in range(3,n):
            fibs.append(fibs[-1]+fibs[-2])
        return fibs

# 输出了第10个斐波那契数列
print(fib(8))

# a,b=0,1
# while a<1000:
#     print(a,end=",")
#     a,b=b,a+b


from tqdm import tqdm
import time
import argparse

N = int(1e9)
T = 1e-2
MAX_LEN = 100

def parse_args():

    parser = argparse.ArgumentParser(description='i really wanna have a rest.')
    parser.add_argument('-n', '--iters', type=int, default=N, help='rest iters.')
    parser.add_argument('-f', '--frequency', type=float, default=1/T, help='rest frequency per iter.')
    args = parser.parse_args()

    return args

def have_a_rest():

    args = parse_args()
    str_ = ''
    for idx in tqdm(range(args.iters)):

        str_ = str_ + '  '
        if len(str_) > MAX_LEN:
            str_ = str_[MAX_LEN:]
        str_to_print = str_ + 'kaizhong faker'
        if idx % 10 < 5:
            print(str_to_print)
        else:
            print(str_to_print + str_to_print)
        time.sleep(1.0 / args.frequency)

if __name__ == '__main__':

    have_a_rest()


import os
import sys
import argparse
import netaddr
from netaddr import EUI

def _parse_args( args_str):
    parser = argparse.ArgumentParser()
    args, remaining_argv = parser.parse_known_args(args_str.split())
    parser.add_argument(
                "--username", nargs='?', default="admin",help="User name")
    parser.add_argument(
                "--password", nargs='?', default="contrail123",help="password")
    parser.add_argument(
                "--tenant_id", nargs='?', help="trnant id",required=True)
    parser.add_argument(
                "--config_node_port", help="config node port")
    parser.add_argument(
                "--config_node_ip",  help="config node ip",required=True)
    parser.add_argument(
                "--physical_router_id",  help="Physical router id")
    parser.add_argument(
                "--start_mac",  help="Mac address of vcenter vm ",required=True)
    parser.add_argument(
                "--start_vn_name", help="Vn name to launch vmi",required=True)
    parser.add_argument(
                "--start_vlan",  help="Initial vlan",required=True)
    parser.add_argument(
                "--number_of_vlan",  help="number of vlans to be created",required=True)
    parser.add_argument(
                "--auth_url", nargs='?', default="check_string_for_empty",help="Auth Url",required=True)
    args = parser.parse_args(remaining_argv)
    return args

def get_mac_address_iter_obj(mac,start_range,end_range):
    return iter(["{:012X}".format(int(mac, 16) + x) for x in range(int(start_range),int(end_range)+1)])

def get_subnet_iter_obj(subnet='1.1.1.0/24'):
    addr,prefix = subnet.split('/')
    ad1,ad2,ad3,ad4 = addr.split('.')
    return iter([ad1+'.'+str(int(ad2)+x)+'.'+str(int(ad3)+y)+'.'+ad4+'/'+prefix for x in range(1,250) for y in range(1,250)])

def get_subnet_iter_obj_for_static_route(subnet='1.1.1.0/24'):
    addr,prefix = subnet.split('/')
    ad1,ad2,ad3,ad4 = addr.split('.')
    return iter([str(int(ad1)+x)+'.'+ad2+'.'+ad3+'.'+ad4+'/'+prefix for x in range(1,250)])

def get_vn_name(base_vn_name,counter):
    return base_vn_name + str(counter)

def get_vlan_range(start_vlan,numbers):
    vlan_range=[]
    end_vlan= int(start_vlan) + int(numbers)
    for x in range(int(start_vlan),int(end_vlan)+1):
        vlan_range.append(str(x))
    return vlan_range

def main(args_str = None):
    if not args_str:
       script_args = ' '.join(sys.argv[1:])
    script_args = _parse_args(script_args)
    start_vlan = script_args.start_vlan
    number_of_vlan = script_args.number_of_vlan
    vlans = get_vlan_range(start_vlan,number_of_vlan)
    mac = get_mac_address_iter_obj(script_args.start_mac,'0',number_of_vlan)
    subnet = get_subnet_iter_obj()
    static_route_subnet = get_subnet_iter_obj_for_static_route(subnet='2.0.1.0/24')
    for vlan in vlans:
        try:
            m_addr = mac.next()
            sub = subnet.next()
            static_route_sub = static_route_subnet.next()
        except StopIteration:
            return
        vn_name = get_vn_name(script_args.start_vn_name,vlan)
        os.system("python vmi.py --static_route_subnet %s\
                          --tenant_id %s\
                          --config_node_ip %s\
                          --vcenter_vm_mac %s\
                          --vn_name %s\
                          --subnet %s\
                          --auth_url %s"
                          %(static_route_sub,
                           script_args.tenant_id,
                           script_args.config_node_ip,
                           m_addr,vn_name,sub,
                           script_args.auth_url
                           )
                         )

#python vmi_scale.py  --tenant_id 74ebcac4-21da-4fe3-8c7f-e84c9e0424ca --config_node_ip 192.168.192.60 --start_mac 000029572113 --start_vn_name tor_vn_ --start_vlan   6 --number_of_vlan 7 --auth_url http://10.204.217.144:5000/v2.0
if __name__ == "__main__":
    main()


# physic_tank.py

'''
-----------------------------------------------------
function for calculating physics formula

1) Calculate Parameter : Charging Time, Discharging Time
2) Reverse Compute Tank Outlet Temperature
-----------------------------------------------------
'''

'==============================================================================================================================='

import numpy as np

def __init__(self, SWIT, SWOT, LWIT, LWOT, SWF, LWF, SWOT_1min, LOWT_1min, Node10_Heat_Discharg, Node1_Heat_Charg, Tank_ChargStorage, Tank_DischargStorage):
    self.SWIT = SWIT
    self.SWOT = SWOT
    self.LWIT = LWIT
    self.LWOT = LWOT
    self.SWF = SWF
    self.LWF = LWF
    self.Node10_Heat_Discharg = Node10_Heat_Discharg
    self.Tank_ChargStorage = Tank_ChargStorage
    self.Node1_Heat_Charg = Node1_Heat_Charg
    self.Tank_DischargStorage = Tank_DischargStorage
    self.SWOT_1min = SWOT_1min
    self.LOWT_1min = LOWT_1min

'------------------------'
# Parameter Calculate
'------------------------'

# 10 layer's Parmeter (kW - m^3/h)
# charging time
def Charging_para(SWIT, SWOT, SWF):
    charge_para = ((SWOT - SWIT) * 2 * SWF * 1.162) / 10
    return charge_para

# discharging time
def layer10_para(LWIT, SWOT, LFW, Node10_Heat_Discharg):

    layer10parameter = []

    for i, (a, b, c, d) in enumerate(zip(LWIT, SWOT, LFW, Node10_Heat_Discharg)):
        if i == 0:
            layer10para =  d - (c * 1.162 * (a - b))
            if layer10para < 0:
                layer10para = 0
            else:
                layer10para = layer10para
        else:
            layer10para =  d - (c * 1.162 * (a - b))
            if layer10para < 0:
                layer10para = 0
            else:
                layer10para = layer10para

        layer10parameter.append(layer10para)

# 1 layer's Parmeter
# discharging time
def Discharging_para(LWIT, LWOT, LWF):
    discharge_para = ((LWOT - LWIT) * 2 * LWF * 1.162) / -10
    return discharge_para

# charging time
def layer01_para(SWIT, LOWT, SWF, Node1_Heat_Charg):

    layer01parameter = []

    for i, (a, b, c, d) in enumerate(zip(SWIT, LOWT, SWF, Node1_Heat_Charg)):
        if i == 0:
            layer01para =  d - (c * 1.162 * (a - b))
            if layer01para < 0:
                layer01para = 0
            else:
                layer01para = layer01para
        else:
            layer01para =  d - (c * 1.162 * (a - b))
            if layer01para < 0:
                layer01para = 0
            else:
                layer01para = layer01para

        layer01parameter.append(layer01para)

'------------------------'
# Reverse Calculate
'------------------------'

# 10 layer
def Tank_SWOT(SWIT, LWIT, SWOT_1min, Node10_Heat_Discharg, SWF, LWF, Charging_para, layer10para):
    # charging time
    if SWF != 0 and LWF == 0:
        TankSWOT = SWIT + ((1 / (2 * SWF * 1.162)) * Charging_para * 10)
        # discharging time
    elif LWF != 0 and SWF == 0:
        if layer10para == 0:
            TankSWOT = SWOT_1min
        else:
            TankSWOT = LWIT - (Node10_Heat_Discharg / (LWF * 1.162)) + (layer10para / (LWF * 1.162))
    # 100% off
    else:
        TankSWOT = SWOT_1min
    return TankSWOT

# Tank Total Charging Heat Sotrage
def Tank_Charging(SWIT, TankSWOT, SWF, LWF):
    if SWF != 0 and LWF == 0:
        TankCharging = ((SWIT-TankSWOT)*SWF*1000*4.184)
    else:
        TankCharging = 0
    return TankCharging

# 10layer Heat Sotrage
def Tank_10layer_charging(LWIT, TankSWOT, SWF, LWF, layer10para):
    if LWF != 0 and SWF == 0:
        Tank_10layer_charging = ((LWIT - TankSWOT) * LWF * 1.162) + layer10para
    else:
        Tank_10layer_charging = 0
    return Tank_10layer_charging

# 01 layer outlet  temperature
def Tank_LWOT(LWIT, SWIT, LOWT_1min, Node1_Heat_Charg, LWF, SWF, Discharging_para, layer01para):
    # discharging time
    if LWF != 0 and SWF == 0:
        TankLWOT = LWIT + ((1 / (2 * LWF * 1.162)) * Discharging_para * -10)
        # charging time
    elif SWF != 0 and LWF == 0:
        if layer01para == 0:
            TankLWOT = LOWT_1min
        else:
            TankLWOT = SWIT - (Node1_Heat_Charg / (SWF * 1.162)) + (layer01para / (SWF * 1.162))
    # 100% off
    else:
        TankLWOT = LOWT_1min
    return TankLWOT

# Tank Total Discharging Heat Sotrage
def Tank_Discharging(LWIT, TankLWOT, SWF, LWF):
    if LWF != 0 and SWF == 0:
        TankDischarging = ((LWIT-TankLWOT)*LWF*1000*4.184)
    else:
        TankDischarging = 0
    return TankDischarging

# 01layer Heat Sotrage
def Tank_01layer_charging(SWIT, TankLWOT, SWF, LWF, layer01para):
    if SWF != 0 and LWF == 0:
        Tank_01layer_charging = ((SWIT - TankLWOT) * SWF * 1.162) + layer01para
    else:
        Tank_01layer_charging = 0
    return Tank_01layer_charging

'==============================================================================================================================='


import soundfile as sf
import numpy as np
import time
import matplotlib.pyplot as plt

from parameterization import STFT, iSTFT, optimal_synth_window, first_larger_square

DEF_PARAMS = {
    "win_len": 25,
    "win_ovlap": 0.75,
    "blocks": 800,
    "max_h_type": "lin-lin",
    "min_gain_dry": 0,
    "bias": 1.01,
    "alpha": 0.1,
    "gamma": 0.7,
}
TITLES = ["aula1_12", "kitchen_12", "stairway1_1", "test"]
SAMPLES = ["sploty/aula1/aula1_12.wav", "sploty/kitchen/kitchen_12.wav", "sploty/stairway1/stairway1_1.wav", "deverb_test_samples/test_raw.wav"]
TEST_SCOPE = False

def get_max_h_matrix(type, freqs, blocks):
    if type == "log-log":
        return (np.logspace(np.ones(freqs), np.ones(freqs) * np.finfo(np.float32).eps, blocks) *
                np.logspace(np.ones(blocks), np.ones(blocks) * np.finfo(np.float32).eps, freqs).T - 1) / 99
    elif type == "log-lin":
        return (np.logspace(np.ones(freqs), np.ones(freqs) * np.finfo(np.float32).eps, blocks) *
                np.linspace(np.ones(blocks), np.zeros(blocks), freqs).T) / 9
    elif type == "log-full":
        return (np.logspace(np.ones(freqs), np.ones(freqs) * np.finfo(np.float32).eps, blocks) - 1) / 9
    elif type == "lin-log":
        return (np.logspace(np.ones(freqs), np.ones(freqs) * np.finfo(np.float32).eps, blocks) *
                np.logspace(np.ones(blocks), np.ones(blocks) * np.finfo(np.float32).eps, freqs).T - 1) / 9
    elif type == "lin-lin":
        return np.linspace(np.ones(freqs), np.zeros(freqs), blocks) * \
               np.linspace(np.ones(blocks), np.zeros(blocks), freqs).T
    elif type == "lin-full":
        return np.linspace(np.ones(freqs), np.zeros(freqs), blocks)
    else:
        return np.ones((freqs, blocks)).T

def reconstruct(stft, window, overlap):
    frame_count, frequency_count = stft.shape
    sym_stft = np.hstack((stft, np.flipud(np.conj(stft[:, 0:frequency_count - 2]))))
    signal = np.real(iSTFT(sym_stft, window, overlap))
    return signal

def read_impulse_response(path, target_fs, target_bins, win_len, win_ovlap):
    h, h_fs = sf.read(path)
    h /= np.max(np.abs(h))
    nfft = int(target_bins * h_fs / target_fs)

    win_len = int(win_len / 1000 * h_fs)
    win_ovlap = int(win_len * win_ovlap)
    window = np.hanning(win_len)

    H = STFT(h, window, win_ovlap, nfft, power=True)

    return H[:, 0:target_bins // 2 + 1], H.shape[0]

def printProgressBar (iteration, total, prefix='', suffix='', decimals=1, length=100, fill='█', printEnd="\r"):
    """
    Call in a loop to create terminal progress bar
    @params:
        iteration   - Required  : current iteration (Int)
        total       - Required  : total iterations (Int)
        prefix      - Optional  : prefix string (Str)
        suffix      - Optional  : suffix string (Str)
        decimals    - Optional  : positive number of decimals in percent complete (Int)
        length      - Optional  : character length of bar (Int)
        fill        - Optional  : bar fill character (Str)
        printEnd    - Optional  : end character (e.g. "\r", "\r\n") (Str)
    """
    percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
    filledLength = int(length * iteration // total)
    bar = fill * filledLength + '-' * (length - filledLength)
    print(f'\r{prefix} |{bar}| {percent}% {suffix}', end = printEnd)
    # Print New Line on Complete
    if iteration == total:
        print()

def dereverberate(wave, fs, params=None, estimate_execution_time=True, show_progress_bar=True):
    """
    Estimates the impulse response in a room the recording took place

    :param wave: 1-D ndarray of wave samples
    :param fs: int - sampling frequency
    :param params: dict containing the algorithm parameters - keys:
    :param estimate_execution_time: should we print estimated execution time for each next frame
    :param show_progress_bar: should we print progress bar of estimation
    :returns: (h_stft_pow) 2-D ndarray power STFT of h_rir,
              (wave_dry) 1-D ndarray of the dry signal,
              (wave_wet) 1-D ndarray of the wet signal
    """
    # estimating execution time
    loop_times = np.zeros(10)

    # =================== Parameters ===================
    if params is None:
        params = DEF_PARAMS

    # ==================== Windowing ===================
    win_len_ms = params["win_len"]
    win_ovlap_p = params["win_ovlap"]

    # ================ Times to samples ================
    win_len = int(win_len_ms / 1000 * fs)
    win_ovlap = int(win_len * win_ovlap_p)
    window = np.hanning(win_len)

    # =================== Signal stft ==================
    nfft = first_larger_square(win_len)
    sig_stft = STFT(wave, window, win_ovlap, nfft)
    sig_stft = sig_stft[:, 0:nfft // 2 + 1]
    frame_count, frequency_count = sig_stft.shape

    # ==================== Constants ===================
    # length of the impulse response
    blocks = params["blocks"]

    # minimum gain of dry signal per frequency
    min_gain_dry = params["min_gain_dry"]

    # maximum impulse response estimate
    # max_h, blocks = read_impulse_response("deverb_test_samples/stalbans_a_mono.wav", fs, nfft, win_len_ms, win_ovlap_p)
    max_h = get_max_h_matrix('const', frequency_count, blocks)

    # bias used to keep magnitudes from getting stuck on a wrong minimum
    bias = params["bias"]

    # alpha and gamma - smoothing factors for impulse response magnitude and gain
    alpha = params["alpha"]
    gamma = params["gamma"]

    # ==================== Algorithm ===================
    # dry_stft and wet_stft are the estimated dry and reverberant signals in frequency-time domain
    dry_stft = np.zeros((frame_count, frequency_count), dtype=np.csingle)
    wet_stft = np.zeros((frame_count, frequency_count), dtype=np.csingle)

    # h_stft_pow is the estimated impulse response in frequency-time domain
    h_stft_pow = max_h / 2

    # matrices with the information of currently estimated raw and dry signal (power spectra)
    raw_frames = np.ones((blocks, frequency_count))
    dry_frames = np.zeros((blocks, frequency_count))

    # c is a matrix to keep the raw estimated powers of the impulse response
    c = np.zeros((blocks, frequency_count))

    # gain_dry and gain_wet are the frequency gains of the dry and wet signals
    gain_dry = np.ones(frequency_count)
    gain_wet = np.zeros(frequency_count)

    for i in range(frame_count):
        if estimate_execution_time:
            remaining = round(np.mean(loop_times) * (frame_count - i))
            loop_times[1:] = loop_times[0:-1]
            loop_times[0] = time.time()
            print("Processing frame {} of {}, estimated time left: {} ms".format(i + 1, frame_count, remaining))

        frame = sig_stft[i, :]
        frame_power = np.power(np.abs(frame), 2)

        # estimate signals based on i-th frame
        for b in range(blocks):

            estimate = frame_power / raw_frames[b, :]
            np.place(estimate, estimate >= h_stft_pow[b, :], h_stft_pow[b, :] * bias + np.finfo(np.float32).eps)
            np.fmin(estimate, max_h[b, :], out=c[b, :])
            h_stft_pow[b, :] = alpha * h_stft_pow[b, :] + (1 - alpha) * c[b, :]

        # calculating gains
        new_gain_dry = 1 - np.sum(dry_frames * h_stft_pow, axis=0) / frame_power
        np.place(new_gain_dry, new_gain_dry < min_gain_dry, min_gain_dry)
        gain_dry = gamma * gain_dry + (1 - gamma) * new_gain_dry

        new_gain_wet = 1 - gain_dry
        gain_wet = gamma * gain_wet + (1 - gamma) * new_gain_wet

        # calculatnig signals
        dry_stft[i, :] = gain_dry * frame
        wet_stft[i, :] = gain_wet * frame

        # shifting previous frames
        dry_frames[1:blocks, :] = dry_frames[0:blocks - 1, :]
        dry_frames[0, :] = np.power(np.abs(dry_stft[i, :]), 2)

        raw_frames[1:blocks, :] = raw_frames[0:blocks - 1, :]
        raw_frames[0, :] = frame_power

        if estimate_execution_time:
            loop_times[0] = round(1000 * (time.time() - loop_times[0]))
        if show_progress_bar:
            printProgressBar(i, frame_count, prefix='Progress', suffix='Complete', length=30)

    window = optimal_synth_window(window, win_ovlap)

    if TEST_SCOPE:
        t = (np.arange(frame_count) * (win_len_ms * (1 - win_ovlap_p))).astype(int)
        f = np.linspace(0, fs / 2, frequency_count).astype(int)

        txx, fxx = np.meshgrid(t, f)

        fig, axes = plt.subplots(3, 1, figsize=(10, 10))
        axes[0].pcolormesh(txx, fxx, np.log10(np.power(np.abs(sig_stft.T), 2)), cmap=plt.get_cmap('plasma'))
        axes[0].set_title("Original signal")
        axes[1].pcolormesh(txx, fxx, np.log10(np.power(np.abs(dry_stft.T), 2)), cmap=plt.get_cmap('plasma'))
        axes[1].set_title("Dry signal")
        axes[2].pcolormesh(txx, fxx, np.log10(np.power(np.abs(wet_stft.T), 2)), cmap=plt.get_cmap('plasma'))
        axes[2].set_title("Reverberant signal")
        fig.show()

    wave_dry = reconstruct(dry_stft, window, win_ovlap)
    wave_wet = reconstruct(wet_stft, window, win_ovlap)

    return h_stft_pow, wave_dry, wave_wet

def test_deverb():
    for i, item in enumerate(SAMPLES):
    # i = 3
    # item = SAMPLES[3]
        print("Estimating " + item)

        wave, fs = sf.read(item)
        wave = wave / np.max(np.abs(wave))
        H_rir, dry_wav, wet_wav = dereverberate(wave, fs, estimate_execution_time=False)

        min_size = np.min([wave.size, dry_wav.size, wet_wav.size])
        t = np.linspace(0, min_size / fs, min_size)

        fig, axes = plt.subplots(3, 1, figsize=(10, 10))
        fig.suptitle("estimated signals - {} reverb".format(TITLES[i]))
        axes[0].plot(t, wave[0:min_size])
        axes[0].set_title("original")
        axes[1].plot(t, dry_wav[0:min_size])
        axes[1].set_title("dry")
        axes[2].plot(t, wet_wav[0:min_size])
        axes[2].set_title("reverberant")
        axes[2].set_xlabel(r"time $[s]$")
        fig.tight_layout()
        fig.show()

        frames, freqs = H_rir.shape
        hop = DEF_PARAMS["win_len"] * (1 - DEF_PARAMS["win_ovlap"]) / 1000
        f = np.linspace(0, fs / 2000, freqs)
        t = np.linspace(0, hop * frames, frames)
        fxx, txx = np.meshgrid(f, t)

        fig, ax = plt.subplots(figsize=(6, 5))
        ax.pcolormesh(txx, fxx, np.log10(H_rir), cmap=plt.get_cmap('plasma'))
        ax.set_title(r"estimated $H_{rir}$: " + TITLES[i])
        ax.set_xlabel(r"time $[s]$")
        ax.set_ylabel(r"frequency $[kHz]$")
        fig.show()

        with open("tmp/dry_{}.wav".format(TITLES[i]), "wb") as f:
            sf.write(f, dry_wav, fs)
        with open("tmp/wet_{}.wav".format(TITLES[i]), "wb") as f:
            sf.write(f, wet_wav, fs)

if __name__ == "__main__":
    TEST_SCOPE = True
    test_deverb()


import tensorflow as tf
import numpy as np
import sys

class conv3:
  def __init__(self,numfilter):
    self.numfilter=numfilter
    self.filmat=np.random.randn(3,3,numfilter)/9 #to decrease
  def forward(self,input):
    l,b=input.shape
    self.chache_input=input
    #paddedinput=zeros(input.shape[0]+2,input.shape[1]+2)
    #paddedinput[1:input.shape[0]+1,1:input.shape[1]+1]+=input
    out=np.zeros((l-2,b-2,8))
    for i in range(l-2):
      for j in range(b-2):
        for f in range(self.numfilter):
          #dl_dfilter[:,:,f]+=dl_dout[i,j,f]*self.chache_input[i:i+3,j:j+3]
          out[i,j,f]=np.sum(input[i:i+3,j:j+3]*self.filmat[:,:,f],axis=(0,1))
    return out
  def backward(self,dl_dout,learning):
    l,b,h=self.filmat.shape
    dl_dfilter=np.zeros((l,b,h))
    for i in range(l-2):
      for j in range(b-2):
        for f in range(h):
          dl_dfilter[:,:,f]+=dl_dout[i,j,f]*self.chache_input[i:i+3,j:j+3]

    self.filmat-=learning*dl_dfilter
    return None

class maxpool2:
  def forward(self,input):
    l,b,h=input.shape
    self.chache_input=input
    out=np.zeros((l//2,b//2,h))
    for i in range(l//2):
      for j in range(b//2):
        out[i,j,:]=np.amax(input[2*i:2*i+2,2*j:2*j+2,:],axis=(0,1))
    return out
  def backward(self,gradient):
    l,b,h=self.chache_input.shape
    dl_dinput=np.zeros((l,b,h))
    for i in range(l//2):
      for j in range(b//2):
        for k in range(h):
          amaxi=np.amax(self.chache_input[2*i:2*i+2,2*j:2*j+2,k],axis=(0,1))
          if self.chache_input[2*i,2*j,k]==amaxi :
            dl_dinput[2*i,2*j,k]=gradient[i,j,k]
          elif self.chache_input[2*i+1,2*j,k]==amaxi :
            dl_dinput[2*i+1,2*j,k]=gradient[i,j,k]
          elif self.chache_input[2*i,2*j+1,k]==amaxi :
            dl_dinput[2*i,2*j+1,k]=gradient[i,j,k]
          elif self.chache_input[2*i+1,2*j+1,k]==amaxi :
            dl_dinput[2*i+1,2*j+1,k]=gradient[i,j,k]
    return dl_dinput

class Softmax:
  def __init__(self,input_length,nodes):
    self.weights=np.random.randn(input_length,nodes)/input_length     #1
    self.biases = np.zeros(nodes)
  def forward(self,input):
    self.chache_shape=input.shape
    input=input.flatten()
    self.chache_input=input
    input_len, nodes = self.weights.shape
    total=np.dot(input,self.weights)+self.biases
    total=total.astype(np.float128)
    # self.chache_total=tot
    #total=tota/np.amax(tota)
    ex=np.exp(total)
    self.chache_prob=ex/np.sum(ex,axis=0)     #2
    return self.chache_prob
  def backward(self , dl_dout,learning,label): #gradient is dl_dout

    dout_dt=-(self.chache_prob)*self.chache_prob[label]
    dout_dt[label]+=self.chache_prob[label]

    dl_dt= dl_dout * dout_dt   #dl/dt=dl/dout * dout/dt

    #totals=input*weight+bias
    dt_db=1
    dt_dinput=self.weights
    dt_dw=self.chache_input

    #dl/dinput=dl/dt*dt/dinput
    dl_dinput= dt_dinput @ dl_dt
    #dl/dw=dl/dt*dt/dw
    dl_dw=dt_dw[np.newaxis].T @ dl_dt[np.newaxis]
    #dl/db=dl/dt*dt/db (dt/db=1)
    dl_db=dl_dt

    #print(learning)
    self.weights-=learning * dl_dw
    self.biases-=learning * dl_db

    return dl_dinput.reshape(self.chache_shape)

# Data initialisation
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
print([i.shape for i in (x_train, y_train, x_test, y_test)])

#taking only 2000 examples

x_train=x_train[0:1000]
y_train=y_train[0:1000]
x_test, y_test=x_test[0:1000], y_test[:1000]
numfilter=8
conv = conv3(8)                  #8 layer filters
pool = maxpool2()                  # 26x26x8 -> 13x13x8 ,pool size=2
softmax  = Softmax(13 * 13 * 8, 10) # 13x13x8 -> 10  ,10nodes

def forward(image, label):
  out = conv.forward((image / 255) - 0.5)
  out = pool.forward(out)
  out = softmax.forward(out)
  # Calculate cross-entropy loss and accuracy. np.log() is the natural log.
  loss = -np.log(out[label])
  acc = 1 if np.argmax(out) == label else 0
  return out, loss, acc

def train(image,label,learning):
  lr=learning
  out, loss, acc=forward(image,label) #array with probability , 10*1
  gradient=np.zeros(10)
  if out[label]!=0:
    gradient[label]=-1/out[label]    #3
  gradient=softmax.backward( gradient,learning,label )
  gradient=pool.backward(gradient)
  gradient=conv.backward(gradient,lr)

  return loss,acc

print('MNIST CNN initialized!')

loss = 0
num_correct = 0
for j in range(1,4):
  print("training round %d"%(j))
  permut=np.random.permutation(len(x_train))
  x_train=x_train[permut]
  y_train=y_train[permut]
  for i, (im, label) in enumerate(zip(x_train, y_train)):
    # Do a forward pass.

    # Print stats every 100 steps.
    if i % 100 == 99:
      print(
        '[Step %d] Past 100 steps: Average Loss %.3f | Accuracy: %d%%' %
        (i + 1, loss / 100, num_correct)
      )
      loss = 0
      num_correct = 0

    l, acc = train(im, label,0.005)
    loss += l
    num_correct += acc
loss = 0
num_correct = 0
for i, (im, label) in enumerate(zip(x_test, y_test)):
  # Do a forward pass.
  _, l, acc = forward(im, label)
  loss += l
  num_correct += acc
#num_tests = len(x_test)
print('Test Loss:', loss / 1000)
print('Test Accuracy:', num_correct / 1000)


import logging
from logging.handlers import TimedRotatingFileHandler
import os

server_logger = logging.getLogger('server')
PATH = os.path.dirname(os.path.abspath(__file__))
PATH = os.path.join(PATH, 'server.log')
formatter = logging.Formatter(
    '%(asctime)s %(levelname)-8s %(funcName)s %(message)s',
    datefmt='%Y %b %d %H:%M:%S',
)

file_hand = logging.handlers.TimedRotatingFileHandler(
    filename=PATH, when='D', interval=1, encoding='utf-8', delay=True,
    backupCount=31, atTime=None
)

file_hand.setFormatter(formatter)
file_hand.setLevel(logging.DEBUG)

server_logger.addHandler(file_hand)
server_logger.setLevel(logging.DEBUG)

if __name__ == '__main__':
    console = logging.StreamHandler()
    console.setLevel(logging.DEBUG)
    console.setFormatter(formatter)
    server_logger.addHandler(console)
    server_logger.info('Тестовый запуск логирования')


###############################
####### SETUP (OVERALL) #######
###############################

## Import statements
# Import statements
import os
from flask import Flask, render_template, session, redirect, url_for, flash, request
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, RadioField, ValidationError # Note that you may need to import more here! Check out examples that do what you want to figure out what.
from wtforms.validators import Required, Length # Here, too
from flask_sqlalchemy import SQLAlchemy
import json
import requests

## App setup code
app = Flask(__name__)
app.debug = True
app.use_reloader = True
app.config['SECRET_KEY'] = 'pokemonpokemon'
## All app.config values
app.config["SQLALCHEMY_DATABASE_URI"] = "postgresql://localhost/Midterm-katmazan"
## Provided:
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

## Statements for db setup (and manager setup if using Manager)
db = SQLAlchemy(app)

######################################
######## HELPER FXNS (If any) ########
######################################

##################
##### MODELS #####
##################

class Name(db.Model):
    __tablename__ = "names"
    id = db.Column(db.Integer,primary_key=True)
    name = db.Column(db.String)
    height_value = db.Column(db.Integer, db.ForeignKey('heights.id'))
    weight_value = db.Column(db.Integer, db.ForeignKey('weights.id'))
    def __repr__(self):
        return ('{' + str(self.name) + '} | ID: {' + str(self.id) + '}')
class Height(db.Model):
    __tablename__ = 'heights'
    id = db.Column(db.Integer, primary_key=True)
    poke_height = db.Column(db.Integer)
    poke_name = db.Column(db.String)
    names = db.relationship('Name',backref='Height')

class Weight(db.Model):
    __tablename__ = 'weights'
    id = db.Column(db.Integer,primary_key=True)
    poke_name = db.Column(db.String)
    poke_weight = db.Column(db.Integer)
    names = db.relationship('Name',backref='Weight')
###################
###### FORMS ######
###################

class NameForm(FlaskForm):
    name = StringField("Pokemon_name",validators=[Required()])
    submit = SubmitField()
    def validate_name(self, field):
        if len(field.data) <= 1:
            raise ValidationError('Pokemon does not exist')

class FavoriteForm(FlaskForm):
    fav_name = StringField("Add one of your favorite Pokemon:")
    nick_name = StringField("Give your favorite a nickname:")
    submit = SubmitField()
    def validate_nick_name(self,field):
        if field.data[-1] != 'y':
            raise ValidationError("Your nickname must end in y!")
class RankForm(FlaskForm):
    name = StringField('Enter a Pokemon name:', validators = [Required()])
    rate = RadioField('Rate this pokemon in terms of how powerful you think it is', choices = [('1', '1 (low)'), ('2', '2'), ('3', '3 (high)')])
    submit = SubmitField('Submit')

#######################
###### VIEW FXNS ######
#######################
@app.errorhandler(404)
def page_not_found(e):
    return render_template('404_error.html'), 404

@app.route('/', methods = ['GET', 'POST'])
def home():
    form = NameForm() # User should be able to enter name after name and each one will be saved, even if it's a duplicate! Sends data with GET

    if form.validate_on_submit():
        poke_name = form.name.data
        pokemon = Name.query.filter_by(name=poke_name).first()
        ##only adds pokemon if it is not in database
        if not pokemon:

            params = {}
            params['name'] = str(poke_name)

            print(params)

            response = requests.get('http://pokeapi.co/api/v2/pokemon/' + params['name'] + '/')
            ##if response.status_code != '200':
                ##return("The data you entered was not available in the data, check spelling")

            poke_height = int(json.loads(response.text)['height'])
            new_height = Height(poke_height = poke_height, poke_name = poke_name)
            db.session.add(new_height)
            db.session.commit()

            poke_weight = int(json.loads(response.text)['weight'])
            new_weight = Weight(poke_weight = poke_weight, poke_name = poke_name)
            db.session.add(new_weight)
            db.session.commit()
            print('hello')

            newname = Name(name = poke_name, height_value = new_height.id, weight_value = new_weight.id)
            db.session.add(newname)
            db.session.commit()

            return redirect(url_for('all_names'))
    errors = [v for v in form.errors.values()]
    if len(errors) > 0:
        flash("!!!! ERRORS IN FORM SUBMISSION - " + str(errors))
    return render_template('base.html',form=form)

@app.route('/names')
def all_names():
    names = Name.query.all()
    return render_template('name_example.html',names=names)

@app.route('/tallest')
def tallest_pokemon():
    all_heights = Height.query.all()
    tallest_pokemon = 0
    for h in all_heights:
        height = h.poke_height
        if height > tallest_pokemon:
            tallest_pokemon = height
            tp = h
    tallest = tp.poke_name
    height = tp.poke_height

    return render_template('tallest_pokemon.html', tallest = tallest, height = height, names = all_heights)

@app.route('/heaviest')
def heaviest_pokemon():
    all_weights = Weight.query.all()
    heaviest_pokemon = 0
    for w in all_weights:
        weight = w.poke_weight
        if weight > heaviest_pokemon:
            heaviest_pokemon = weight
            hp = w
    heaviest = hp.poke_name
    weight = hp.poke_weight

    return render_template('heaviest.html', heaviest = heaviest, weight = weight, names = all_weights)

@app.route('/favorite_pokemon')
def favorite_form():
    form = FavoriteForm()
    return render_template('favorite_form.html', form = form)

@app.route('/fav_answers',methods=["GET","POST"])
def show_favs():
    form = FavoriteForm()
    if request.args:
        fav_name = form.fav_name.data
        nickname = form.nick_name.data

        return render_template('fav_results.html',fav_name=fav_name, nick_name=nickname)

    flash(form.errors)
    return redirect(url_for('favorite_form'))

## Code to run the application...

# Put the code to do so here!
# NOTE: Make sure you include the code you need to initialize the database structure when you run the application!
if __name__ == '__main__':
    db.create_all() # Will create any defined models when you run the application
    app.run(use_reloader=True,debug=True) # The usual


#Link: https://leetcode.com/problems/kth-largest-element-in-an-array/
# Name: Kth Largest Element in an Array
# Difficulty: Medium
# Topic: Min Heap
#Time: O(n log k) since we update the root a maximum of n times, each update is a log k operation
#Space: O(k) for size of heap used
import heapq
class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        if(k > len(nums)):
            return

        #Initialize Heap
        minHeap = []
        heapq.heapify(minHeap)
        for i in range(k):
            heapq.heappush(minHeap, nums[i])
        #Update heap
        for i in range(k, len(nums)):
            root = minHeap[0]
            if(nums[i] >= root):
                removed = heapq.heappop(minHeap)
                heapq.heappush(minHeap, nums[i])
        #return lowest number in heap
        return heapq.heappop(minHeap)


#! /usr/bin/env python
#
# Implementation of elliptic curves, for cryptographic applications.
#
# This module doesn't provide any way to choose a random elliptic
# curve, nor to verify that an elliptic curve was chosen randomly,
# because one can simply use NIST's standard curves.
#
# Notes from X9.62-1998 (draft):
#   Nomenclature:
#     - Q is a public key.
#     The "Elliptic Curve Domain Parameters" include:
#     - q is the "field size", which in our case equals p.
#     - p is a big prime.
#     - G is a point of prime order (5.1.1.1).
#     - n is the order of G (5.1.1.1).
#   Public-key validation (5.2.2):
#     - Verify that Q is not the point at infinity.
#     - Verify that X_Q and Y_Q are in [0,p-1].
#     - Verify that Q is on the curve.
#     - Verify that nQ is the point at infinity.
#   Signature generation (5.3):
#     - Pick random k from [1,n-1].
#   Signature checking (5.4.2):
#     - Verify that r and s are in [1,n-1].
#
# Version of 2008.11.25.
#
# Revision history:
#    2005.12.31 - Initial version.
#    2008.11.25 - Change CurveFp.is_on to contains_point.
#
# Written in 2005 by Peter Pearson and placed in the public domain.

from __future__ import division

from .six import print_
from . import numbertheory

class CurveFp( object ):
  """Elliptic Curve over the field of integers modulo a prime."""
  def __init__( self, p, a, b ):
    """The curve of points satisfying y^2 = x^3 + a*x + b (mod p)."""
    self.__p = p
    self.__a = a
    self.__b = b

  def p( self ):
    return self.__p

  def a( self ):
    return self.__a

  def b( self ):
    return self.__b

  def contains_point( self, x, y ):
    """Is the point (x,y) on this curve?"""
    return ( y * y - ( x * x * x + self.__a * x + self.__b ) ) % self.__p == 0

class Point( object ):
  """A point on an elliptic curve. Altering x and y is forbidding,
     but they can be read by the x() and y() methods."""
  def __init__( self, curve, x, y, order = None ):
    """curve, x, y, order; order (optional) is the order of this point."""
    self.__curve = curve
    self.__x = x
    self.__y = y
    self.__order = order
    # self.curve is allowed to be None only for INFINITY:
    if self.__curve: assert self.__curve.contains_point( x, y )
    if order: assert self * order == INFINITY

  def __eq__( self, other ):
    """Return True if the points are identical, False otherwise."""
    if self.__curve == other.__curve \
       and self.__x == other.__x \
       and self.__y == other.__y:
      return True
    else:
      return False

  def __add__( self, other ):
    """Add one point to another point."""

    # X9.62 B.3:

    if other == INFINITY: return self
    if self == INFINITY: return other
    assert self.__curve == other.__curve
    if self.__x == other.__x:
      if ( self.__y + other.__y ) % self.__curve.p() == 0:
        return INFINITY
      else:
        return self.double()

    p = self.__curve.p()

    l = ( ( other.__y - self.__y ) * \
          numbertheory.inverse_mod( other.__x - self.__x, p ) ) % p

    x3 = ( l * l - self.__x - other.__x ) % p
    y3 = ( l * ( self.__x - x3 ) - self.__y ) % p

    return Point( self.__curve, x3, y3 )

  def __mul__( self, other ):
    """Multiply a point by an integer."""

    def leftmost_bit( x ):
      assert x > 0
      result = 1
      while result <= x: result = 2 * result
      return result // 2

    e = other
    if self.__order: e = e % self.__order
    if e == 0: return INFINITY
    if self == INFINITY: return INFINITY
    assert e > 0

    # From X9.62 D.3.2:

    e3 = 3 * e
    negative_self = Point( self.__curve, self.__x, -self.__y, self.__order )
    i = leftmost_bit( e3 ) // 2
    result = self
    # print_("Multiplying %s by %d (e3 = %d):" % ( self, other, e3 ))
    while i > 1:
      result = result.double()
      if ( e3 & i ) != 0 and ( e & i ) == 0: result = result + self
      if ( e3 & i ) == 0 and ( e & i ) != 0: result = result + negative_self
      # print_(". . . i = %d, result = %s" % ( i, result ))
      i = i // 2

    return result

  def __rmul__( self, other ):
    """Multiply a point by an integer."""

    return self * other

  def __str__( self ):
    if self == INFINITY: return "infinity"
    return "(%d,%d)" % ( self.__x, self.__y )

  def double( self ):
    """Return a new point that is twice the old."""

    if self == INFINITY:
      return INFINITY

    # X9.62 B.3:

    p = self.__curve.p()
    a = self.__curve.a()

    l = ( ( 3 * self.__x * self.__x + a ) * \
          numbertheory.inverse_mod( 2 * self.__y, p ) ) % p

    x3 = ( l * l - 2 * self.__x ) % p
    y3 = ( l * ( self.__x - x3 ) - self.__y ) % p

    return Point( self.__curve, x3, y3 )

  def x( self ):
    return self.__x

  def y( self ):
    return self.__y

  def curve( self ):
    return self.__curve

  def order( self ):
    return self.__order

# This one point is the Point At Infinity for all purposes:
INFINITY = Point( None, None, None )

def __main__():

  class FailedTest(Exception): pass
  def test_add( c, x1, y1, x2,  y2, x3, y3 ):
    """We expect that on curve c, (x1,y1) + (x2, y2 ) = (x3, y3)."""
    p1 = Point( c, x1, y1 )
    p2 = Point( c, x2, y2 )
    p3 = p1 + p2
    print_("%s + %s = %s" % ( p1, p2, p3 ), end=' ')
    if p3.x() != x3 or p3.y() != y3:
      raise FailedTest("Failure: should give (%d,%d)." % ( x3, y3 ))
    else:
      print_(" Good.")

  def test_double( c, x1, y1, x3, y3 ):
    """We expect that on curve c, 2*(x1,y1) = (x3, y3)."""
    p1 = Point( c, x1, y1 )
    p3 = p1.double()
    print_("%s doubled = %s" % ( p1, p3 ), end=' ')
    if p3.x() != x3 or p3.y() != y3:
      raise FailedTest("Failure: should give (%d,%d)." % ( x3, y3 ))
    else:
      print_(" Good.")

  def test_double_infinity( c ):
    """We expect that on curve c, 2*INFINITY = INFINITY."""
    p1 = INFINITY
    p3 = p1.double()
    print_("%s doubled = %s" % ( p1, p3 ), end=' ')
    if p3.x() != INFINITY.x() or p3.y() != INFINITY.y():
      raise FailedTest("Failure: should give (%d,%d)." % ( INFINITY.x(), INFINITY.y() ))
    else:
      print_(" Good.")

  def test_multiply( c, x1, y1, m, x3, y3 ):
    """We expect that on curve c, m*(x1,y1) = (x3,y3)."""
    p1 = Point( c, x1, y1 )
    p3 = p1 * m
    print_("%s * %d = %s" % ( p1, m, p3 ), end=' ')
    if p3.x() != x3 or p3.y() != y3:
      raise FailedTest("Failure: should give (%d,%d)." % ( x3, y3 ))
    else:
      print_(" Good.")

  # A few tests from X9.62 B.3:

  c = CurveFp( 23, 1, 1 )
  test_add( c, 3, 10, 9, 7, 17, 20 )
  test_double( c, 3, 10, 7, 12 )
  test_add( c, 3, 10, 3, 10, 7, 12 )	# (Should just invoke double.)
  test_multiply( c, 3, 10, 2, 7, 12 )

  test_double_infinity(c)

  # From X9.62 I.1 (p. 96):

  g = Point( c, 13, 7, 7 )

  check = INFINITY
  for i in range( 7 + 1 ):
    p = ( i % 7 ) * g
    print_("%s * %d = %s, expected %s . . ." % ( g, i, p, check ), end=' ')
    if p == check:
      print_(" Good.")
    else:
      raise FailedTest("Bad.")
    check = check + g

  # NIST Curve P-192:
  p = 6277101735386680763835789423207666416083908700390324961279
  r = 6277101735386680763835789423176059013767194773182842284081
  #s = 0x3045ae6fc8422f64ed579528d38120eae12196d5L
  c = 0x3099d2bbbfcb2538542dcd5fb078b6ef5f3d6fe2c745de65
  b = 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1
  Gx = 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012
  Gy = 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811

  c192 = CurveFp( p, -3, b )
  p192 = Point( c192, Gx, Gy, r )

  # Checking against some sample computations presented
  # in X9.62:

  d = 651056770906015076056810763456358567190100156695615665659
  Q = d * p192
  if Q.x() != 0x62B12D60690CDCF330BABAB6E69763B471F994DD702D16A5:
    raise FailedTest("p192 * d came out wrong.")
  else:
    print_("p192 * d came out right.")

  k = 6140507067065001063065065565667405560006161556565665656654
  R = k * p192
  if R.x() != 0x885052380FF147B734C330C43D39B2C4A89F29B0F749FEAD \
     or R.y() != 0x9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835:
    raise FailedTest("k * p192 came out wrong.")
  else:
    print_("k * p192 came out right.")

  u1 = 2563697409189434185194736134579731015366492496392189760599
  u2 = 6266643813348617967186477710235785849136406323338782220568
  temp = u1 * p192 + u2 * Q
  if temp.x() != 0x885052380FF147B734C330C43D39B2C4A89F29B0F749FEAD \
     or temp.y() != 0x9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835:
    raise FailedTest("u1 * p192 + u2 * Q came out wrong.")
  else:
    print_("u1 * p192 + u2 * Q came out right.")

if __name__ == "__main__":
  __main__()


import os
import sys
import glob
import argparse

from lsdo_viz.problem import Problem
from lsdo_viz.utils import clean, get_viz, get_args, exec_python_file

def main_viz(args=None):
    if args is None:
        args = sys.argv[1:]

    parser = argparse.ArgumentParser()
    parser.add_argument('args_file_name', nargs='?', default='viz_args.py')
    parser.add_argument('--clean_data', '-cd', nargs='?', default=None, const=True)
    parser.add_argument('--clean_frames', '-cf', nargs='?', default=None, const=True)
    parser.add_argument('--viz_initial', '-vi', nargs='?', default=None, const=True)
    parser.add_argument('--viz_final', '-vf', nargs='?', default=None, const=True)
    parser.add_argument('--viz_initial_show', '-vis', nargs='?', default=None, const=True)
    parser.add_argument('--viz_final_show', '-vfs', nargs='?', default=None, const=True)
    parser.add_argument('--viz_all', '-va', nargs='?', default=None, const=True)
    parser.add_argument('--movie', '-m', nargs='?', default=None, const=True)
    parsed_args = parser.parse_args(args)

    args = get_args(parsed_args.args_file_name)

    show = parsed_args.viz_initial_show or parsed_args.viz_final_show

    if not show:
        import matplotlib
        matplotlib.use('Agg')

    if parsed_args.clean_data:
        clean(args.data_dir)

    if parsed_args.clean_frames:
        clean(args.frames_dir)

    modes = []
    if parsed_args.viz_initial or parsed_args.viz_initial_show:
        modes.append('viz_initial')
    if parsed_args.viz_final or parsed_args.viz_final_show:
        modes.append('viz_final')
    if parsed_args.viz_all:
        modes.append('viz_all')
    if parsed_args.movie:
        modes.append('movie')

    Problem.args = args
    Problem.viz = get_viz(args.viz_file_name)
    Problem.viz.args = args
    Problem.viz.show = show

    for mode in modes:
        Problem.mode = mode

        exec_python_file(args.run_file_name)


#Create a gspread class and extract the data from the sheets
#requires:
# 1. Google API credentials json_key file path
# 2. scope e.g. ['https://spreadsheets.google.com/feeds','https://www.googleapis.com/auth/drive']
# 3. gspread_url e.g. 'https://docs.google.com/spreadsheets/d/1itaohdPiAeniCXNlntNztZ_oRvjh0HsGuJXUJWET008/edit?usp=sharing'

import gspread
from oauth2client.service_account import ServiceAccountCredentials
import pandas as pd

class gspread_obj(object):
    """
    Create a google spreadsheet instance to download sheet(s) and merge them
    Requires spreadsheet url and Google API json key file

    Examples:
        >>>> gc = gspread_obj()

        >>>> gc.login('home/user/google_api_key.json')

        >>>> gc.get_sheets('https://docs.google.com/spreadsheets/d/1itaohdPiAeniCXNlntNztZ_oRvjh0HsGuJXUJWET008/edit?usp=sharing')

        >>>> df = gc.merge_sheets()

    """
    def __init__(self):
        self.scope = ['https://spreadsheets.google.com/feeds','https://www.googleapis.com/auth/drive']
        self.client = None # gspread.Client object
        self.sheets = None

    def login(self, credentials_google: str):
        #set Google spreadsheet credentials
        credentials = ServiceAccountCredentials.from_json_keyfile_name(credentials_google, self.scope)
        self.client = gspread.authorize(credentials)

    def get_sheets(self, gspread_url: str):
        #Get Google sheet instance
        wks = self.client.open_by_url(gspread_url)
        self.sheets = wks.worksheets()

    def merge_sheets(self):
        if self.sheets is None:
            print('No sheets are found!')
            df = None

        elif len(self.sheets)==1:
            data = self.sheets[0].get_all_values()
            header = data.pop(0)
            df = pd.DataFrame(data, columns=header)

        elif len(self.sheets)>1:
            #read all the sheets
            df_list = []
            for s in self.sheets:
                data = s.get_all_values()
                header = data.pop(0)
                df = pd.DataFrame(data, columns=header)
                df_list.append(df)
            df = pd.concat(df_list, axis=0, join='outer', sort=False)

        else:
            print("self.sheets must be a list of sheet(s)!")
            df = None

        if df is not None:
            print("Columns: ", df.columns)
            print("{} Rows x {} Columns".format(df.shape[0],df.shape[1]))
        return df


import numpy as np
import pandas as pd
import math
import json
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns

import warnings
warnings.filterwarnings('ignore')

import optuna

def create_data(f1, f2, A1, A2, sigma=0.02):
    outs = []
    ts = 1000
    theta1 = 1.4
    theta2 = 1.0
    for t in range(ts):
        # if t == 500:
        #     theta1 = 1.4
        #     theta2 = -0.5
        # elif t == 1500:
        #     theta1 = 0.7
        #     theta2 = 0.0
        n_f1 = np.random.normal(0.0, 0.05)
        n_f2 = np.random.normal(0.0, 0.05)
        val = A1*math.sin(f1*t+theta1+n_f1) + A2*math.sin(f2*t+theta2+n_f2) + np.random.normal(0.0, sigma)
        outs.append(val)
    return np.array(outs)

def sigmoid(x):
    return 1.0 / (1.0 + np.exp(-x))

def relu(x):
    if x > 0:
        return x
    else:
        return 0.

### EKF
def predict_phase(x_vec, P_mat, J_s=np.eye(2), dw=np.array([0.01, 0.1]), Q_t=np.ones((2,2))):
    # J_s: Jacobian
    x_hat = x_vec + dw
    P_hat = np.matmul(np.matmul(J_s,P_mat),J_s.T) + Q_t
    return x_hat, P_hat

def update_phase(obs, x_hat, P_hat, x_vec, P_mat, w_vec, R_t=np.eye(2)):
    y_error = obs - (np.sin(x_hat[0])+0.3*np.sin(x_hat[1]))
    w_err = np.array([np.tanh(y_error*w_vec[0]), np.tanh(y_error*w_vec[1]), np.tanh(y_error*w_vec[2]), np.tanh(y_error*w_vec[3])])
    alpha = sigmoid(np.dot(w_err, w_vec[4:]))
    J_o = np.array([np.cos(x_hat[0]), 0.3*np.cos(x_hat[1])]) # Jacobian
    S_t = np.matmul(np.matmul(J_o, P_hat), J_o.T) + R_t
    K_t = np.matmul(np.matmul(P_hat, J_o.T), np.linalg.inv(S_t)) # Kalman Gain
    K_t = K_t*np.array([alpha, 1.-alpha])
    new_x_vec = x_vec + K_t*y_error
    new_P_mat = np.matmul((np.eye(2) - np.matmul(K_t, J_o)), P_hat)
    return new_x_vec, new_P_mat, y_error, alpha, K_t

ys = create_data(f1=0.01, f2=0.1, A1=1.0, A2=0.3, sigma=0.05)

# w_dict = {'w1': 0.8654948627671226, 'w2': -1.7444762795695032, 'w3': -1.256158244213108, 'w4': 2.9877172040880846, 'w5': 0.7674940690302532, 'w6': -0.5751565428986629, 'w7': -2.1525316155059886, 'w8': -1.593668210140296}
w_dict = {'w1': 0.8868339845276003, 'w2': -2.4239527390853723, 'w3': 2.5663446991064536, 'w4': -1.835679959314501, 'w5': 2.668697875044799, 'w6': -0.578802425496894, 'w7': -2.3135794565999737, 'w8': -0.9460572459969298}
w1 = w_dict['w1']
w2 = w_dict['w2']
w3 = w_dict['w3']
w4 = w_dict['w4']
w5 = w_dict['w5']
w6 = w_dict['w6']
w7 = w_dict['w7']
w8 = w_dict['w8']
W_1 = np.array([w1, w2, w3, w4, w5, w6, w7, w8])

x_vec = np.array([0.0, 0.0])
P_mat = np.eye(2)

total_err = 0.0
alphas = []
y_errors = []
preds = []
k_gains = []
ttt = 1
for _y in ys[1:]:
    x_hat, P_hat = predict_phase(x_vec, P_mat)
    new_x_vec, new_P_mat, y_error, _alpha, K_t = update_phase(_y, x_hat, P_hat, x_vec, P_mat, W_1)
    x_vec = new_x_vec
    P_mat = new_P_mat
    total_err = total_err + np.sqrt(y_error*y_error)
    alphas.append(_alpha)
    y_errors.append(np.abs(y_error))
    preds.append(np.sin(x_vec[0])+0.3*np.sin(x_vec[1]))
    k_gains.append(K_t.tolist())
    # print(ttt, y_error, _alpha)
    ttt = ttt + 1
total_err = total_err/float(len(ys[1:]))

with open("./data/json/test_ekf_no_alpha5.json", "w") as f:
    out_dict = {
        "k_gain": k_gains,
        # "alphas": alphas,
        "y_errors": y_errors,
        "ys": ys[1:].tolist(),
        "preds": preds
    }
    json.dump(out_dict, f)

# print(alphas)
# print(y_errors)
# print(ys[1:].tolist())
# print(preds)


import os
import cv2
import numpy as np
import faceRecognition as fr
import HumanDetection as hd
import time
from playsound import playsound

#variabel status ruangan. 0 = empty, 1 = uknown, 2 = known
status = 0
#variabel timestamp
tsk = [0,0,0,False] #untuk durasi status known, mendeteksi ruang kosong (isempty)
tsu = [0,0,0,False] #untuk durasi status unkown

#Merupakan bagian untuk load data training dan capture video dari sumber
face_recognizer = cv2.face.LBPHFaceRecognizer_create()
face_recognizer.read('trainingData.yml')#Load data training yang sudah tersimpan sebelumnya

name = {0 : "TestImages", 1 : "Ronalod", 2 : "Faruq", 3 : "Fadhil", 4 : "Unknown"}
#Nama Video untuk presentasi final
# known1 -> known, isempty
# coba14 -> unknown alarm
# coba 16 -> unknown alarm
# CekFadhilFaruqNaila1 -> deteksi beberapa orang sekaligus
filename = '\coba16'
hog = hd.initiate()
cap=cv2.VideoCapture('D:\Bahan Kuliah\PyCharm Projects\FaceRecog\Video'+ filename +'.mp4')
fps_read = cap.get(cv2.CAP_PROP_FPS)
print("Input Video FPS :",fps_read)
height = int( cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
print("Input Video Frame Size : ",width," x ",height)
out = cv2.VideoWriter(
    'output '+ 'coba16' +'.avi',
    cv2.VideoWriter_fourcc(*'MJPG'),
    fps_read,
    (640,480))

while (cap.isOpened()):

    ret,test_img=cap.read()#capture frame dari video dan mengembalikan 2 nilai yaitu gambar dan nilai boolean dari gambar
    if ret :
        # Resizing Image for faster detection
        resized_img = cv2.resize(test_img, (640, 480))
        #resized_img = test_img
        timer = cv2.getTickCount()
        if status == 0 or status == 1: #apabila status sebelumnya empty atau unknown

            faces_detected,gray_img=fr.faceDetection(resized_img)
            #print("faces_detected:",faces_detected)

            for (x,y,w,h) in faces_detected:
                cv2.rectangle(resized_img,(x,y),(x+w,y+h),(0,0,255),thickness=2) #menggambar kotak untuk wajah

                #cv2.imshow('face detection Tutorial ',resized_img)

            for face in faces_detected:
                (x,y,w,h)=face
                roi_gray=gray_img[y:y+w, x:x+h]
                label,confidence=face_recognizer.predict(roi_gray)#Memprediksi identitas wajah
                print("confidence:",confidence)
                print("label:",label)
                fr.draw_rect(resized_img,face)
                predicted_name=name[label]
                if confidence < 80: #Jika confidence kecil dari 80 maka print identitas wajah
                    fr.put_text(resized_img,predicted_name,x,y)
                    status = 2 #ubah status jadi known
                else:
                    predicted_name=name[4]
                    fr.put_text(resized_img,predicted_name,x,y)
                    status = 1 #ubah status jadi uknown

        if status == 0 or status == 1 :
            regions = hd.detect(hog, resized_img, (4,4), (4, 4), 1.2)
            hd.boxes(resized_img, regions)
            if len(regions) !=0 : #terdeteksi manusia
                if status == 0 :
                    status = 1
                print('Human Detected')
                #update durasi
                if tsu[3] == False:
                    tsu[0] = time.time()
                    tsu[3] = True
                elif tsu[3] == True:
                    tsu[1] = time.time()
                    tsu[2] = tsu[1] - tsu[0]

                tsk = [0, 0, 0, False]

        if status == 2 :
            tsu =[0,0,0,False] #reset
            regions = hd.detect(hog, resized_img, (4,4), (4, 4), 1.2)
            hd.boxes(resized_img, regions)
            if len(regions) == 0:
                print('Human Not Detected')
                if tsk[3] == False:
                    tsk[0] = time.time()
                    tsk[3] = True
                elif tsk[3] == True:
                    tsk[1] = time.time()
                    tsk[2] = tsk[1] - tsk[0]

            else :
                tsk = [0,0,0,False] #reset bila terdeteksi manusia

        # showing fps
        cv2.putText(resized_img, "Fps:", (20, 40), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 255), 2);
        fps = cv2.getTickFrequency() / (cv2.getTickCount() - timer);            cv2.putText(resized_img, str(int(fps)), (75, 40), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2);

        # ubah durasi

        tsu[2] = tsu[2]*(fps/fps_read)
        tsk[2] = tsk[2]*(fps/fps_read)

        if status == 1:  # status unknown
            print("Waktu terdeteksi : ")
            print(tsu, '\n')
            if tsu[2] >= 10:  # durasi terdeteksi melebihi 10 detik
                print("alarm triggered!")
                playsound("Industrial Alarm.wav")
                break  # keluar program
        if status == 2:
            print("Waktu tidak terdeteksi : ")
            print(tsk, '\n')
            if tsk[2] >= 2:  # misal tidak terdeteksi (kosong) selama 5 detik
                print("Reset Status menjadi 0")
                status = 0  # ubah status jadi empty

        cv2.imshow('face recognition tutorial ',resized_img)
        print("Status : ",status)
        out.write(resized_img.astype('uint8'))
        if cv2.waitKey(1) & 0xFF == ord('q'):
        # Tekan q untuk menghentikan atau tunggu hingga akhir video
            break
    else :
        break

cap.release()
out.release()
cv2.destroyAllWindows()

print('Waktu awal terdeteksi : ', tsu[0], '\n')
print('Waktu akhir terdeteksi : ', tsu[1], '\n')
print('Durasi terdeteksi : ', tsu[2],' detik','\n')

print('Waktu awal tidak terdeteksi : ', tsk[0], '\n')
print('Waktu akhir tidak terdeteksi : ', tsk[1], '\n')
print('Durasi tidak terdeteksi : ', tsk[2],' detik','\n')

if tsu[2] >=10:
    print ("Alarm Triggered!")
    playsound("Industrial Alarm.wav")
    print("Alarm Triggered!")
    playsound("Industrial Alarm.wav")


'''
/**********************************************************************************
* Purpose: Write a Util Static Function to calculate monthlyPayment that reads in three
* commandline arguments P, Y, and R and calculates the monthly payments you
* would have to make over Y years to pay off a P principal loan amount at R per cent
* interest compounded monthly.
* logic :
*
* @author : Janhavi Mhatre
* @python version 3.7
* @platform : PyCharm
* @since 26-12-2018
*
***********************************************************************************/
'''
from utilities import utility

p = int(input("enter principal loan amount p: "))
y = int(input("enter years y: "))
r = int(input("enter rate r: "))

utility.monthly_pay(p, y, r)


#
# @lc app=leetcode id=1 lang=python3
#
# [1] Two Sum
#

# @lc code=start
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        d = {}
        for i, val in enumerate(nums):
            rev = target - val
            if rev in d:
                return [d[rev], i]
            else:
                d[val] = i
# @lc code=end


# Bootstrap dropdown doesn't have select tag
# inspect the dropdown, find all the li under ui tag
# Loop through it and click the right li

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service

# Launch the browser
service_obj = Service("C:\Drivers\chromedriver_win32\chromedriver.exe")
driver = webdriver.Chrome(service=service_obj)
driver.implicitly_wait(10)

# Open the web application
driver.get("https://www.dummyticket.com/dummy-ticket-for-visa-application/")
driver.maximize_window()

driver.find_element(By.XPATH, "//span[@id='select2-billing_country-container']").click()

countries_list = driver.find_elements(By.XPATH, "//ul[@id='select2-billing_country-results']/li")
print(len(countries_list))

for country in countries_list:
    if country.text == "India":
        country.click()
        break