# ###
# Mathematical expression recognition tool.
# Written as a part of masters thesis at VUT FIT Brno, 2022

# Author: Vladislav Halva
# Login: xhalva04
# ###

from torch import nn

from src.model.Decoder import Decoder
from src.model.Encoder import Encoder

class Model(nn.Module):
    """
    Encoder-decoder model for mathematical expressions recognition wrapper.
    """
    def __init__(
            self, device, edge_features, edge_h_size,
            enc_in_size, enc_h_size, enc_out_size, dec_in_size, dec_h_size, emb_size, dec_att_size,
            vocab_size, end_node_token_id, tokenizer,
            enc_vgg_dropout_p, enc_gat_dropout_p, dec_emb_dropout_p, dec_att_dropout_p):
        """
        :param device: device
        :param edge_features: in edge features size
        :param edge_h_size: hidden and out edge features size
        :param enc_in_size: encoder GATs in nodes features size
        :param enc_h_size: encoder GATs hidden nodes features size
        :param enc_out_size: encoder GATs out nodes features size
        :param dec_in_size: decoder in node features size
        :param dec_h_size: decoder hidden node features size
        :param emb_size: decoder out node features=embeddings size
        :param dec_att_size: decoder source graph attention vector size
        :param vocab_size: vocabulary size
        :param end_node_token_id: id of end-leaf-node token [EOS]
        :param tokenizer: tokenizer
        :param enc_vgg_dropout_p: dropout probability for encoder VGG linear layers
        :param enc_gat_dropout_p: dropout probability for encoder GAT layers
        :param dec_emb_dropout_p: dropout probability for decoder initial embedding layer
        :param dec_att_dropout_p: dropout probability for decoder attention to source graph
        """
        super(Model, self).__init__()

        self.encoder = Encoder(
            edge_features, edge_h_size,
            enc_in_size, enc_h_size, enc_out_size, vocab_size,
            enc_vgg_dropout_p, enc_gat_dropout_p)
        self.decoder = Decoder(
            device, enc_out_size, dec_in_size, dec_h_size, emb_size,
            dec_att_size, vocab_size, end_node_token_id,
            tokenizer, dec_emb_dropout_p, dec_att_dropout_p)

        self.lin_x_out = nn.Linear(enc_out_size, vocab_size, bias=False)

    def forward(self, data, beam_search=True, beam_width=3):
        """
        :param data: databatch object
        :param beam_search: True if beam search, False otherwise
        :param beam_width: if beam search sets the beam width - number of simultaneously generated output graphs
        :return: output data
        """
        # encode source graph
        x, edge_index, edge_attr, x_conv_score = self.encoder(data.x, data.edge_index, data.edge_attr)
        # decode output graph
        y, y_batch, y_edge_index, y_edge_type, y_score, y_edge_rel_score, gcn1_alpha, gcn2_alpha, gcn3_alpha, = self.decoder(
            x, data.x_batch, data.tgt_y, data.tgt_edge_index, data.tgt_edge_type, data.tgt_y_batch, beam_search, beam_width)
        # get source graph node predictions and update values in databatch object for source graph
        data.x = x
        data.x_score = self.lin_x_out(x)
        data.edge_index = edge_index
        data.edge_attr = edge_attr
        data.x_conv_score = x_conv_score
        # include output graph in output databatch object
        data.y = y
        data.y_batch = y_batch
        data.y_edge_index = y_edge_index
        data.y_edge_type = y_edge_type
        data.y_score = y_score
        data.y_edge_rel_score = y_edge_rel_score
        data.gcn1_alpha = gcn1_alpha
        data.gcn2_alpha = gcn2_alpha
        data.gcn3_alpha = gcn3_alpha
        return data


import sys
import typing
from PyQt5.QtWidgets import QWidget, QApplication, QLineEdit, QPushButton, QLabel, QPlainTextEdit

class Lz78Code:
    def __init__(self, i, c):
        self.i = i
        self.c = c

    def __str__(self) -> str:
        return f"<{self.i}, '{self.c}'>"

def encode(input_str: str) -> typing.List[Lz78Code]:
    ret = []
    prev_sub = ""
    sub_dict = {"": 0}
    for c in input_str:
        next_sub = prev_sub + c
        if next_sub not in sub_dict:
            i = sub_dict[prev_sub]
            output = Lz78Code(i, c)
            sub_dict[next_sub] = len(sub_dict)
            print(f"'{next_sub}'\t{str(output)}\t{len(sub_dict) - 1}")
            ret.append(f"'{next_sub}'\t{str(output)}\t{len(sub_dict) - 1}")
            prev_sub = ""
        else:
            prev_sub = next_sub
    return ret

def decode(input_ar: typing.List[Lz78Code]) -> str:
    ret = ""
    sub_dict = [""]
    for output in input_ar:
        entry = sub_dict[output.i] + output.c
        sub_dict.append(entry)
        ret += entry
    return ret

class Windows(QWidget):
    def __init__(self):
        super().__init__()
        self.addProperties()
        self.addProperties1()
        self.buton.clicked.connect(self.click)

    def addProperties(self):
        self.resize(400, 400)
        self.move(700, 100)
        self.setWindowTitle('LZ78 Algorithm')

    def addProperties1(self):
        self.label = QLabel("Enter Characters", self)
        self.label.setGeometry(100, 5, 200, 75)

        self.input = QLineEdit(self)
        self.input.setGeometry(100, 60, 200, 25)

        self.buton = QPushButton("Run", self)
        self.buton.setGeometry(100, 100, 200, 25)

        self.label = QLabel("Result:", self)
        self.label.setGeometry(100, 120, 200, 75)

        self.label = QPlainTextEdit(self)
        self.label.setGeometry(75, 170, 250, 190)

    def click(self):
        result = ""
        for i in encode(self.input.text()):
            result += f" {i} \n"
        self.label.clear()
        self.label.insertPlainText(result)

app = QApplication(sys.argv)
form = Windows()
form.show()
sys.exit(app.exec_())


#!/usr/bin/env python3
"""Simple pagination"""
import csv
import math
from typing import List, Tuple

class Server:
    """Server class to paginate a database of popular baby names.
    """
    DATA_FILE = "Popular_Baby_Names.csv"

    def __init__(self):
        self.__dataset = None

    def dataset(self) -> List[List]:
        """Cached dataset
        """
        if self.__dataset is None:
            with open(self.DATA_FILE) as f:
                reader = csv.reader(f)
                dataset = [row for row in reader]
            self.__dataset = dataset[1:]

        return self.__dataset

    def get_page(self, page: int = 1, page_size: int = 10) -> List[List]:
        """return list"""
        assert type(page) is int
        assert type(page_size) is int
        assert page > 0
        assert page > page_size
        self.dataset()
        a = index_range(page, page_size)
        if a[0] >= len(self.__dataset):
            return []
        else:
            return self.__dataset[a[0]:a[1]]

def index_range(page: int, page_size: int) -> Tuple[int, int]:
    """return a tuple of size two containing a start index and an end index"""
    total_size = page * page_size
    page_n = total_size - page_size
    return (page_n, page)


import json
import os
from pathlib import Path

from syndicate.commons.log_helper import get_logger, get_user_logger
from syndicate.core import ProjectState
from syndicate.core.project_state.project_state import BUILD_MAPPINGS
from syndicate.core.generators import (_touch,
                                       _mkdir, _write_content_to_file,
                                       FILE_LAMBDA_HANDLER_PYTHON,
                                       FILE_LAMBDA_HANDLER_NODEJS,
                                       _read_content_from_file)
from syndicate.core.generators.project import _generate_java_project_hierarchy
from syndicate.core.generators.tests import _generate_python_tests
from syndicate.core.generators.contents import (
    NODEJS_LAMBDA_HANDLER_TEMPLATE,
    _generate_python_node_lambda_config,
    _generate_lambda_role_config, _generate_nodejs_node_lambda_config,
    CANCEL_MESSAGE, _generate_package_nodejs_lambda,
    _generate_package_lock_nodejs_lambda, JAVA_LAMBDA_HANDLER_CLASS,
    SRC_MAIN_JAVA, FILE_POM, PYTHON_LAMBDA_HANDLER_TEMPLATE, INIT_CONTENT,
    ABSTRACT_LAMBDA_CONTENT, EXCEPTION_CONTENT, LOG_HELPER_CONTENT)
from syndicate.core.groups import (RUNTIME_JAVA, RUNTIME_NODEJS,
                                   RUNTIME_PYTHON)

_LOG = get_logger('syndicate.core.generators.lambda_function')
USER_LOG = get_user_logger()

FOLDER_LAMBDAS = 'lambdas'
FOLDER_COMMONS = 'commons'

FILE_DEPLOYMENT_RESOURCES = 'deployment_resources.json'
FILE_INIT_PYTHON = '__init__.py'
FILE_LAMBDA_CONFIG = 'lambda_config.json'
FILE_PACKAGE_LOCK = 'package-lock.json'
FILE_PACKAGE = 'package.json'

FILE_REQUIREMENTS = 'requirements.txt'
FILE_LOCAL_REQUIREMENTS = 'local_requirements.txt'

LAMBDA_ROLE_NAME_PATTERN = '{0}-role'  # 0 - lambda_name
POLICY_NAME_PATTERN = '{0}-policy'  # 0 - lambda_name

ABSTRACT_LAMBDA_NAME = 'abstract_lambda'

PROJECT_STATE_PARAM = 'project_state'
LAMBDAS_PATH_PARAM = 'lambdas_path'
LAMBDA_NAMES_PARAM = 'lambda_names'
PROJECT_NAME_PARAM = 'project_name'
PROJECT_PATH_PARAM = 'project_path'

PYTHON_LAMBDA_FILES = [
    FILE_INIT_PYTHON, FILE_LOCAL_REQUIREMENTS,
    FILE_REQUIREMENTS,
    FILE_DEPLOYMENT_RESOURCES,  # content
    FILE_LAMBDA_CONFIG  # content
]  # + handler content

NODEJS_LAMBDA_FILES = [
    FILE_PACKAGE,
    FILE_PACKAGE_LOCK,
    FILE_LAMBDA_CONFIG,
    FILE_LAMBDA_HANDLER_NODEJS,
    FILE_DEPLOYMENT_RESOURCES
]

def generate_common_module(src_path, runtime):
    runtime_processor = COMMON_MODULE_PROCESSORS.get(runtime)
    if not runtime_processor:
        raise AssertionError(f'Unable to create a common module in {src_path}')
    runtime_processor(src_path=src_path)

def generate_lambda_function(project_path, runtime,
                             lambda_names):
    if not os.path.exists(project_path):
        USER_LOG.info(f'Project "{project_path}" you '
                      f'have provided does not exist')
        return

    if not ProjectState.check_if_project_state_exists(
            project_path=project_path):
        USER_LOG.info(f'Seems that the path {project_path} is not a project')
        return
    project_state = ProjectState(project_path=project_path)
    src_path = os.path.join(project_path, BUILD_MAPPINGS[runtime])

    common_module_generator = COMMON_MODULE_PROCESSORS.get(runtime)
    if not common_module_generator:
        raise AssertionError(f'The runtime {runtime} is not currently '
                             f'supported to bootstrap the project')
    common_module_generator(src_path=src_path)
    project_state.add_project_build_mapping(runtime=runtime)

    processor = LAMBDAS_PROCESSORS.get(runtime)
    if not processor:
        raise RuntimeError(f'Wrong project runtime {runtime}')

    lambdas_path = os.path.join(src_path, FOLDER_LAMBDAS)

    processor(project_path=project_path, lambda_names=lambda_names,
              lambdas_path=lambdas_path, project_state=project_state)

    tests_generator = TESTS_MODULE_PROCESSORS.get(runtime)
    [tests_generator(project_path, name) for name in lambda_names]

    project_state.save()
    if len(lambda_names) == 1:
        USER_LOG.info(f'Lambda {lambda_names[0]} has been successfully '
                      f'added to the project.')
    else:
        generated_lambdas = ', '.join(lambda_names)
        USER_LOG.info(f'The following lambdas have been successfully '
                      f'added to the project: {generated_lambdas}')

def _generate_python_lambdas(**kwargs):
    lambdas_path = kwargs.get(LAMBDAS_PATH_PARAM)
    lambda_names = kwargs.get(LAMBDA_NAMES_PARAM)
    project_state = kwargs.get(PROJECT_STATE_PARAM)

    if not os.path.exists(lambdas_path):
        _mkdir(lambdas_path, exist_ok=True)

    init_file = os.path.join(lambdas_path, '__init__.py')
    _touch(init_file)
    _LOG.info(f'Lambdas path: {lambdas_path}')
    for lambda_name in lambda_names:
        lambda_folder = os.path.join(lambdas_path, lambda_name)

        answer = _mkdir(
            path=lambda_folder,
            fault_message=f'\nLambda {lambda_name} already exists.\nOverride '
                          f'the Lambda function? [y/n]: ')
        if not answer:
            _LOG.info(CANCEL_MESSAGE.format(lambda_name))
            continue

        PYTHON_LAMBDA_FILES.append(
            FILE_LAMBDA_HANDLER_PYTHON)  # add lambda handler
        for file in PYTHON_LAMBDA_FILES:
            _touch(os.path.join(lambda_folder, file))

        # fill handler.py
        lambda_class_name = __lambda_name_to_class_name(
            lambda_name=lambda_name)
        python_lambda_handler_template = PYTHON_LAMBDA_HANDLER_TEMPLATE. \
            replace('LambdaName', lambda_class_name)
        _write_content_to_file(os.path.join(
            lambda_folder, FILE_LAMBDA_HANDLER_PYTHON),
            python_lambda_handler_template)

        # fill deployment_resources.json
        pattern_format = LAMBDA_ROLE_NAME_PATTERN.format(lambda_name)
        role_def = _generate_lambda_role_config(pattern_format)
        _write_content_to_file(os.path.join(
            lambda_folder, FILE_DEPLOYMENT_RESOURCES), role_def)

        # fill lambda_config.json
        lambda_def = _generate_python_node_lambda_config(
            lambda_name,
            os.path.join(FOLDER_LAMBDAS, lambda_name))
        _write_content_to_file(os.path.join(lambda_folder, FILE_LAMBDA_CONFIG),
                               lambda_def)

        # fill local_dependencies.txt
        _write_content_to_file(
            os.path.join(lambda_folder, FILE_LOCAL_REQUIREMENTS),
            FOLDER_COMMONS)

        project_state.add_lambda(lambda_name=lambda_name, runtime='python')

        _LOG.info(f'Lambda {lambda_name} created')

def __lambda_name_to_class_name(lambda_name):
    class_name = lambda_name.split('-')
    if len(class_name) == 1:
        class_name = lambda_name.split('_')
    return ''.join([_.capitalize() for _ in class_name])

def _generate_java_lambdas(**kwargs):
    project_path = kwargs.get(PROJECT_PATH_PARAM)
    project_state = kwargs.get(PROJECT_STATE_PARAM)
    project_name = project_state.name
    lambda_names = kwargs.get(LAMBDA_NAMES_PARAM, [])

    _generate_java_project_hierarchy(project_name=project_name,
                                     full_project_path=project_path)

    java_package_name = _generate_java_package_name(project_name)
    java_package_as_path = java_package_name.replace('.', '/')

    pom_file_path = os.path.join(project_path, FILE_POM)
    pom_xml_content = _read_content_from_file(pom_file_path)
    pom_xml_content = pom_xml_content.replace(
        '<!--packages to scan-->',
        f'<package>{java_package_name}</package>')
    _write_content_to_file(pom_file_path, pom_xml_content)

    full_package_path = Path(project_path, SRC_MAIN_JAVA, java_package_as_path)
    for lambda_name in lambda_names:
        if not os.path.exists(full_package_path):
            _mkdir(full_package_path, exist_ok=True)

        lambda_class_name = _get_parts_split_by_chars(to_split=lambda_name,
                                                      chars=['-', '_']).title()
        lambda_class_name = lambda_class_name.replace(' ', '')
        lambda_role_name = LAMBDA_ROLE_NAME_PATTERN.format(lambda_name)
        java_handler_content = \
            (JAVA_LAMBDA_HANDLER_CLASS
             .replace('{java_package_name}', java_package_name)
             .replace('{lambda_name}', lambda_name)
             .replace('{lambda_class_name}', lambda_class_name)
             .replace('{lambda_role_name}', lambda_role_name))

        java_handler_file_name = os.path.join(
            project_path, SRC_MAIN_JAVA, java_package_as_path,
            f'{lambda_class_name}.java')
        _write_content_to_file(
            java_handler_file_name,
            java_handler_content
        )

        # add role to deployment_resource.json

        dep_res_path = os.path.join(project_path,
                                    FILE_DEPLOYMENT_RESOURCES)
        deployment_resources = json.loads(_read_content_from_file(
            dep_res_path
        ))
        deployment_resources.update(_generate_lambda_role_config(
            lambda_role_name, stringify=False))
        _write_content_to_file(dep_res_path,
                               json.dumps(deployment_resources, indent=2))

        project_state.add_lambda(lambda_name=lambda_name, runtime=RUNTIME_JAVA)
        _LOG.info(f'Lambda {lambda_name} created')

def _generate_java_package_name(project_name):
    unified_package_name = _get_parts_split_by_chars(to_split=project_name,
                                                     chars=['-', '_'])
    java_package_name = unified_package_name.replace(' ', '')
    java_package_name = f'com.{java_package_name}'
    return java_package_name

def _get_parts_split_by_chars(chars, to_split):
    result = to_split
    for char in chars:
        result = result.replace(char, ' ')
    return result

def _generate_nodejs_lambdas(**kwargs):
    lambdas_path = kwargs.get(LAMBDAS_PATH_PARAM)
    lambda_names = kwargs.get(LAMBDA_NAMES_PARAM, [])
    project_state = kwargs.get(PROJECT_STATE_PARAM)

    if not os.path.exists(lambdas_path):
        _mkdir(lambdas_path, exist_ok=True)
    for lambda_name in lambda_names:

        lambda_folder = os.path.join(lambdas_path, lambda_name)

        answer = _mkdir(
            path=lambda_folder,
            fault_message=f'\nLambda {lambda_name} already exists.\n'
                          f'Override the Lambda function? [y/n]: ')
        if not answer:
            _LOG.info(CANCEL_MESSAGE.format(lambda_name))
            continue

        for file in NODEJS_LAMBDA_FILES:
            _touch(Path(lambda_folder, file))

        # fill index.js
        _write_content_to_file(
            os.path.join(lambda_folder, FILE_LAMBDA_HANDLER_NODEJS),
            NODEJS_LAMBDA_HANDLER_TEMPLATE)

        # fill package.json
        package_def = _generate_package_nodejs_lambda(lambda_name)
        _write_content_to_file(os.path.join(lambda_folder, FILE_PACKAGE),
                               package_def)

        # fill package.json
        package_lock_def = _generate_package_lock_nodejs_lambda(
            lambda_name)
        _write_content_to_file(os.path.join(lambda_folder, FILE_PACKAGE_LOCK),
                               package_lock_def)

        # fill deployment_resources.json
        role_def = _generate_lambda_role_config(
            LAMBDA_ROLE_NAME_PATTERN.format(lambda_name))
        _write_content_to_file(
            os.path.join(lambda_folder, FILE_DEPLOYMENT_RESOURCES),
            role_def)

        # fill lambda_config.json
        lambda_def = _generate_nodejs_node_lambda_config(
            lambda_name,
            os.path.join(FOLDER_LAMBDAS, lambda_name))
        _write_content_to_file(os.path.join(lambda_folder, FILE_LAMBDA_CONFIG),
                               lambda_def)
        project_state.add_lambda(lambda_name=lambda_name, runtime=RUNTIME_NODEJS)
        _LOG.info(f'Lambda {lambda_name} created')

LAMBDAS_PROCESSORS = {
    RUNTIME_JAVA: _generate_java_lambdas,
    RUNTIME_NODEJS: _generate_nodejs_lambdas,
    RUNTIME_PYTHON: _generate_python_lambdas,
}

def _common_java_module(src_path):
    pass

def _common_nodejs_module(src_path):
    pass

def _common_python_module(src_path):
    common_module_path = os.path.join(src_path, FOLDER_COMMONS)
    _mkdir(path=common_module_path, exist_ok=True)

    init_path = os.path.join(common_module_path, '__init__.py')
    _touch(init_path)
    _write_content_to_file(file=init_path, content=INIT_CONTENT)

    abstract_lambda_path = os.path.join(common_module_path,
                                        'abstract_lambda.py')
    _touch(path=abstract_lambda_path)
    _write_content_to_file(file=abstract_lambda_path,
                           content=ABSTRACT_LAMBDA_CONTENT)

    logger_path = os.path.join(common_module_path, 'log_helper.py')
    _touch(path=logger_path)
    _write_content_to_file(file=logger_path, content=LOG_HELPER_CONTENT)

    exception_path = os.path.join(common_module_path, 'exception.py')
    _touch(path=exception_path)
    _write_content_to_file(file=exception_path, content=EXCEPTION_CONTENT)

def resolve_lambda_path(project: Path, runtime: str, source: str) -> Path:
    _lambda = ''
    if runtime == RUNTIME_JAVA:
        _lambda = _generate_java_package_name(project.name).replace('.', '/')
    elif runtime in LAMBDAS_PROCESSORS:
        _lambda = FOLDER_LAMBDAS
    return project/Path(source, _lambda)

COMMON_MODULE_PROCESSORS = {
    RUNTIME_JAVA: _common_java_module,
    RUNTIME_NODEJS: _common_nodejs_module,
    RUNTIME_PYTHON: _common_python_module
}

TESTS_MODULE_PROCESSORS = {
    RUNTIME_JAVA: lambda project_path, lambda_name: None,
    RUNTIME_NODEJS: lambda project_path, lambda_name: None,
    RUNTIME_PYTHON: _generate_python_tests,
}


tudo = []
dados = []
maior = menor = 0
while True:
    dados.append(str(input('Digite um nome: ')))
    dados.append(float(input('Digite seu peso: ')))
    if len(tudo) == 0:
        maior = menor = dados[1]
    else:
        if dados[1] > maior:
            maior = dados[1]
        if dados[1] < menor:
            menor = dados[1]
    tudo.append(dados[:])
    dados.clear()
    resp = (str(input('Quer continuar:(s;n) ')))
    if resp in 'nN':
        break
print('--'*30)
print(tudo)
print(f'Foram cadastradas {len(tudo)} pessoas')
for c in tudo:
    if c[1] == maior:
        print(f'O {c[0]} foi a pessoa mais gorda.')
for c in tudo:
    if c[1] == menor:
        print(f'O {c[0]} foi a pessoa mais magra.')
print(f'Maior peso {maior} e o menor peso {menor}')


class User:
    def __init__(self, user_id, user_name):
        print("User Created...")
        self.id = user_id
        self.user_name = user_name
        self.follower = 0  # default value
        self.following = 0

    def follow(self, user):
        user.follower += 1
        self.following += 1

# user_1 = User()
# user_1.id = "001"
# user_1.user_name = "ashwin"

user_1 = User("001", "ashwin")
user_2 = User("002", "angela")

user_1.follow(user_2)

print(user_1.follower)
print(user_1.following)
print(user_2.follower)
print(user_2.following)


import cv2
import numpy as np
from tensorflow.keras.models import load_model
cap = cv2.VideoCapture(0)
from training_data.model import anti_spoof_face
from processing_data.cropping_face import extract_face

# model_path = 'models/anti_spoof_128_1677228839.5275097.h5'

model_path = 'checkpoint/spoof_face_classification.hdf5'

model = anti_spoof_face()
model.load_weights(model_path)
# model = load_model(model_path)
def pre_processing(image):
    image = cv2.imread(image)
    face = []
    x_total = []
    y_total = []
    w_total = []
    h_total = []
    bbox, confi = extract_face(image)
    for i in bbox:
        x = i[0]
        y = i[1]
        w = i[2]
        h = i[3]
        face_image = image[i[1]: i[3], i[0]: i[2]]
        # face_image = face_image[:,:,::-1]
        face_image = cv2.resize(image, (224,224))
        result_img = np.expand_dims(face_image, axis=0)
        face.append(result_img)
        x_total.append(x)
        y_total.append(y)
        w_total.append(w)
        h_total.append(h)
    return face, x_total[0], y_total[0],w_total[0],h_total[0]

while True:
    ret, frame = cap.read()
    bbox, confi = extract_face(frame)
    for i in bbox:
        facial_img = frame[i[1]: i[3], i[0]: i[2]]
        try:
            face_image = cv2.resize(facial_img, (224,224))
        except:
            continue
        face_image = np.expand_dims(face_image, axis=0)
        result = model.predict(face_image)[0]
        label = np.argmax(result)
        confidence = np.max(result)
        if label == 0:
            labels = 'real'
            color = (0,0,255)
        else:
            labels = 'spoof'
            color = (0,255,0)
        cv2.putText(frame, labels, (i[0], i[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, color, 2)
        cv2.rectangle(frame, (i[0],i[1]), (i[2], i[3]), (0,255,255), 1)
        cv2.imshow('a', frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
cap.release()
cv2.destroyAllWindows()


# ---
# jupyter:
#   jupytext:
#     formats: ipynb,py:light
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.7.1
#   kernelspec:
#     display_name: Manifold 2
#     language: python
#     name: manifold2
# ---

# # Plot Embeddings
#
# Only plots one embedding at a time.

import pandas as pd
import numpy as np
import os.path as osp
import umap
from sklearn.metrics import silhouette_score
from utils.data_info import PRJDIR, task_labels, SBJ_list, UMAP_k_list, wl_sec, tr
import panel as pn
import plotly.express as px
pn.extension('plotly')

SBJ = 'SBJ06' # Subject number
n = 3 # number of dimensions
drop = 'DropData' # Type of data (FullData: all windows, DropData: only pure windows, DropX: keep every X window)
ndrop = 15 # If using DropX embedding, X value (5, 10, or 15) MUST MATCH X
wl_trs = int(wl_sec/1.5) # Window length in TRs (TR = 1.5 sec)

if drop == 'FullData':
    task_df = task_labels(wl_trs, PURE=False)
elif drop == 'Drop5' or drop == 'Drop10' or drop == 'Drop15':
    print('in')
    task_df = task_labels(wl_trs, PURE=False)
    task_df = task_df.loc[range(0, task_df.shape[0], ndrop)].copy()
elif drop == 'DropData':
    task_df = task_labels(wl_trs, PURE=True)
print(task_df.shape)

# +
# Load LE Embedding
# -----------------
k = 60 # k-NN value
metric = 'correlation' # distance metric

file_name = SBJ+'_LE_embedding_wl'+str(wl_sec).zfill(3)+'_k'+str(k).zfill(3)+'_n'+str(n).zfill(2)+'_'+metric+'_'+drop+'.csv'
file_path = osp.join(PRJDIR,'derivatives','LE',file_name)
embed_df  = pd.read_csv(file_path)
print('++ INFO: LE embedding loaded')
print('         Data shape:',embed_df.shape)

# + jupyter={"outputs_hidden": true, "source_hidden": true}
# Load TSNE Embedding
# -------------------
p = 13
metric = 'correlation'

file_name = SBJ+'_TSNE_embedding_wl'+str(wl_sec).zfill(3)+'_p'+str(p).zfill(3)+'_n'+str(n).zfill(2)+'_'+metric+'_'+drop+'.csv'
file_path = osp.join(PRJDIR,'derivatives','TSNE',file_name)
embed_df  = pd.read_csv(file_path)
print('++ INFO: TSNE embedding loaded')
print('         Data shape:',embed_df.shape)

# + jupyter={"outputs_hidden": true, "source_hidden": true}
# Load UMAP Embedding
# -------------------
k = 11
metric = 'correlation'

file_name = SBJ+'_UMAP_embedding_wl'+str(wl_sec).zfill(3)+'_k'+str(k).zfill(3)+'_n'+str(n).zfill(2)+'_'+metric+'_'+drop+'.csv'
file_path = osp.join(PRJDIR,'derivatives','UMAP',file_name)
embed_df  = pd.read_csv(file_path)
print('++ INFO: UMAP embedding loaded')
print('         Data shape:',embed_df.shape)
# -

embed_df.index = task_df.index # Make embeding data frame index and task label data frame index the same

# +
# Plot Embedding
task_cmap = {'Rest': 'gray', 'Memory': 'blue', 'Video': '#F4D03F', 'Math': 'green', 'Inbetween': 'black'}

plot_input = pd.DataFrame(columns=['x','y','z'])
plot_input[['x','y','z']] = embed_df[['1_norm','2_norm','3_norm']].copy()
plot_input['Task'] = task_df['Task']

plot = px.scatter_3d(plot_input, x='x', y='y', z='z', color='Task', color_discrete_map=task_cmap, width=700, height=600, opacity=0.7)
plot = plot.update_traces(marker=dict(size=3,line=dict(width=0)))

plot
# -

# Compute SI Value
if drop == 'FullData' or drop == 'Drop5' or drop == 'Drop10' or drop == 'Drop15':
    drop_index    = task_df.index[task_df['Task'] == 'Inbetween']
    drop_embed_df = embed_df.drop(drop_index).reset_index(drop=True)
    drop_task_df  = task_df.drop(drop_index).reset_index(drop=True)
    SI = silhouette_score(drop_embed_df[['1_norm', '2_norm', '3_norm']], drop_task_df['Task'].values)
elif drop == 'DropData':
    SI = silhouette_score(embed_df[['1_norm', '2_norm', '3_norm']], task_df['Task'].values)
print(SI)


import abc

class CarFactory():
    def create_car(self, type, engine):
        if type == 'Sedan':
            return Sedan(engine)

        elif type == 'Pickup':
            return Pickup(engine)

        elif type == 'SUV':
            return SUV(engine)

        elif type == 'Coupe':
            return Coupe(engine)

        raise Exception('Error! Unknown vehicle.')

class Car(metaclass=abc.ABCMeta):
    def start(self):
        print (f'The {self.engine} engine is starting...')

class Sedan(Car):
    def __init__(self, engine):
        self.doors = 4
        self.engine = engine

class Pickup(Car):
    def __init__(self, engine):
        self.doors = 2
        self.engine = engine

class SUV(Car):
    def __init__(self, engine):
        self.doors = 5
        self.engine = engine

class Coupe(Car):
    def __init__(self, engine):
        self.doors = 2
        self.engine = engine

car_factory = CarFactory()

my_x5 = car_factory.create_car("SUV", "v8")
my_miata = car_factory.create_car("Coupe", "v4")

my_x5.start()
my_miata.start()


# import cv
import cv2
from PyQt5 import QtCore
import numpy as np
import os

class CameraDevice(QtCore.QObject):
    _DEFAULT_FPS = 30

    # newFrame = QtCore.pyqtSignal(cv.iplimage)
    newFrame = QtCore.pyqtSignal(np.ndarray)
    video_time_out = QtCore.pyqtSignal()

    def __init__(self, cameraId=0, video_path=None, mirrored=False, parent=None):
        super(CameraDevice, self).__init__(parent)

        self.mirrored = mirrored

        if video_path:
            self._cameraDevice = cv2.VideoCapture(video_path)
        else:
            self._cameraDevice = cv2.VideoCapture(cameraId)

        self._timer = QtCore.QTimer(self)
        self._timer.timeout.connect(self._queryFrame)
        self._timer.setInterval(1000 / self.fps)

        self.paused = False

    @QtCore.pyqtSlot()
    def _queryFrame(self):
        '''
        frame = cv.QueryFrame(self._cameraDevice)
        if self.mirrored:
            mirroredFrame = cv.CreateImage(cv.GetSize(frame), frame.depth, \
                                           frame.nChannels)
            cv.Flip(frame, mirroredFrame, 1)
            frame = mirroredFrame
        '''
        ret, frame = self._cameraDevice.read()
        if ret:
            self.newFrame.emit(frame)
        else:
            self._cameraDevice.set(cv2.CAP_PROP_POS_FRAMES, 0)
            self.video_time_out.emit()

    @property
    def paused(self):
        return not self._timer.isActive()

    @paused.setter
    def paused(self, p):
        if p:
            self._timer.stop()
        else:
            self._timer.start()

    @property
    def frameSize(self):
        w = cv2.cv.GetCaptureProperty(self._cameraDevice, cv2.CAP_PROP_FRAME_WIDTH)
        h = cv2.cv.GetCaptureProperty(self._cameraDevice, cv2.CAP_PROP_FRAME_HEIGHT)
        return int(w), int(h)

    @property
    def fps(self):
        fps = 0
        if not fps > 0:
            fps = self._DEFAULT_FPS
        return fps

    def set_video_path(self, video_path):
        if os.path.exists(video_path):
            self.paused = True
            self._cameraDevice = cv2.VideoCapture(video_path)
            self.paused = False
        else:
            print('video path ' + video_path + ' does not exist!')

    def set_image_path(self, image_path):
        if os.path.exists(image_path):
            frame = cv2.imread(image_path)
            if frame is not None:
                self.newFrame.emit(frame)
        else:
            print('image path ' + image_path + ' does not exist!')


import sys
if len(sys.argv)==1:
	print("Missing required input")
	quit()

K = int(sys.argv[1])

listofnumbers1 = list()
for i in range(2,len(sys.argv)):
	listofnumbers1.append(int(sys.argv[i]))

listofnumbers1.sort()
middle = int(len(listofnumbers1)/2)
median=0

if (len(listofnumbers1)%2)!=0:
#If total numbers are odd
	median = listofnumbers1[middle]
else:
#If total numbers are even
	median = ((listofnumbers1[middle]+listofnumbers1[middle-1])/2)

distancefromMedian = dict()
for num in listofnumbers1:
	if num>median:
#Finding distance
		distancefromMedian[num] = num-median
	else:
#Finding distance
		distancefromMedian[num] = median-num

sortedValues = sorted(distancefromMedian.values())
distancefromMedian1 = dict()
for i in range(0,len(sortedValues)):
	for key in distancefromMedian:
#Matching sorted values with the keys and sorting the keys according to the distance from median
		if distancefromMedian[key]==sortedValues[i]:
			distancefromMedian1[key] = sortedValues[i]

listofnumbers = list()
listofnumbers1.clear()
for key in distancefromMedian1:
#Storing sorted keys in the list
	listofnumbers.append(key)

for i in range(0,K):
#Fetching first K numbers or fetching K numbers that are nearest to the median
	listofnumbers1.append(listofnumbers[i])

listofnumbers1.sort()
print(listofnumbers1)


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

import scorelib
import sys
import codecs

if len(sys.argv) < 2:
    exit("Too less arguments calling script")

fileName = sys.argv[1]

sys.stdout = codecs.getwriter('utf-8')(sys.stdout.buffer)

prints = scorelib.load(fileName)
for print_obj in prints:
    print_obj.format()
    print()


### Python script to use SNAP as InSAR processor for TSX/TDX processing compatible with StaMPS PSI processing
# Author: Jonas Ziemer, adapted from Jose Manuel Delgado Blasco (snap2stamps package)
# Date: 01/01/2023
# Version: 2.1, Python 3.9

# Step 1: unzip downloaded TSX scenes (.tar; .tar.gz)
# Step 2: preparing secondaries in folder structure
# Step 3: subset TSX scenes
# Step 4: Coregistration
# Step 5: Interferogram generation
# Step 6: StaMPS export

import os
import shutil
import sys
import glob
import subprocess
import shlex
import time
import tarfile

import configparser
import argparse
import warnings

warnings.filterwarnings('ignore')

parser = argparse.ArgumentParser(description='This script unpacks the original TSX/TDX data')
parser.add_argument("--ProjFile","-F", type=str)

args = parser.parse_args()
if not args.ProjFile:
    print("No Input File detected")
    sys.exit(-1)
else:
    configfile = args.ProjFile

print(configfile)

config = configparser.ConfigParser()
config.read(configfile)
PROJECTFOLDER=config['PROJECT_DEFINITION'].get('PROJECTFOLDER')
print(PROJECTFOLDER)

bar_message='\n#####################################################################\n'

##############################################################################
################### Unpack zipped files in the zipfolder #####################
##############################################################################
# Folders involved in this processing step
logfolder=os.path.join(PROJECTFOLDER,'logs')
zipfolder=os.path.join(PROJECTFOLDER,'zipfiles')
secondariesfolder=os.path.join(PROJECTFOLDER,'secondaries')

if not os.path.exists(logfolder):
                os.makedirs(logfolder)
if not os.path.exists(zipfolder):
                os.makedirs(zipfolder)
if not os.path.exists(secondariesfolder):
                os.makedirs(secondariesfolder)

errorlog=os.path.join(logfolder,'unpack_proc_stderr.log')
outlog=os.path.join(logfolder,'unpack_proc_stdout.log')
out_file = open(outlog, 'a')
err_file = open(errorlog, 'a')

timeStarted_global = time.time()
# Unpack .tar(.gz) files
try:
    for filename in os.listdir(zipfolder):
        os.chdir(zipfolder)
        filename = zipfolder + '/' + filename
        print(filename)
        if filename.endswith("tar.gz"):
            tar = tarfile.open(filename, "r:gz")
            if filename.endswith("tar"):
                tar = tarfile.open(filename, "r:")
        elif filename.endswith("tar"):
            tar = tarfile.open(filename, "r:")
        tar.extractall()
        tar.close()
except:
    raise Exception("The files have already been extracted!")

# Cut out the data folder only, to get the right naming of the files for later processing steps
for file in os.listdir(zipfolder):
    folder = os.path.join(zipfolder, file)
    if os.path.isdir(folder):
        for tsxmainfolder in glob.iglob(folder + '/*'):
            if tsxmainfolder.endswith('.L1B'):
                for tsxsubfolder in glob.iglob(tsxmainfolder + '/*'):
                    print(tsxsubfolder)
                    shutil.move(tsxsubfolder, secondariesfolder)
timeDelta_global = time.time() - timeStarted_global
print('Finished unzipping in ' + str(timeDelta_global) + ' seconds.\n')


from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy import String
from sqlalchemy.orm import sessionmaker, DeclarativeBase, mapped_column
from sqlalchemy import DateTime
from sqlalchemy.sql import func
from src.utils import generate_uuid

SQLALCHEMY_DATABASE_URL = "sqlite+aiosqlite:///./example.db"

# initial db engine
async_engine = create_async_engine(
    SQLALCHEMY_DATABASE_URL,
    connect_args={"check_same_thread": False},
)

# initial session maker
async_session = sessionmaker(
    autocommit=False,
    autoflush=False,
    bind=async_engine,
    class_=AsyncSession,
    expire_on_commit=False,
)

class Base(DeclarativeBase):
    id = mapped_column(String, primary_key=True, default=generate_uuid)
    created_at = mapped_column(DateTime(timezone=True), server_default=func.now())
    updated_at = mapped_column(
        DateTime(timezone=True), onupdate=func.now(), server_default=func.now()
    )

# Dependency
async def get_db() -> AsyncSession:
    async with async_session() as session:
        yield session


"""
For a given json file which defines pods that should be launched on
some nodes, this script creates yaml files which can spawn these pods.
"""

import json
import sys
import os

# Template for the pod yaml file.
pod_template = "\
apiVersion: v1\n\
kind: Pod\n\
metadata:\n\
  name: {}\n\
  labels: {{\n\
    id.pod: {},\n\
  }}\n\
spec:\n\
  nodeName: {}\n\
  volumes:\n\
  - name: results-volume\n\
    hostPath:\n\
      path: /home/niek/results\n\
      type: Directory\n\
  containers:\n\
  - name: ubuntu-shell\n\
    image: ubuntu-shell\n\
    stdin: true\n\
    tty: true\n\
    imagePullPolicy: IfNotPresent\n\
    volumeMounts:\n\
    - name: results-volume\n\
      mountPath: /usr/share/results\n\
    securityContext:\n\
      privileged: true\n\
"

def gen_pods(scen, output, prefix):
    """
    Write the pods to the output file using the template.
    """
    vms = scen["VMs"]
    names = scen["VMpodnames"]
    first = True

    with open(output, 'a') as out:
        for c, vm in enumerate(vms):
            for pod in names[c]:
                name = prefix + "-" + pod
                if not first:
                    out.write("---\n")
                else:
                    first = False

                out.write(pod_template.format(name, name, vm))

if __name__ == "__main__":
    if len(sys.argv) < 4:
        print("Usage: python3 gen_pods.py <gen id> <pods.json> <output.yaml>")
    else:
        prefix = sys.argv[1]
        file = sys.argv[2]
        output = sys.argv[3]
        try:
            os.remove(output)
        except OSError:
            pass

        with open(file) as f:
            scen = json.load(f)
            policy_data = gen_pods(scen, output, prefix)


from flask import Blueprint, render_template, abort
from jinja2 import TemplateNotFound
from blueprints import default_blueprint

@default_blueprint.route('/', defaults={'page': 'index'})
@default_blueprint.route('/<page>')
def show(page):
    try:
        return render_template('pages/%s.html' % page)
    except TemplateNotFound:
        abort(404)


# You are given a sorted unique integer array nums.

# A range [a,b] is the set of all integers from a to b (inclusive).

# Return the smallest sorted list of ranges that cover all the numbers in the array exactly. That is, each element of nums is covered by exactly one of the ranges, and there is no integer x such that x is in one of the ranges but not in nums.

# Each range [a,b] in the list should be output as:

# "a->b" if a != b
# "a" if a == b

# Example 1:

# Input: nums = [0,1,2,4,5,7]
# Output: ["0->2","4->5","7"]
# Explanation: The ranges are:
# [0,2] --> "0->2"
# [4,5] --> "4->5"
# [7,7] --> "7"
# Example 2:

# Input: nums = [0,2,3,4,6,8,9]
# Output: ["0","2->4","6","8->9"]
# Explanation: The ranges are:
# [0,0] --> "0"
# [2,4] --> "2->4"
# [6,6] --> "6"
# [8,9] --> "8->9"

class Solution(object):
    def summaryRanges(self, nums):
        """
        :type nums: List[int]
        :rtype: List[str]
        """
        if not nums:
            return
        ans = []
        rangeList = [[] for i in range(0, len(nums))]
        index = 0
        for i in range(1, len(nums)):
            if nums[i] - 1 != nums[i - 1]:
                rangeList[index].append(nums[i - 1])
                index += 1
            else:
                rangeList[index].append(nums[i - 1])
        rangeList[index].append(nums[i])
        for item in rangeList:
            if not item:
                continue
            if (item[0] == item[-1]):
                ans.append("{}".format(item[0]))
            else:
                ans.append("{}->{}".format(item[0], item[-1]))
        return ans


###
# 04-12-2020
# Hi, here's your problem today. This problem was recently asked by Microsoft:
# You 2 integers n and m representing an n by m grid, determine the number of ways you can get from the top-left to the bottom-right of the matrix y going only right or down.

# Example:
# n = 2, m = 2

# This should return 2, since the only possible routes are:
# Right, down
# Down, right.
###
def num_ways(n, m):
    A = [[0 for _ in range(m)] for _ in range(n)]
    for i in range(n):
        A[i][0] = 1
    for j in range(m):
        A[0][j] = 1
    for i in range(1, n):
        for j in range(1, m):
            A[i][j] = A[i - 1][j] + A[i][j - 1]
    return A[-1][-1]

print(num_ways(2, 2))
# 2


import os
import cv2
import numpy as np
import psutil

from ogi.ProcessOptions import ProcessOptions

from ogi.face_util import get_first_face, get_all_faces, rotate_image_180
from ogi.utilities import compute_cosine_distance, get_device, str_to_class

from typing import Any, List, Callable
from ogi.typing import Frame
from concurrent.futures import ThreadPoolExecutor, as_completed
from threading import Thread, Lock
from queue import Queue
from tqdm import tqdm
from ogi.ffmpeg_writer import FFMPEG_VideoWriter
import ogi.globals

def create_queue(temp_frame_paths: List[str]) -> Queue[str]:
    queue: Queue[str] = Queue()
    for frame_path in temp_frame_paths:
        queue.put(frame_path)
    return queue

def pick_queue(queue: Queue[str], queue_per_future: int) -> List[str]:
    queues = []
    for _ in range(queue_per_future):
        if not queue.empty():
            queues.append(queue.get())
    return queues

class ProcessMgr():
    input_face_datas = []
    target_face_datas = []

    processors = []
    options : ProcessOptions = None

    num_threads = 1
    current_index = 0
    processing_threads = 1
    buffer_wait_time = 0.1

    lock = Lock()

    frames_queue = None
    processed_queue = None

    videowriter= None

    progress_gradio = None
    total_frames = 0

    plugins =  {
    'faceswap'      : 'FaceSwapInsightFace',
    'mask_clip2seg' : 'Mask_Clip2Seg',
    'codeformer'    : 'Enhance_CodeFormer',
    'gfpgan'        : 'Enhance_GFPGAN',
    'dmdnet'        : 'Enhance_DMDNet',
    'gpen'          : 'Enhance_GPEN',
    }

    def __init__(self, progress):
        if progress is not None:
            self.progress_gradio = progress

    def initialize(self, input_faces, target_faces, options):
        self.input_face_datas = input_faces
        self.target_face_datas = target_faces
        self.options = options

        processornames = options.processors.split(",")
        devicename = get_device()
        if len(self.processors) < 1:
            for pn in processornames:
                classname = self.plugins[pn]
                module = 'ogi.processors.' + classname
                p = str_to_class(module, classname)
                p.Initialize(devicename)
                self.processors.append(p)
        else:
            for i in range(len(self.processors) -1, -1, -1):
                if not self.processors[i].processorname in processornames:
                    self.processors[i].Release()
                    del self.processors[i]

            for i,pn in enumerate(processornames):
                if i >= len(self.processors) or self.processors[i].processorname != pn:
                    p = None
                    classname = self.plugins[pn]
                    module = 'ogi.processors.' + classname
                    p = str_to_class(module, classname)
                    p.Initialize(devicename)
                    if p is not None:
                        self.processors.insert(i, p)

    def run_batch(self, source_files, target_files, threads:int = 1):
        progress_bar_format = '{l_bar}{bar}| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, {rate_fmt}{postfix}]'
        self.total_frames = len(source_files)
        self.num_threads = threads
        with tqdm(total=self.total_frames, desc='Processing', unit='frame', dynamic_ncols=True, bar_format=progress_bar_format) as progress:
            with ThreadPoolExecutor(max_workers=threads) as executor:
                futures = []
                queue = create_queue(source_files)
                queue_per_future = max(len(source_files) // threads, 1)
                while not queue.empty():
                    future = executor.submit(self.process_frames, source_files, target_files, pick_queue(queue, queue_per_future), lambda: self.update_progress(progress))
                    futures.append(future)
                for future in as_completed(futures):
                    future.result()

    def process_frames(self, source_files: List[str], target_files: List[str], current_files, update: Callable[[], None]) -> None:
        for f in current_files:
            if not ogi.globals.processing:
                return

            temp_frame = cv2.imread(f)
            if temp_frame is not None:
                resimg = self.process_frame(temp_frame)
                if resimg is not None:
                    i = source_files.index(f)
                    cv2.imwrite(target_files[i], resimg)
            if update:
                update()

    def read_frames_thread(self, cap, frame_start, frame_end, num_threads):
        num_frame = 0
        total_num = frame_end - frame_start
        if frame_start > 0:
            cap.set(cv2.CAP_PROP_POS_FRAMES,frame_start)

        while True and ogi.globals.processing:
            ret, frame = cap.read()
            if not ret:
                break

            self.frames_queue[num_frame % num_threads].put(frame, block=True)
            num_frame += 1
            if num_frame == total_num:
                break

        for i in range(num_threads):
            self.frames_queue[i].put(None)

    def process_videoframes(self, threadindex, progress) -> None:
        while True:
            frame = self.frames_queue[threadindex].get()
            if frame is None:
                self.processing_threads -= 1
                self.processed_queue[threadindex].put((False, None))
                return
            else:
                resimg = self.process_frame(frame)
                self.processed_queue[threadindex].put((True, resimg))
                del frame
                progress()

    def write_frames_thread(self):
        nextindex = 0
        num_producers = self.num_threads

        while True:
            process, frame = self.processed_queue[nextindex % self.num_threads].get()
            nextindex += 1
            if frame is not None:
                self.videowriter.write_frame(frame)
                del frame
            elif process == False:
                num_producers -= 1
                if num_producers < 1:
                    return

    def run_batch_inmem(self, source_video, target_video, frame_start, frame_end, fps, threads:int = 1, skip_audio=False):
        cap = cv2.VideoCapture(source_video)
        # frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
        frame_count = (frame_end - frame_start) + 1
        width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
        height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

        self.total_frames = frame_count
        self.num_threads = threads

        self.processing_threads = self.num_threads
        self.frames_queue = []
        self.processed_queue = []
        for _ in range(threads):
            self.frames_queue.append(Queue(1))
            self.processed_queue.append(Queue(1))

        self.videowriter =  FFMPEG_VideoWriter(target_video, (width, height), fps, codec=ogi.globals.video_encoder, crf=ogi.globals.video_quality, audiofile=None)

        readthread = Thread(target=self.read_frames_thread, args=(cap, frame_start, frame_end, threads))
        readthread.start()

        writethread = Thread(target=self.write_frames_thread)
        writethread.start()

        progress_bar_format = '{l_bar}{bar}| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, {rate_fmt}{postfix}]'
        with tqdm(total=self.total_frames, desc='Processing', unit='frames', dynamic_ncols=True, bar_format=progress_bar_format) as progress:
            with ThreadPoolExecutor(thread_name_prefix='swap_proc', max_workers=self.num_threads) as executor:
                futures = []

                for threadindex in range(threads):
                    future = executor.submit(self.process_videoframes, threadindex, lambda: self.update_progress(progress))
                    futures.append(future)

                for future in as_completed(futures):
                    future.result()
        # wait for the task to complete
        readthread.join()
        writethread.join()
        cap.release()
        self.videowriter.close()
        self.frames_queue.clear()
        self.processed_queue.clear()

    def update_progress(self, progress: Any = None) -> None:
        process = psutil.Process(os.getpid())
        memory_usage = process.memory_info().rss / 1024 / 1024 / 1024
        msg = 'memory_usage: ' + '{:.2f}'.format(memory_usage).zfill(5) + f' GB execution_threads {self.num_threads}'
        progress.set_postfix({
            'memory_usage': '{:.2f}'.format(memory_usage).zfill(5) + 'GB',
            'execution_threads': self.num_threads
        })
        progress.update(1)
        self.progress_gradio((progress.n, self.total_frames), desc='Processing', total=self.total_frames, unit='frames')

    def on_no_face_action(self, frame:Frame):
        if ogi.globals.no_face_action == 0:
            return None, frame
        elif ogi.globals.no_face_action == 2:
            return None, None

        faces = get_all_faces(frame)
        if faces is not None:
            return faces, frame
        return None, frame

    def process_frame(self, frame:Frame):
        if len(self.input_face_datas) < 1:
            return frame

        temp_frame = frame.copy()
        num_swapped, temp_frame = self.swap_faces(frame, temp_frame)
        if num_swapped > 0:
            return temp_frame
        if ogi.globals.no_face_action == 0:
            return frame
        if ogi.globals.no_face_action == 2:
            return None
        else:
            copyframe = frame.copy()
            copyframe = rotate_image_180(copyframe)
            temp_frame = copyframe.copy()
            num_swapped, temp_frame = self.swap_faces(copyframe, temp_frame)
            if num_swapped == 0:
                return frame
            temp_frame = rotate_image_180(temp_frame)
            return temp_frame

    def swap_faces(self, frame, temp_frame):
        num_faces_found = 0
        if self.options.swap_mode == "first":
            face = get_first_face(frame)
            if face is None:
                return num_faces_found, frame
            num_faces_found += 1
            temp_frame = self.process_face(self.options.selected_index, face, temp_frame)

        else:
            faces = get_all_faces(frame)
            if faces is None:
                return num_faces_found, frame

            if self.options.swap_mode == "all":
                for face in faces:
                    num_faces_found += 1
                    temp_frame = self.process_face(self.options.selected_index, face, temp_frame)
                    del face

            elif self.options.swap_mode == "selected":
                for i,tf in enumerate(self.target_face_datas):
                    for face in faces:
                        if compute_cosine_distance(tf.embedding, face.embedding) <= self.options.face_distance_threshold:
                            if i < len(self.input_face_datas):
                                temp_frame = self.process_face(i, face, temp_frame)
                                num_faces_found += 1
                            break
                        del face
            elif self.options.swap_mode == "all_female" or self.options.swap_mode == "all_male":
                gender = 'F' if self.options.swap_mode == "all_female" else 'M'
                for face in faces:
                    if face.sex == gender:
                        num_faces_found += 1
                        temp_frame = self.process_face(self.options.selected_index, face, temp_frame)
                    del face

        if num_faces_found == 0:
            return num_faces_found, frame

        maskprocessor = next((x for x in self.processors if x.processorname == 'clip2seg'), None)
        if maskprocessor is not None:
            temp_frame = self.process_mask(maskprocessor, frame, temp_frame)
        return num_faces_found, temp_frame

    def process_face(self,face_index, target_face, frame:Frame):
        enhanced_frame = None
        inputface = self.input_face_datas[face_index].faces[0]

        for p in self.processors:
            if p.type == 'swap':
                fake_frame = p.Run(inputface, target_face, frame)
                scale_factor = 0.0
            elif p.type == 'mask':
                continue
            else:
                enhanced_frame, scale_factor = p.Run(self.input_face_datas[face_index], target_face, fake_frame)

        upscale = 512
        orig_width = fake_frame.shape[1]
        fake_frame = cv2.resize(fake_frame, (upscale, upscale), cv2.INTER_CUBIC)
        mask_offsets = inputface.mask_offsets

        if enhanced_frame is None:
            scale_factor = int(upscale / orig_width)
            result = self.paste_upscale(fake_frame, fake_frame, target_face.matrix, frame, scale_factor, mask_offsets)
        else:
            result = self.paste_upscale(fake_frame, enhanced_frame, target_face.matrix, frame, scale_factor, mask_offsets)
        return result

    def cutout(self, frame:Frame, start_x, start_y, end_x, end_y):
        if start_x < 0:
            start_x = 0
        if start_y < 0:
            start_y = 0
        if end_x > frame.shape[1]:
            end_x = frame.shape[1]
        if end_y > frame.shape[0]:
            end_y = frame.shape[0]
        return frame[start_y:end_y, start_x:end_x], start_x, start_y, end_x, end_y

    # Paste back adapted from here
    # https://github.com/fAIseh00d/refacer/blob/main/refacer.py
    # which is revised insightface paste back code

    def paste_upscale(self, fake_face, upsk_face, M, target_img, scale_factor, mask_offsets):
        M_scale = M * scale_factor
        IM = cv2.invertAffineTransform(M_scale)

        face_matte = np.full((target_img.shape[0],target_img.shape[1]), 255, dtype=np.uint8)
        ##Generate white square sized as a upsk_face
        img_matte = np.full((upsk_face.shape[0],upsk_face.shape[1]), 255, dtype=np.uint8)
        if mask_offsets[0] > 0:
            img_matte[:mask_offsets[0],:] = 0
        if mask_offsets[1] > 0:
            img_matte[-mask_offsets[1]:,:] = 0

        ##Transform white square back to target_img
        img_matte = cv2.warpAffine(img_matte, IM, (target_img.shape[1], target_img.shape[0]), flags=cv2.INTER_NEAREST, borderValue=0.0)
        ##Blacken the edges of face_matte by 1 pixels (so the mask in not expanded on the image edges)
        img_matte[:1,:] = img_matte[-1:,:] = img_matte[:,:1] = img_matte[:,-1:] = 0

        #Detect the affine transformed white area
        mask_h_inds, mask_w_inds = np.where(img_matte==255)
        #Calculate the size (and diagonal size) of transformed white area width and height boundaries
        mask_h = np.max(mask_h_inds) - np.min(mask_h_inds)
        mask_w = np.max(mask_w_inds) - np.min(mask_w_inds)
        mask_size = int(np.sqrt(mask_h*mask_w))
        #Calculate the kernel size for eroding img_matte by kernel (insightface empirical guess for best size was max(mask_size//10,10))
        # k = max(mask_size//12, 8)
        k = max(mask_size//10, 10)
        kernel = np.ones((k,k),np.uint8)
        img_matte = cv2.erode(img_matte,kernel,iterations = 1)
        #Calculate the kernel size for blurring img_matte by blur_size (insightface empirical guess for best size was max(mask_size//20, 5))
        # k = max(mask_size//24, 4)
        k = max(mask_size//20, 5)
        kernel_size = (k, k)
        blur_size = tuple(2*i+1 for i in kernel_size)
        img_matte = cv2.GaussianBlur(img_matte, blur_size, 0)

        #Normalize images to float values and reshape
        img_matte = img_matte.astype(np.float32)/255
        face_matte = face_matte.astype(np.float32)/255
        img_matte = np.minimum(face_matte, img_matte)
        img_matte = np.reshape(img_matte, [img_matte.shape[0],img_matte.shape[1],1])
        ##Transform upcaled face back to target_img
        paste_face = cv2.warpAffine(upsk_face, IM, (target_img.shape[1], target_img.shape[0]), borderMode=cv2.BORDER_REPLICATE)
        if upsk_face is not fake_face:
            fake_face = cv2.warpAffine(fake_face, IM, (target_img.shape[1], target_img.shape[0]), borderMode=cv2.BORDER_REPLICATE)
            paste_face = cv2.addWeighted(paste_face, self.options.blend_ratio, fake_face, 1.0 - self.options.blend_ratio, 0)

        ##Re-assemble image
        paste_face = img_matte * paste_face
        paste_face = paste_face + (1-img_matte) * target_img.astype(np.float32)
        del img_matte
        del face_matte
        del upsk_face
        del fake_face
        return paste_face.astype(np.uint8)

    def process_mask(self, processor, frame:Frame, target:Frame):
        img_mask = processor.Run(frame, self.options.masking_text)
        img_mask = cv2.resize(img_mask, (target.shape[1], target.shape[0]))
        img_mask = np.reshape(img_mask, [img_mask.shape[0],img_mask.shape[1],1])

        target = target.astype(np.float32)
        result = (1-img_mask) * target
        result += img_mask * frame.astype(np.float32)
        return np.uint8(result)

    def unload_models():
        pass

    def release_resources(self):
        for p in self.processors:
            p.Release()
        self.processors.clear()


# returns dictionary of string
def getDictionary(string):
	dictionary = dict()

	for char in string:
	    dictionary[char] = string.count(char)

	return dictionary

''' compares dictionaries, returns true if both contain
    same number of characters, false if otherwise
'''
def checkDictionaries(d1,d2):
	possible = []

	for char1 in d1:
		for char2 in d2:
			if len(d1) != len(d2):
				del possible[:]
				possible.append(False)

			elif char1 == char2:
				if d1[char1] == d2[char2]:
					possible.append(True)
				else:
					del possible[:]
					possible.append(False)

	return possible[0]

magazine = input("Enter the magazine: ")
ransomNote = input("Enter the required ransome note: ")

print(checkDictionaries(getDictionary(magazine),getDictionary(ransomNote)))


import os
import random
import re
import xlwt

dataDir = '8.20'
NUMBER_OF_CLASS = 5

def numberSplit(txt):
    res = re.findall(r"X:(.*)mY:(.*)mP:(.*)dB", txt)
    X = res[0][0]
    Y = res[0][1]
    Z = res[0][2]
    if "0.00" in X or "0.00" in Y or "0.00" in Z:
        return 0
    result = X + " " + Y + " " + Z + '\n'
    return result

def makeExl(filename):
    fopen = open(dataDir+"/"+filename)
    try:
        lines = fopen.readlines()
    except:
        print(filename+"有问题")
    else:
        random.shuffle(lines)

        a = 0
        b = 0
        c = 0
        A = ""
        B = ""
        C = ""
        for line in lines:
            line = line.replace(" ", "")
            if line[4] == '0' and a < NUMBER_OF_CLASS and numberSplit(line) != 0:
                A += numberSplit(line)
                a += 1

            elif line[4] == '1' and b < NUMBER_OF_CLASS and numberSplit(line) != 0:
                B += numberSplit(line)
                b += 1

            elif line[4] == '2' and c < NUMBER_OF_CLASS and numberSplit(line) != 0:
                C += numberSplit(line)
                c += 1

        Date = "0: \n"+A+'1: \n'+B+"2: \n"+C

        temp = open("temp", 'w')
        temp.write(Date)
        temp.close()

        tempOpen = open("temp")
        tempLines = tempOpen.readlines()

        sheet = exlFile.add_sheet(filename)

        exlX = 0
        exlY = 0
        for tLine in tempLines:
            if ":" in tLine:
                continue
            lineDate = tLine.split(" ")
            sheet.write(exlX, exlY, lineDate[0])
            exlY += 1
            sheet.write(exlX, exlY, lineDate[1])
            exlY += 1
            sheet.write(exlX, exlY, lineDate[2])
            exlX += 1
            exlY = 0

        exlFile.save(dataDir+".xls")
        # print(filename + '完成')

print(dataDir)
exlFile = xlwt.Workbook(encoding='utf-8', style_compression=0)
for files in os.listdir(dataDir):
    makeExl(files)