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

import django.test
from django.core.urlresolvers import reverse

from otree import constants_internal
import otree.common_internal
from otree.common_internal import random_chars_8, random_chars_10
from otree.db import models
from otree.models_concrete import ParticipantToPlayerLookup, RoomToSession
from .varsmixin import ModelWithVars

logger = logging.getLogger('otree')

client = django.test.Client()

# for now removing SaveTheChange

class Session(ModelWithVars):

    class Meta:
        app_label = "otree"
        # if i don't set this, it could be in an unpredictable order
        ordering = ['pk']

    config = models.JSONField(default=dict, null=True)  # type: dict
    vars = models.JSONField(default=dict)  # type: dict

    # label of this session instance
    label = models.CharField(
        max_length=300, null=True, blank=True,
        help_text='For internal record-keeping')

    experimenter_name = models.CharField(
        max_length=300, null=True, blank=True,
        help_text='For internal record-keeping')

    ready = models.BooleanField(default=False)

    code = models.CharField(
        default=random_chars_8,
        max_length=16,
        # set non-nullable, until we make our CharField non-nullable
        null=False,
        unique=True,
        doc="Randomly generated unique identifier for the session.")

    time_scheduled = models.DateTimeField(
        null=True, doc="The time at which the session is scheduled",
        help_text='For internal record-keeping', blank=True)

    time_started = models.DateTimeField(
        null=True,
        doc="The time at which the experimenter started the session")

    mturk_HITId = models.CharField(
        max_length=300, null=True, blank=True,
        help_text='Hit id for this session on MTurk')
    mturk_HITGroupId = models.CharField(
        max_length=300, null=True, blank=True,
        help_text='Hit id for this session on MTurk')
    mturk_qualification_type_id = models.CharField(
        max_length=300, null=True, blank=True,
        help_text='Qualification type that is '
                  'assigned to each worker taking hit')

    # since workers can drop out number of participants on server should be
    # greater than number of participants on mturk
    # value -1 indicates that this session it not intended to run on mturk
    mturk_num_participants = models.IntegerField(
        default=-1,
        help_text="Number of participants on MTurk")

    mturk_sandbox = models.BooleanField(
        default=True,
        help_text="Should this session be created in mturk sandbox?")

    archived = models.BooleanField(
        default=False,
        db_index=True,
        doc=("If set to True the session won't be visible on the "
             "main ViewList for sessions"))

    comment = models.TextField(blank=True)

    _anonymous_code = models.CharField(
        default=random_chars_10, max_length=10, null=False, db_index=True)

    _pre_create_id = models.CharField(max_length=300, db_index=True, null=True)

    use_browser_bots = models.BooleanField(default=False)

    # if the user clicks 'start bots' twice, this will prevent the bots
    # from being run twice.
    _cannot_restart_bots = models.BooleanField(default=False)
    _bots_finished = models.BooleanField(default=False)
    _bots_errored = models.BooleanField(default=False)
    _bot_case_number = models.PositiveIntegerField()

    is_demo = models.BooleanField(default=False)

    # whether SOME players are bots
    has_bots = models.BooleanField(default=False)

    def __unicode__(self):
        return self.code

    @property
    def participation_fee(self):
        '''This method is deprecated from public API,
        but still useful internally (like data export)'''
        return self.config['participation_fee']

    @property
    def real_world_currency_per_point(self):
        '''This method is deprecated from public API,
        but still useful internally (like data export)'''
        return self.config['real_world_currency_per_point']

    def is_for_mturk(self):
        return (not self.is_demo) and (self.mturk_num_participants > 0)

    def get_subsessions(self):
        lst = []
        app_sequence = self.config['app_sequence']
        for app in app_sequence:
            models_module = otree.common_internal.get_models_module(app)
            subsessions = models_module.Subsession.objects.filter(
                session=self
            ).order_by('round_number')
            lst.extend(list(subsessions))
        return lst

    def delete(self, using=None):
        for subsession in self.get_subsessions():
            subsession.delete()
        super(Session, self).delete(using)

    def get_participants(self):
        return self.participant_set.all()

    def get_human_participants(self):
        return self.participant_set.filter(_is_bot=False)

    def _create_groups_and_initialize(self):
        # group_by_arrival_time code used to be here
        for subsession in self.get_subsessions():
            subsession._create_groups()
            subsession.before_session_starts()
            subsession.save()

    def mturk_requester_url(self):
        if self.mturk_sandbox:
            requester_url = (
                "https://requestersandbox.mturk.com/mturk/manageHITs"
            )
        else:
            requester_url = "https://requester.mturk.com/mturk/manageHITs"
        return requester_url

    def mturk_worker_url(self):
        if self.mturk_sandbox:
            return (
                "https://workersandbox.mturk.com/mturk/preview?groupId={}"
            ).format(self.mturk_HITGroupId)
        return (
            "https://www.mturk.com/mturk/preview?groupId={}"
        ).format(self.mturk_HITGroupId)

    def advance_last_place_participants(self):

        # can't auto-advance bots, because that could break their
        # pre-determined logic
        # consider pros/cons of doing this
        participants = self.get_human_participants()

        # in case some participants haven't started
        unvisited_participants = []
        for p in participants:
            if p._index_in_pages == 0:
                unvisited_participants.append(p)
                client.get(p._start_url(), follow=True)

        if unvisited_participants:
            # that's it -- just visit the start URL, advancing by 1
            return

        last_place_page_index = min([p._index_in_pages for p in participants])
        last_place_participants = [
            p for p in participants
            if p._index_in_pages == last_place_page_index
        ]

        for p in last_place_participants:
            # what if first page is wait page?
            # that shouldn't happen, because then they must be
            # waiting for some other players who are even further back
            assert p._current_form_page_url
            try:
                resp = client.post(
                    p._current_form_page_url,
                    data={constants_internal.auto_submit: True}, follow=True
                )
            except:
                logging.exception("Failed to advance participants.")
                raise

            assert resp.status_code < 400

    def build_participant_to_player_lookups(self):
        subsession_app_names = self.config['app_sequence']

        views_modules = {}
        for app_name in subsession_app_names:
            views_modules[app_name] = (
                otree.common_internal.get_views_module(app_name))

        def views_module_for_player(player):
            return views_modules[player._meta.app_config.name]

        records_to_create = []

        for participant in self.get_participants():
            page_index = 0
            for player in participant.get_players():
                for View in views_module_for_player(player).page_sequence:
                    page_index += 1
                    records_to_create.append(
                        ParticipantToPlayerLookup(
                            participant=participant,
                            page_index=page_index,
                            app_name=player._meta.app_config.name,
                            player_pk=player.pk,
                            url=reverse(View.url_name(),
                                        args=[participant.code, page_index]))
                    )

            # technically could be stored at the session level
            participant._max_page_index = page_index
            participant.save()
        ParticipantToPlayerLookup.objects.bulk_create(records_to_create)

    def get_room(self):
        from otree.room import ROOM_DICT
        try:
            room_name = RoomToSession.objects.get(session=self).room_name
            return ROOM_DICT[room_name]
        except RoomToSession.DoesNotExist:
            return None


import unittest

from quick_sort_concept import quick_sort

class QuickSortTest(unittest.TestCase):

    def test_quick_sort_random_1(self):
        data = [4, 1, 10, 4, 4, 3, 9, 4, 1, 9]
        expected = [1, 1, 3, 4, 4, 4, 4, 9, 9, 10]
        output = quick_sort(data)
        self.assertEqual(expected, output)

    def test_quick_sort_random_2(self):
        data = [10, 3, 10, 9, 7, 9, 6, 2, 7, 7]
        expected = [2, 3, 6, 7, 7, 7, 9, 9, 10, 10]
        output = quick_sort(data)
        self.assertEqual(expected, output)

    def test_quick_sort_sorted_asc(self):
        data = [2, 3, 6, 7, 7, 7, 9, 9, 10, 10]
        expected = [2, 3, 6, 7, 7, 7, 9, 9, 10, 10]
        output = quick_sort(data)
        self.assertEqual(expected, output)

    def test_quick_sort_sorted_des(self):
        data = [10, 10, 9, 9, 7, 7, 7, 6, 3, 2]
        expected = [2, 3, 6, 7, 7, 7, 9, 9, 10, 10]
        output = quick_sort(data)
        self.assertEqual(expected, output)

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


"""
Steps for interacting with ZooKeeper or Clickhouse Keeper.
"""
import logging
import os

from behave import given
from kazoo.client import KazooClient
from modules.docker import get_container, get_exposed_port
from tenacity import retry, stop_after_attempt, wait_fixed

@given("a working zookeeper")
@retry(wait=wait_fixed(0.5), stop=stop_after_attempt(40))
def step_wait_for_zookeeper_alive(context):
    """
    Ensure that ZK is ready to accept incoming requests.
    """
    client = _zk_client(context)
    try:
        client.start()
    finally:
        client.stop()

@given("a working keeper on {node:w}")
@retry(wait=wait_fixed(0.5), stop=stop_after_attempt(20))
def step_wait_for_keeper_alive(context, node):
    """
    Wait until clickhouse keeper is ready to accept incoming requests.
    """
    client = _zk_client(context, instance_name=node, port=2281, use_ssl=True)
    try:
        client.start()
        client.get("/")
    except Exception:
        client.stop()
        raise
    finally:
        client.stop()

@given("we have removed ZK metadata for {node:w}")
def clean_zk_tables_metadata_for_host(context, node):
    """
    Remove all metadata for specified host from ZK
    """

    def recursive_remove_node_data(zk_client, path, node):
        for subpath in zk_client.get_children(path):
            if subpath == node:
                zk_client.delete(os.path.join(path, subpath), recursive=True)
            else:
                recursive_remove_node_data(zk_client, os.path.join(path, subpath), node)

    client = _zk_client(context)

    try:
        client.start()
        recursive_remove_node_data(client, "/", node)
    finally:
        client.stop()

def _zk_client(context, instance_name="zookeeper01", port=2181, use_ssl=False):
    # disable logging
    logging.getLogger("kazoo").setLevel(logging.CRITICAL)

    zk_container = get_container(context, instance_name)
    host, port = get_exposed_port(zk_container, port)

    return KazooClient(f"{host}:{port}", use_ssl=use_ssl, verify_certs=False)


"""
Usage:
  pgdatadiff --firstdb=<firstconnectionstring> --seconddb=<secondconnectionstring> [--only-data|--only-sequences] [--count-only] [--chunk-size=<size>]
  pgdatadiff --version

Options:
  -h --help          Show this screen.
  --version          Show version.
  --firstdb=postgres://postgres:password@localhost/firstdb        The connection string of the first DB
  --seconddb=postgres://postgres:password@localhost/seconddb         The connection string of the second DB
  --only-data        Only compare data, exclude sequences
  --only-sequences   Only compare seqences, exclude data
  --count-only       Do a quick test based on counts alone
  --chunk-size=10000       The chunk size when comparing data [default: 10000]
"""

import pkg_resources
from fabulous.color import red

from pgdatadiff.pgdatadiff import DBDiff
from docopt import docopt

def main():
    arguments = docopt(
        __doc__, version=pkg_resources.require("pgdatadiff")[0].version)
    first_db_connection_string=arguments['--firstdb']
    second_db_connection_string=arguments['--seconddb']
    if not first_db_connection_string.startswith("postgres://") or \
            not second_db_connection_string.startswith("postgres://"):
        print(red("Only Postgres DBs are supported"))
        return 1

    differ = DBDiff(first_db_connection_string, second_db_connection_string,
                    chunk_size=arguments['--chunk-size'],
                    count_only=arguments['--count-only'])

    if not arguments['--only-sequences']:
        if differ.diff_all_table_data():
            return 1
    if not arguments['--only-data']:
        if differ.diff_all_sequences():
            return 1
    return 0


from Redactor import Redactor
from Jefes import Jefe
from Secciones import Seccion

def get_redactores_entretenimiento():
    return[
        Redactor('leonardo',254488976)
    ]

def get_redactores_farandula():
    return[
        Redactor('andres',254488976)
    ]

def get_redactores_deportes():
    return[
        Redactor('guillermo',254488976)
    ]

def process_articles(seccion):
    print('\ninicio de labores en la seccion',seccion.nombre)
    print('el jefe al mando es: ',seccion.jefe.name)
    articles=[]
    for escritor in seccion.jefe.redactores_supervisados:
        print('el escritor en labor es:',escritor.name)
        articulo=escritor.escribir_articulo()
        articulo.redactor=escritor.name

        if seccion.jefe.decidir(articulo):
            articles.append(articulo)

def main():
    jefe_redactor_entretenimiento=Jefe('Jose Quevedo',25225,get_redactores_entretenimiento())
    jefe_redactor_farandula=Jefe('Juan Landaeta',25225,get_redactores_farandula())
    jefe_redactor_deportes=Jefe('Antonio Guerra',25225,get_redactores_deportes())

    seccion_entretenimiento=Seccion(jefe_redactor_entretenimiento,'Entretenimiento')
    seccion_farandula=Seccion(jefe_redactor_farandula,'Farandula')
    seccion_deportes=Seccion(jefe_redactor_deportes,'Deportes')

    process_articles(seccion_entretenimiento)
    process_articles(seccion_farandula)
    process_articles(seccion_deportes)

#github prof

main()


from ui.ui import Ui_App
from PyQt5 import QtWidgets,QtGui
import sys

from datetime import datetime
from process import *
class MainApplication(QtWidgets.QMainWindow):
    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        self.isSucces = False
        self.client_socket = None
        self.setWindowTitle("CANOpen Gateway")
        self.ui = Ui_App()
        self.ui.setupUi(self)
        self.show()
        self.ui.send.SaveAndConnectButton.clicked.connect(self.connectIP)
        self.ui.send.SendButton.clicked.connect(self.sendData)
        self.ui.send.DisConnectButton.clicked.connect(self.disconnectIP)
    def sendData(self):
        timeNow = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        if(self.isSucces):
            if(len(self.ui.send.EditSend.text()) > 0):
                _,message = send_data(self.client_socket,self.ui.send.EditSend.text())
                self.addToList("["+timeNow+"]:"+str(message))
            else:
                timeNow = datetime.now().strftime('%Y-%m-%d %H-%M-%S')
                self.addToList("["+timeNow+"]:Không có dữ liệu gửi đi !")
        else:
            timeNow = datetime.now().strftime('%Y-%m-%d %H-%M-%S')
            self.addToList("["+timeNow+"]:Gửi dữ liệu thất bại !")

    def addToList(self,str):
        new_item = QtGui.QStandardItem(str)
        self.ui.send.model.appendRow(new_item)
        self.ui.send.listView.setCurrentIndex(self.ui.send.model.indexFromItem(new_item))
    def closeEvent(self,event):
        disconnect_device(self.isSucces,self.client_socket)
        self.close()
    def disconnectIP(self):
        disconnect_device(self.isSucces,self.client_socket)
        self.ui.send.DisConnectButton.setStyleSheet("background-color: rgba(241,241,241,1);border:none;")
        self.ui.send.SaveAndConnectButton.setStyleSheet("")
    def connectIP(self):
        timeNow = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        if(len(self.ui.send.CANgatewayIP.text()) > 0):
            self.isSucces,self.client_socket = connect_device(self.ui.send.CANgatewayIP.text())
            if(self.isSucces):
                self.addToList("["+timeNow+"]:Kết nối thành công !")
                self.ui.send.SaveAndConnectButton.setStyleSheet("background-color: rgba(241,241,241,1);border:none;")
                self.ui.send.DisConnectButton.setStyleSheet("")
            else:
                self.addToList("["+timeNow+"]:Kết nối thất bại !")
        else:
            self.addToList("["+timeNow+"]:CAN getway IP trống. Vui lòng nhập!")
if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    w = MainApplication()
    sys.exit(app.exec_())


import __builtin__
import importlib
import maps
from mock import patch

from tendrl.commons.objects.cluster.atoms.delete_monitoring_details \
    import DeleteMonitoringDetails
from tendrl.commons.objects.cluster import Cluster
from tendrl.commons.objects.job import Job

def test_constructor():
    DeleteMonitoringDetails()

def save(*args):
    pass

def load(*args):
    return Cluster(short_name="test_short_name")

def load_job_finished(*args):
    return Job(job_id="uuid", status='finished')

def load_job_failed(*args):
    return Job(job_id="uuid", status='failed')

def init():
    setattr(__builtin__, "NS", maps.NamedDict())
    setattr(NS, "_int", maps.NamedDict())
    NS._int.etcd_kwargs = {
        'port': 1,
        'host': 2,
        'allow_reconnect': True}
    obj = importlib.import_module("tendrl.commons.tests.fixtures.client")
    NS._int.client = obj.Client()
    NS._int.wclient = obj.Client()

def test_run():
    init()
    obj = DeleteMonitoringDetails()
    assert obj.parameters is not None
    obj.parameters = maps.NamedDict()
    obj.parameters["TendrlContext.integration_id"] = \
        "test_uuid"
    obj.parameters['job_id'] = "test_job_id"
    obj.parameters['flow_id'] = "test_flow_id"
    setattr(NS, "tendrl", maps.NamedDict())
    setattr(NS, "tendrl_context", maps.NamedDict())
    NS.tendrl_context['integration_id'] = "rete"
    setattr(NS.tendrl, "objects", maps.NamedDict(Job=Job, Cluster=Cluster))
    NS.publisher_id = "publisher"
    with patch.object(Job, 'save', save):
        with patch.object(Job, 'load', load_job_finished):
            obj.run()

    # failure
    NS.publisher_id = maps.NamedDict()
    obj.parameters['flow_id'] = 'test_flow_id'

    with patch.object(NS.tendrl.objects.Job, 'save', save):
        with patch.object(Job, 'load', load_job_failed):
            obj.run()


import sys
import os
import multiprocessing
from PySide6.QtWidgets import QApplication, QDialog, QPushButton, QFileDialog, QLabel, QRadioButton, \
    QVBoxLayout, QComboBox, QCheckBox, QWidget
from PySide6 import QtWidgets, QtCore, QtGui
from const import AUDIO_RATE, AUDIO_INTERVAL,AUDIO_FRAMES_PER_BUFFER,\
    AI_INFERENCE_INTERVAL_DEFAULT,AI_SAVE_AUDIO_DEFAULT,AI_MELBINS,AI_NORM_MEAN,AI_NORM_STD,\
    AI_TARGET_LENGTH, AI_UINT16_MAX, UI_LOG_SHOW_MAX_LINE_NUM
import processes

def LOG_RED(string):
    return "" + string + "" " "

def LOG_GREEN(string):
    return "" + string + "" " "

class Form(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.joins=[]
        self.model = None
        self.player_flag_set = False
        self.logger_ng_flag_set = False
        self.logger_ok_flag_set = False
        self.inference_interval_set = AI_INFERENCE_INTERVAL_DEFAULT
        self.save_audio_set = AI_SAVE_AUDIO_DEFAULT
        self.log_queue = multiprocessing.Queue(maxsize=10)
        self.keepalive_queue = multiprocessing.Queue(maxsize=10)

        self.setWindowTitle("继电器尾音检测 V1.0")
        self.setting_label = QLabel("设置:", alignment=QtCore.Qt.AlignLeft)

        self.sync_btn = QCheckBox("同步播放开关")
        self.ng_btn = QCheckBox("显示NG")
        self.ok_btn = QCheckBox("显示OK")

        self.inter_label = QLabel("检测间隔(ms):", alignment=QtCore.Qt.AlignLeft)
        self.inter_cob = QComboBox(self)
        self.inter_cob.addItems(["1500", "2000", "2500"])

        self.save_label = QLabel("音频保存(ms):", alignment=QtCore.Qt.AlignLeft)
        self.save_cob = QComboBox(self)
        self.save_cob.addItems(["保存", "不保存"])

        self.btn_change_model = QPushButton("更改模型文件(.pth)")
        self.btn_run = QPushButton("开始")
        self.log = QtWidgets.QTextBrowser(self)
        self.log.moveCursor(QtGui.QTextCursor.End)

        #主layout
        self.global_layout = QVBoxLayout(self)

        # 网格layout， 控件分行列排列
        self.gridlayout = QtWidgets.QGridLayout(self)
        self.gridlayout.addWidget(self.setting_label, 1, 1)
        self.gridlayout.addWidget(self.sync_btn, 2, 1)
        self.gridlayout.addWidget(self.ng_btn, 2, 2)
        self.gridlayout.addWidget(self.ok_btn, 2, 3)
        self.gridlayout.addWidget(self.inter_label, 3, 1)
        self.gridlayout.addWidget(self.save_label, 3, 2)
        self.gridlayout.addWidget(self.inter_cob, 4, 1)
        self.gridlayout.addWidget(self.save_cob, 4, 2)

        # log， pretrain，run layout
        self.sub_layout = QVBoxLayout(self)
        self.sub_layout.addWidget(self.log)
        self.sub_layout.addWidget(self.btn_change_model)
        self.sub_layout.addWidget(self.btn_run)

        #  网格layout和sublayout还要被添加到一个QWidget里才能生效
        # 应用layout
        self.q1 = QWidget()
        self.q2 = QWidget()
        self.q1.setLayout(self.gridlayout)
        self.q2.setLayout(self.sub_layout)
        self.global_layout.addWidget(self.q1)
        self.global_layout.addWidget(self.q2)
        self.setLayout(self.global_layout)

        # 连接函数和button
        self.btn_change_model.clicked.connect(self.change_model)
        self.btn_run.clicked.connect(self.run)

    def change_model(self):
        """
        选择文件
        :return: None
        """
        self.model, file_type = QFileDialog.getOpenFileName(self, caption="choose file", dir=r'./')
        self.log_queue.put(f"模型路径： {self.model}")
        if self.model == '':
            print("Cancel choosing")

    def save_audio_cb_chang_value(self, v):
        self.save_audio_set = float(v.split('(')[-1][:-1])   # e.g. v=NG&OK(0.7)->0.7, 预测结果大于0.7的ok的尾音才被保存
        self.log_queue.put(f'{self.save_audio_cb_label.text()}{v}, 文件保存在工程目录下的save_audio文件夹里。')

    def inference_interval_cb_chang_value(self, v):
        self.inference_interval_set = int(v)
        self.log_queue.put(f'{self.inference_interval_cb_label.text()}{v}')

    def logger_ok_flag(self, checked):
        """
        显示OK
        :param checked:
        :return:
        """
        self.logger_ok_flag_set = checked
        if checked:
            self.log_queue.put(f'{self.logger_ok_button.text()}：已开启')
        else:
            self.log_queue.put(f'{self.logger_ok_button.text()}：已关闭')

    def logger_ng_flag(self, checked):
        """
        显示NG
        :param checked:
        :return:
        """
        self.logger_ng_flag_set = checked
        if checked:
            self.log_queue.put(f'{self.logger_ng_button.text()}：已开启')
        else:
            self.log_queue.put(f'{self.logger_ng_button.text()}：已关闭')

    def player_flag(self, checked):
        """
        播放录音
        :param checked:
        :return:
        """
        self.player_flag_set = checked
        if checked:
            self.log_queue.put(f'{self.play_button.text()}：已开启')
        else:
            self.log_queue.put(f'{self.play_button.text()}：已关闭')

    def run(self):
        """
        点击”开始“
        :return:
        """
        try:
            if self.btn_run.text() == '开始':
                self.q1.hide()  #隐藏网格widget
                self.btn_run.setText("结束")  # 等待用户点击“结束”
                if not self.model:
                    if not os.path.exists(r'.\model.pth'):
                        print("模型不存在")
                    else:
                        self.model = r'.\model.pth'
                self.log_queue.put("模型启动中...")
                #  预测尾音
                ret, self.joins = processes(self.model, self.log_queue, play_flag=self.player_flag_set,
                                               logger_ng_flag_set=self.logger_ng_flag_set,
                                               logger_ok_flag_set=self.logger_ok_flag_set,
                                               inference_interval_set=self.inference_interval_set,
                                               save_audio_set=self.save_audio_set,
                                               keepalive_queue=self.keepalive_queue,
                                               ).run()
                if not ret:
                    self.button_pth.show()
                    self.q1.show()
                    self.button_run.setText('开始')
                else:
                    self.log_queue.put('检测程序启动完成!')
            else:
                self.btn_change_model.show()
                self.q1.show()
                self.btn_run.setText("开始")
                for one in self.joins:
                    if one:
                        self.log_queue.put(f"{one.name}(PID:{one.pid},PPID:{os.getpid()}, PPPID:{os.getppid()})已退出")
                        one.kill()
        except Exception as e:
            print("Error occurs: ", str(e))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    form = Form()
    form.resize(480,320)
    form.show()
    sys.exit(app.exec())


from data_stark import*
import re

def extraer_iniciales(nombre_heroe):
    """
    Esta función toma un nombre de héroe como entrada y retorna sus iniciales.

    - Recibe: nombre_heroe (str) - El nombre del héroe.
    - Retorna: iniciales (str) - Las iniciales del héroe, sin "N/A".
    """
    if nombre_heroe.strip() == "":
        return "N/A"

    nombre = nombre_heroe.replace("the ", "").replace("-", " ")
    palabras = nombre.split()

    iniciales = []

    for palabra in palabras:
        inicial = ''.join (palabra[0].upper() + '.')
        iniciales.append(inicial)

    iniciales_unidas = ''.join(iniciales)
    resultado = re.sub('N.','',iniciales_unidas)

    return resultado

def definir_iniciales_nombre(heroe: dict):
    """
    Esta función recibe un diccionario de héroe y define sus iniciales en el diccionario.

    - Recibe: heroe (dict) - El diccionario del héroe con al menos una clave 'nombre'.
    - Retorna: True si las iniciales se definen con éxito, False en caso contrario.
    """
    if not type(heroe) == dict:
        return False

    if 'nombre' not in heroe:
        return False

    iniciales = f"({extraer_iniciales(heroe['nombre'])})"

    heroe['iniciales'] = iniciales

    return True

def agregar_iniciales_nombre(lista:list)->bool:
    """
    Esta función toma una lista de diccionarios de héroes y agrega las iniciales de nombre a cada héroe.

    - Recibe: lista (list) - Una lista de diccionarios de héroes, cada uno con al menos una clave 'nombre'.
    - Retorna: True si todas las iniciales se agregan con éxito, False en caso contrario.
    """
    if type(lista) == list and len(lista) > 0:
        for heroe in lista:
            if not definir_iniciales_nombre(heroe):
                print("Error: El origen de datos no contiene el formato correcto")
                return False

        return True

def stark_imprimir_nombres_con_iniciales(lista:list):
    """
    Esta función toma una lista de diccionarios de héroes, agrega iniciales a cada héroe y los imprime en un formato específico.

    - Recibe: lista (list) - Una lista de diccionarios de héroes, cada uno con al menos una clave 'nombre'.
    - No retorna ningún valor.
    """

    if type(lista) == list and len(lista) > 0:
        agregar_iniciales_nombre(lista)
        for personaje in lista:
            personaje = print(f"* {personaje['nombre']} {personaje['iniciales']}")

def generar_codigo_heroe(id_heroe:int, genero_heroe:str):
    """
    Esta función genera un código de héroe basado en su género y ID.

    - Recibe: id_heroe (int) - El ID del héroe y genero_heroe (str) - El género del héroe (F, M, o NB).
    - Retorna: Un código de héroe (str) o "N/A" si los parámetros son inválidos.
    """
    genero_heroe = genero_heroe.upper()

    if genero_heroe not in ["F","M","NB"] or genero_heroe == "" or type(id_heroe) != int:
        return "N/A"
    else:
        if genero_heroe == "F" or "M":
            codigo_heroe = f"{genero_heroe}-{str(id_heroe).zfill(8)}"
        else:
            codigo_heroe = f"{genero_heroe}-{str(id_heroe).zfill(7)}"

        return codigo_heroe

def agregar_codigo_heroe(heroe:dict,id_heroe:int):
    """
    agrega el código de héroe al diccionario del héroe y verifica su longitud.

    - Recibe: heroe (dict) - El diccionario del héroe con la clave 'genero' y id_heroe (int) - El ID del héroe.
    - Retorna: True si se agrega el código de héroe con éxito y tiene una longitud de 10 caracteres, False en caso contrario.
    """
    if heroe != {} and 'genero' in heroe:
        genero_heroe = heroe["genero"]
        heroe['codigo_heroe'] = generar_codigo_heroe(id_heroe,genero_heroe)
        if len(heroe["codigo_heroe"]) == 10:
            return True
        else: return False
    else: return False

def stark_generar_codigos_heroes(lista: list):
    """
    genera códigos de héroes para una lista de diccionarios de héroes y muestra información relacionada.

    - Recibe: lista (list) - Una lista de diccionarios de héroes.
    - No retorna ningún valor.
    """
    acumulador_id = 0
    for id_heroe,personaje in enumerate(lista,1):
        agregar_codigo_heroe(personaje,id_heroe)
        acumulador_id += 1

    print('''{}
    Se asignaron {} códigos
    * El código del primer héroe es: {}
    * El ultimo codigo agregado es: {}
    '''.format(generar_separador('*',50,False),acumulador_id, lista[0]['codigo_heroe'],lista[-1]['codigo_heroe']))

def sanitizar_entero(numero_str:str):
    """
    toma un string que representa un número entero, realiza un proceso de saneamiento y validación, y retorna
    el número entero si es válido. Si el número no es un entero positivo válido, la función retorna un valor específico
    para indicar si el número es negativo o si no es un entero válido.

    Parámetros:
        numero_str (str): Un string que representa el número entero.

    Retorna:
        int: El número entero si es válido.
        -1: Si el número no es un entero positivo válido.
        -2: Si el número representa un valor negativo.
    """
    # Quitar espacios en blanco al principio y al final del string
    numero_str = numero_str.strip()

    # Verificar si el primer carácter es un signo negativo
    if numero_str and numero_str[0] == '-':
        return -2

    # Patrón regex para verificar números enteros positivos
    patron = r'^\d+$'

    # Verificar si el string coincide con el patrón regex
    if re.search(patron, numero_str):
        # Convertir el string a entero y retornarlo
        return int(numero_str)
    else:
        # Si no coincide con el patrón, retornar -1
        return -1

def sanitizar_flotante(numero_str:str):
    """
    sanitiza una cadena para convertirla en un número flotante redondeado a 2 decimales.

    - Recibe: numero_str (str) - La cadena que se desea sanitizar.
    - Retorna: El número flotante redondeado a 2 decimales, -2 si es negativo, o -1 si no es válido.
    """
    numero_str = numero_str.strip()
    if numero_str and numero_str[0] == '-':
        return -2

    # Patrón regex para verificar números enteros positivos
    patron_flotante = r'^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$'

    # Verificar si el string coincide con el patrón regex
    if re.search(patron_flotante, numero_str):
         # Convertir el string a flotante y redondearlo a 2 decimales
        numero_flotante = float(numero_str)
        numero_redondeado = round(numero_flotante, 2)
        return numero_redondeado
    else:
        # Si no coincide con el patrón, retornar -1
        return -1

def sanitizar_string(valor_str: str, valor_por_defecto: str, parámetro_opcional='-'):
    """
    sanitiza una cadena de texto, realizando ciertas transformaciones y validaciones.

    - Recibe: valor_str (str) - La cadena que se desea sanitizar, valor_por_defecto (str) - El valor por defecto,
              y parámetro_opcional (str, opcional) - Un carácter opcional.
    - Retorna: La cadena sanitizada en minúsculas, el valor por defecto en minúsculas si valor_str está vacío y se proporciona un valor por defecto, o 'N/A' si no es válido.
    """
    valor_str = valor_str.strip()

    valor_str = valor_str.replace('/', ' ')

    # Verificar si valor_str es solo texto (sin números)
    if re.match('^[a-zA-Z ]*$', valor_str):
        # Si es solo texto, convertir a minúsculas
        valor_str = valor_str.lower()
    else:

        return 'N/A'

    # Si el valor_str está vacío y se proporciona un valor por defecto, retornar el valor por defecto en minúsculas
    if not valor_str and valor_por_defecto:
        return valor_por_defecto.lower()

    return valor_str

def sanitizar_dato(heroe: dict, clave: str, tipo_dato):
    """
    sanitiza un valor en el diccionario de un héroe de acuerdo al tipo de dato especificado.

    - Recibe: heroe (dict) - El diccionario del héroe, clave (str) - La clave del valor a sanitizar, tipo_dato (str) - El tipo de dato ('string', 'entero' o 'flotante').
    - Retorna: True si el valor se sanitiza con éxito, False si el tipo de dato no es reconocido.
    """
    tipo_dato = tipo_dato.lower()

    # Verificar si tipo_dato es válido
    if tipo_dato not in ['string','entero','flotante']:
        print('Tipo de dato no reconocido')
        return False
    else:
        if tipo_dato == 'string':
            heroe[clave] = sanitizar_string(heroe[clave], heroe[clave])
        elif tipo_dato == 'entero':
            heroe[clave] = sanitizar_entero(heroe[clave])
        elif tipo_dato == 'flotante':
            heroe[clave] = sanitizar_flotante(heroe[clave])

        return True

def stark_normalizar_datos(lista_heroes:list):
    """
    normaliza los datos de una lista de héroes, sanitizando ciertas claves de acuerdo a su tipo de dato.

    - Recibe: lista_heroes (list) - Una lista de diccionarios de héroes.
    - No retorna ningún valor.
    """
    if lista_heroes == []:
        print('La lista se encuentra vacia.')

    #las claves a sanitizar
    claves_a_sanitizar = ['altura', 'peso', 'color_ojos', 'color_pelo', 'fuerza', 'inteligencia']

    tipos_dato = {
        'altura': 'flotante',
        'peso': 'flotante',
        'color_ojos': 'string',
        'color_pelo': 'string',
        'fuerza': 'entero',
        'inteligencia': 'entero'
    }

    for heroe in lista_heroes:
        for clave in claves_a_sanitizar:
            # Verificar si la clave existe en el héroe
            if clave in heroe:
                # Obtener el tipo de dato apropiado para la clave
                tipo_dato = tipos_dato.get(clave, 'string')  # Por defecto, considerar 'string'

                # Sanitizar el dato utilizando la función sanitizar_dato
                sanitizar_dato(heroe, clave, tipo_dato)
                print(f"Sanitizado: {clave} de {heroe['nombre']}")

    print("\nDatos normalizados")

def generar_indice_nombres(lista_heroes):
    """
    Esta función genera un índice de nombres a partir de una lista de héroes.

    - Recibe: lista_heroes (list) - Una lista de diccionarios de héroes.
    - Retorna: Una lista de palabras individuales que conforman los nombres de los héroes, o None si la lista está vacía o no contiene el formato correcto.
    """
    lista_nombres = []

    if len(lista_heroes) == 0:
        print('El origen de datos no contiene el formato correcto')
        return  # Termina la función si la lista está vacía

    for personaje in lista_heroes:
        if isinstance(personaje, dict) and 'nombre' in personaje:
            nombre = personaje['nombre']
            # Dividir el nombre en palabras
            palabras = nombre.split()
            # Extiender la lista con los nombres
            lista_nombres.extend(palabras)

    if len(lista_nombres) == 0:
        print('El origen de datos no contiene el formato correcto')
    else:
        return lista_nombres

def stark_imprimir_indice_nombre(lista_heroes: list):
    """
    Esta función genera un índice de nombres a partir de una lista de héroes y lo imprime en un formato específico.

    - Recibe: lista_heroes (list) - Una lista de diccionarios de héroes.
    - No retorna ningún valor.
    """
    lista_nombres = generar_indice_nombres(lista_heroes)
    lista_formateada = '-'.join(lista_nombres)
    print(lista_formateada)

def convertir_cm_a_mtrs(valor_cm:float):
    """
    Esta función convierte centímetros a metros y retorna el valor resultante.

    - Recibe: valor_cm (float) - El valor en centímetros a ser convertido.
    - Retorna: El valor en metros (float) redondeado a 2 decimales, o -1 si el valor no es válido.
    """
    if type(valor_cm) == float and valor_cm > 0:
        valor_mts = valor_cm / 100
        valor_mts_formateado = round(valor_mts,2)
        return valor_mts_formateado
    else:
        return -1

def generar_separador(patron: str, largo: int, imprimir=True):
    """
    Esta función genera un separador utilizando un patrón y un largo especificados, y opcionalmente lo imprime.

    - Recibe: patron (str) - El patrón a repetir, largo (int) - La cantidad de veces a repetir el patrón,
              e imprimir (bool, opcional) - Un indicador para imprimir el separador.
    - Retorna: El separador (str) generado, o "N/A" si los valores no son válidos.
    """
    # Validación del patrón
    if not (1 <= len(patron) <= 2):
        return "N/A"

    # Validación del largo
    if not (1 <= largo <= 235):
        return "N/A"

    separador = patron * largo

    if imprimir:
        print(separador)

    return separador

def generar_encabezado(titulo:str):
    """
    Esta función genera un encabezado con un título en mayúsculas y un separador.

    - Recibe: titulo (str) - El título a ser incluido en el encabezado.
    - No retorna ningún valor, imprime el encabezado.
    """
    titulo_mayus = titulo.upper()
    separador = generar_separador('*',100,False)

    print(separador + "\n" + titulo_mayus + "\n" + separador)

def imprimir_ficha_heroe(heroe: dict)->str:
    """
    Esta función imprime la ficha de un héroe con información detallada.

    - Recibe: heroe (dict) - Un diccionario con información del héroe.
    - No retorna ningún valor, imprime la ficha del héroe.
    """
    nombre = heroe['nombre']
    iniciales = heroe['iniciales']
    identidad = heroe['identidad']
    consultora = heroe['empresa']
    codigo = heroe['codigo_heroe']
    altura = convertir_cm_a_mtrs(heroe['altura'])
    peso = heroe['peso']
    fuerza = heroe['fuerza']
    color_ojos = heroe['color_ojos']
    color_pelo = heroe['color_pelo']

    generar_encabezado("PRINCIPAL")
    print(f"NOMBRE DEL HÉROE: {nombre} {iniciales}")
    print(f"IDENTIDAD SECRETA: {identidad}")
    print(f"CONSULTORA: {consultora}")
    print(f"CODIGO DE HEROE: {codigo}")

    generar_encabezado("FISICO")
    print(f"ALTURA: {altura}Mts")
    print(f"PESO: {peso}Kg")
    print(f"FUERZA: {fuerza}")

    generar_encabezado("SEÑAS PARTICULARES")
    print(f"COLOR OJOS: {color_ojos}")
    print(f"COLOR PELO: {color_pelo}")

def stark_navegar_fichas(lista_heroes:list):
    """
    Esta función permite navegar a través de las fichas de héroes en una lista y visualizar la información de cada héroe.

    - Recibe: lista_heroes (list) - Una lista de diccionarios de héroes.
    - No retorna ningún valor, interactúa con el usuario para navegar las fichas de héroes.
    """
    navegar = True
    posicion_actual = 0

    while(navegar):
        imprimir_ficha_heroe(lista_heroes[posicion_actual])

        opcion = input('ingrese la opcion deseada: [ 1 ] Ir a la izquierda [ 2 ] Ir a la derecha [ S ] Salir ')

        if opcion == '1':
            if posicion_actual > 0:
                posicion_actual -= 1
            else:
                posicion_actual = len(lista_heroes) -1
        elif opcion == '2':
            if posicion_actual < len(lista_heroes) - 1:
                posicion_actual += 1
            else:
                posicion_actual = 0

        elif opcion.lower() == 's':
            navegar = False
        else:
            print("Opción no válida. Por favor, elige una opción válida.")

def imprimir_menu():
    """
    Esta función imprime un menú de opciones para el usuario.

    - No recibe ningún valor.
    - No retorna ningún valor, imprime el menú en la consola.
    """
    print('\n1 - Imprimir la lista de nombres junto con sus iniciales')
    print('2 - Generar códigos de héroes')
    print('3 - Normalizar datos')
    print('4 - Imprimir índice de nombres')
    print('5 - Navegar fichas')
    print('S - Salir')
    print('____________________________________________________________\n')

def stark_menu_principal():
    """
    Esta función muestra el menú principal y permite al usuario ingresar una opción.

    - No recibe ningún valor.
    - Retorna: La opción ingresada por el usuario como una cadena.
    """
    imprimir_menu()
    opcion_ingresada = input('Ingrese una opcion: ')
    return opcion_ingresada

def stark_marvel_app_4(lista_heroes: list):
    """
    Esta función representa una aplicación que permite interactuar con los héroes y sus datos.

    - Recibe: lista_heroes (list) - Una lista de diccionarios de héroes.
    - No retorna ningún valor, interactúa con el usuario a través del menú principal.
    """
    opcion_uno_ejecutada = False
    opcion_dos_ejecutada = False
    while True:
        opcion = stark_menu_principal()

        if opcion == '1':
            stark_imprimir_nombres_con_iniciales(lista_heroes)
            opcion_uno_ejecutada = True
        elif opcion == '2':
            stark_generar_codigos_heroes(lista_personajes)
            opcion_dos_ejecutada = True
        elif opcion == '3':
            stark_normalizar_datos(lista_heroes)
        elif opcion == '4':
            stark_imprimir_indice_nombre(lista_personajes)
        elif opcion == '5':
            if opcion_uno_ejecutada and opcion_dos_ejecutada:
                stark_navegar_fichas(lista_personajes)
            else:
                print('Para ejecutar esta opcion es necesario ejecutar la opcion 1 y 2 primero. ')
        elif opcion == 's':
            break
        else:
            print('ERROR, Ingresa una opcion valida')

stark_marvel_app_4(lista_personajes)


import os, sys
import requests
import base64
from ast import literal_eval
import pyaudio, wave, soundfile

class TTS():
    def __init__(self) -> None:
        self.speaker_x = 2.67
        self.speaker_y = 1.88

    def _get_audio(self, message, style):
        if os.path.exists("temp.wav"):
            os.remove("temp.wav")
        # POSTメソッドのみ対応 curl --location 'https://api.rinna.co.jp/models/cttse/koeiro' --header 'Content-Type: application/json' --data '{"text": "こんにちは",  "speaker_x": 0.0,  "speaker_y": 0.0,  "style": "talk"}'
        # use requests
        url = 'https://api.rinna.co.jp/models/cttse/koeiro'
        headers = {'Content-Type': 'application/json'}
        data = {
            'text': message,
            'speaker_x': self.speaker_x,
            'speaker_y': self.speaker_y,
            'style': style
        }
        response = requests.post(url, headers=headers, json=data)
        if response.status_code == 200:
            # save as temp.wav
            encoded_audio = literal_eval(response.content.decode('utf-8'))["audio"].split(",")[1] # base 64 encoded
            wav_file = open("temp.wav", "wb")
            decode_audio = base64.b64decode(encoded_audio)
            wav_file.write(decode_audio)
            wav_file.close()

            # change temp.wave to 16-bit wav file
            with open('temp.wav', 'rb') as f:
                data, samplerate = soundfile.read(f)
                soundfile.write('temp.wav', data, samplerate, subtype='PCM_16')
            return
        else:
            print('Error: ', response.status_code)
            return

    def say(self, message, style):
        # style:
        #   talk: 通常の話し声
        #   happy: 嬉しい
        #   sad: 悲しい
        #   angry: 怒った
        #   fear: 恐怖
        #   surprise: 驚いた
        self._get_audio(message, style)
        self.play()

    def play(self):
        # play temp.wav
        CHUNK = 1024
        wf = wave.open("temp.wav", 'rb')
        p = pyaudio.PyAudio()
        stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
                        channels=wf.getnchannels(), rate=wf.getframerate(), output=True)
        data = wf.readframes(CHUNK)
        while data != b'':
            stream.write(data)
            data = wf.readframes(CHUNK)
        stream.stop_stream()
        stream.close()
        wf.close()
        p.terminate()
        # os.remove("temp.wav")

if __name__ == '__main__':
    tts = TTS()
    tts.say('こんにちは', style='happy')


import cv2
import numpy as np

prototxt_path = r"./deploy.prototxt.txt"
model_path =r"./res10_300x300_ssd_iter_140000_fp16.caffemodel"

model = cv2.dnn.readNetFromCaffe(prototxt_path, model_path)
image = cv2.imread("test_8.jpg")
h, w = image.shape[:2]
blob = cv2.dnn.blobFromImage(image, 1.0, (300, 300),(104.0, 177.0, 123.0))
model.setInput(blob)
output = np.squeeze(model.forward())
font_scale = 1.0
for i in range(0, output.shape[0]):
    confidence = output[i, 2]
    if confidence > 0.5:
        box = output[i, 3:7] * np.array([w, h, w, h])
        start_x, start_y, end_x, end_y = box.astype(np.int)
        cv2.rectangle(image, (start_x, start_y), (end_x, end_y), color=(255, 0, 0), thickness=2)
        cv2.putText(image, f"{confidence*100:.2f}%", (start_x, start_y-5), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (255, 0, 0), 2)
cv2.imshow("image", image)
cv2.waitKey(0)
cv2.imwrite("beauty_detected.jpg", image)


import os
import glob
import shutil

class DirectoryCleaner(object):

    def __init__(self):
        self.names = list()

    def file_names(self):
        """
        Adds all file extensions in current path to self.names.
        """
        files = os.listdir()
        exts = {os.path.splitext(i)[1] for i in files if os.path.isfile(i)}
        for i in exts:
            self.names.append(i[1:])

    def create_dir(self):
        """
        Creates new directories with file extension names given in self.names.
        """
        for i in self.names:
            try:
                os.makedirs(i)
                print(f"Created {i} directory.")
            except Exception:
                print(f"Folder name with \'{i}\' already exists.")

    def move_files(self, ext: str):
        """
        Moves files into new directories specified by file extension.
        """
        for i in glob.glob('*.' + ext):
            try:
                if (os.path.isdir(os.getcwd() + f'/{ext}')):
                    shutil.move(i, ext)
            except Exception:
                print(f"Folder \'{ext}\' has not been created yet.")
                break

a = DirectoryCleaner()
a.file_names()


n = int(input('''
	\nDigite um progrma para ver
o seu fatorial: '''))

cont = n
fatorial = 1

while cont > 0:
    resultado =  cont * (cont-1)
    fatorial *= cont
    cont-=1

    print ('{}'.format(resultado),end=' ')
    print ('x ' if cont > 0 else '= ', end ='')
print(fatorial)

Python 3 - Estrutura de Controle/Desafio 60.py


import pandas as pd

import sys
sys.path.append('./')
from features import features
from metrics import average_precision

from collections import defaultdict
from surprise import Dataset
from surprise import Reader
from surprise import SVD
from surprise import accuracy
from surprise.model_selection import train_test_split

train = pd.read_csv('./input/train.csv', parse_dates=['datetime'])
test = pd.read_csv('./input/test.csv')

# to remove usercode not in test
# user_test = set(test['userCode'].values)
# train = train[train['userCode'].isin(user_test)]
# print(len(train), len(test))

# count userCode feature
gp, name_col = features.count_duplicate(train, group_cols=['userCode', 'project_id'])
train = train.merge(gp, on=['userCode', 'project_id'], how='left')
# print(name_col, train.head(), (1, train[name_col].max()))

#drop duplicate
train = train.drop_duplicates(['userCode','project_id'],keep= 'last')
print(len(train), len(test))

#to scale
scale = train[name_col].max()
train[name_col] = train[name_col].apply(lambda x: x/scale)
print('max: ',train[name_col].max())

reader = Reader(rating_scale=(0, 1))

trainset = Dataset.load_from_df(train[["userCode", "project_id", name_col]], reader)
trainset = trainset.build_full_trainset()
algo = SVD()
algo.fit(trainset)

# Than predict ratings for all pairs (u, i) that are NOT in the training set.
testset = trainset.build_anti_testset()
predictions = algo.test(testset)

accuracy.rmse(predictions, verbose=True)

def get_top_n(predictions, n=10):
    # First map the predictions to each user.
    top_n = defaultdict(list)
    for uid, iid, true_r, est, _ in predictions:
        top_n[uid].append((iid, est))

    # Then sort the predictions for each user and retrieve the k highest ones.
    for uid, user_ratings in top_n.items():
        user_ratings.sort(key=lambda x: x[1], reverse=True)
        top_n[uid] = user_ratings[:n]

    return top_n

top_n = get_top_n(predictions, n=7)

#evaluate
actual_list = [[pid] for pid in test['project_id'].values]
predicted_list = [[project_id for (project_id, _) in top_n[uid]]for uid in test['userCode'].values]

print(average_precision.mapk(actual_list, predicted_list))

# Print the recommended items for each user
# for uid, ratings in top_n.items():
#     print(uid, [(project_id, rating) for (project_id, rating) in ratings])


from sympy import Function
from sympy.core.numbers import Integer, IntegerConstant

class MaxCompl(Function):
    name = "MaxCompl"

    @classmethod
    def eval(cls, m, n):
        if isInt(m):
            return n
        if isInt(n):
            return m

    def doit(self, deep=False, **hints):
        m, n = self.args
        if deep:
            m, n = m.doit(deep=deep, **hints), n.doit(deep=deep, **hints)

def isInt(x):
    return isinstance(x, (int, Integer, IntegerConstant))


# -*- coding: utf-8 -*-
"""
Created on Thu Nov  9 12:54:02 2017

@author: linjian_sx
jiezhen change:
    line24 => 25
    line44 => 45
"""

from datetime import datetime
import numpy as np
import os, sys, cv2
import random
import time
from PIL import Image, ImageDraw, ImageFont

#os.environ["CUDA_VISIBLE_DEVICES"] = ""
os.environ["CUDA_VISIBLE_DEVICES"] = "0"

if __name__ == '__main__':
    videoFilePath = r"/root/linjian/darknet_0/video/"
    temp_jpgPath = r"/root/temp_testdiff/"
    txt = open(r'/root/linjian/darknet_0/video/video116_ffmpegdiff.txt','a')
#    videoFile = cv2.VideoCapture(videoFilePath+'test2.mkv')

#    msec = int(videoFile.get(cv2.cv.CV_CAP_PROP_POS_MSEC))

#    fourcc = cv2.cv.CV_FOURCC('M', 'J', 'P', 'G') # motion-JPEG code
##6.14    out = videoFilePath+'video2_img_init'
##6.14    out_diff = videoFilePath+'video2_img_diff'
#    all_img = videoFilePath+'all_img-v2'
#    tiny_pick = videoFilePath+'tiny_pick-v3'
#    out = cv2.VideoWriter("/home/jz/JZ-working/e2ediff0_ZF_output.avi",
#                          fourcc, fps, size)
    i = 0
    num = 0
    jpg_list = os.listdir(temp_jpgPath)
    jpg_list.sort(key=lambda jpg:int(jpg.split('.')[0]))
    for jpg in jpg_list:
#        print"==========="
        find_obj = os.path.join(temp_jpgPath, jpg)
        image = cv2.imread(find_obj)
##ERROR        image = Image.open(find_obj)
##ERROR        image = np.array(image)
#        gray_img = cv2.CvtColor(image, cv2.COLOR_BGR2GRAY)
#        print ret
#        print image, type(image)
#        print(image.shape)
##6.14        cv2.imwrite(os.path.join(out, str(i)+'-'+time_str+'.jpg'), image)
        print("============== "+str(i)+" ============")
        if i == 0:
#            last_gray = gray_img
            last_BGR = image
        else:
#            frameDelta_gray = cv2.AbsDiff(last_gray, gray_img)
            frameDelta_BGR = cv2.absdiff(last_BGR, image)
            frameDelta_gray = cv2.cvtColor(frameDelta_BGR, cv2.COLOR_BGR2GRAY)

            mean_gray = np.mean(frameDelta_gray)
            mean_BGR = np.mean(frameDelta_BGR, axis=2)    #w*h
            BGR_nonZero = cv2.countNonZero(mean_BGR)
            gray_nonZero = cv2.countNonZero(frameDelta_gray)
#            print(frameDelta_gray.shape)
##6.14            cv2.imwrite(os.path.join(out_diff, str(i)+'-'+time_str+'.jpg'), frameDelta_BGR)
            print("-----"+str(mean_gray)+"-----")
#            print("-----"+str(mean_BGR)+"-----")
#            print("-----"+str(diff_nonZero)+"-----")
            txt.write(str(mean_gray)+' '+str(BGR_nonZero)+' '+str(gray_nonZero)+' '+jpg+'\n')
#            last_gray = gray_img
            last_BGR = image
            if i == 10000:
                break
        i = i+1
    txt.close()
#    videoFile.release()

#eval()


import project_euler
import math

count = 0
for d in range(2, 12000 + 1):
    for n in range(max(1, math.floor(d / 3)), math.ceil(d / 2)):
        if n / d > 1/3 and n / d < 1/2:
            if project_euler.gcd(n, d) == 1:
                count += 1

    if d % 120 == 0:
        print('.', end="", flush=True)

print(count)


"""Development tasks."""

import os
import sys
from pathlib import Path
from shutil import which

from duty import duty

PY_SRC_PATHS = (Path(_) for _ in ("src", "tests", "duties.py", "docs/macros.py"))
PY_SRC_LIST = tuple(str(_) for _ in PY_SRC_PATHS)
PY_SRC = " ".join(PY_SRC_LIST)
TESTING = os.environ.get("TESTING", "0") in {"1", "true"}
CI = os.environ.get("CI", "0") in {"1", "true", "yes", ""}
WINDOWS = os.name == "nt"
PTY = not WINDOWS and not CI

@duty(pre=["check_docs", "check_dependencies"])
def check(ctx):
    """
    Check it all!

    Arguments:
        ctx: The context instance (passed automatically).
    """

@duty
def check_dependencies(ctx):
    """
    Check for vulnerabilities in dependencies.

    Arguments:
        ctx: The context instance (passed automatically).
    """
    nofail = False
    safety = which("safety")
    if not safety:
        pipx = which("pipx")
        if pipx:
            safety = f"{pipx} run safety"
        else:
            safety = "safety"
            nofail = True
    ctx.run(
        f"poetry export -f requirements.txt --without-hashes | {safety} check --stdin --full-report",
        title="Checking dependencies",
        pty=PTY,
        nofail=nofail,
    )

@duty
def check_docs(ctx):
    """
    Check if the documentation builds correctly.

    Arguments:
        ctx: The context instance (passed automatically).
    """
    Path("build/coverage").mkdir(parents=True, exist_ok=True)
    Path("build/coverage/index.html").touch(exist_ok=True)
    ctx.run("mkdocs build -s", title="Building documentation", pty=PTY)

@duty
def check_types(ctx):
    """
    Check that the code is correctly typed.

    Arguments:
        ctx: The context instance (passed automatically).
    """
    ctx.run(f"mypy --config-file config/mypy.ini {PY_SRC}", title="Type-checking", pty=PTY)

@duty(silent=True)
def clean(ctx):
    """
    Delete temporary files.

    Arguments:
        ctx: The context instance (passed automatically).
    """
    ctx.run("rm -rf .coverage*")
    ctx.run("rm -rf .mypy_cache")
    ctx.run("rm -rf .pytest_cache")
    ctx.run("rm -rf tests/.pytest_cache")
    ctx.run("rm -rf build")
    ctx.run("rm -rf dist")
    ctx.run("rm -rf pip-wheel-metadata")
    ctx.run("rm -rf site")
    ctx.run("find . -type d -name __pycache__ | xargs rm -rf")
    ctx.run("find . -name '*.rej' -delete")

@duty
def docs(ctx):
    """
    Build the documentation locally.

    Arguments:
        ctx: The context instance (passed automatically).
    """
    ctx.run("mkdocs build", title="Building documentation")

@duty
def docs_serve(ctx, host="127.0.0.1", port=8000):
    """
    Serve the documentation (localhost:8000).

    Arguments:
        ctx: The context instance (passed automatically).
        host: The host to serve the docs from.
        port: The port to serve the docs on.
    """
    ctx.run(f"mkdocs serve -a {host}:{port}", title="Serving documentation", capture=False)

@duty
def docs_deploy(ctx):
    """
    Deploy the documentation on GitHub pages.

    Arguments:
        ctx: The context instance (passed automatically).
    """
    ctx.run("mkdocs gh-deploy", title="Deploying documentation")

@duty
def release(ctx, version):
    """
    Release a new Python package.

    Arguments:
        ctx: The context instance (passed automatically).
        version: The new version number to use.
    """
    ctx.run(f"poetry version {version}", title=f"Bumping version in pyproject.toml to {version}", pty=PTY)
    ctx.run(f'gsed --in-place  "s/__version__ = .*/__version__ = \\"{version}\\"/g" src/kmerpapa/__init__.py')
    ctx.run("git add pyproject.toml src/kmerpapa/__init__.py", title="Staging files", pty=PTY)
    ctx.run(["git", "commit", "-m", f"chore: Prepare release {version}"], title="Committing changes", pty=PTY)
    ctx.run(f"git tag v{version}", title="Tagging commit", pty=PTY)
    if not TESTING:
        ctx.run("git push", title="Pushing commits", pty=False)
        ctx.run("git push --tags", title="Pushing tags", pty=False)
        ctx.run("poetry build", title="Building dist/wheel", pty=PTY)
        ctx.run("poetry publish -u __token__ -p $POETRY_PYPI_TOKEN_PYPI ", title="Publishing version", pty=PTY)
        #docs_deploy.run()  # type: ignore

@duty(silent=True)
def coverage(ctx):
    """
    Report coverage as text and HTML.

    Arguments:
        ctx: The context instance (passed automatically).
    """
    ctx.run("coverage combine .coverage-*", nofail=True)
    ctx.run("coverage report --rcfile=config/coverage.ini", capture=False)
    ctx.run("coverage html --rcfile=config/coverage.ini")

@duty
def test(ctx, match: str = ""):
    """
    Run the test suite.

    Arguments:
        ctx: The context instance (passed automatically).
        match: A pytest expression to filter selected tests.
    """
    py_version = f"{sys.version_info.major}{sys.version_info.minor}"
    os.environ["COVERAGE_FILE"] = f".coverage-{py_version}"
    ctx.run(
        ["pytest", "-c", "config/pytest.ini", "-n", "auto", "-k", match, "tests"],
        title="Running tests",
        pty=PTY,
    )


trans = {'0':'ling', '1':'yi', '2':'er', '3':'san', '4': 'si', '5':'wu',
         '6':'liu', '7':'qi', '8':'ba', '9':'jiu', '10': 'shi', '100': 'bai'}

def speak_Chinese(number):
    '''
    number: an integer, 0<=number<=999

    Returns: a string that is the number in Chinese
    '''
    while number < 1000:
        # print("Hello, I can help you translate some numbers into Mandarin!")
        # number = int(input("Please input a number (0-999) to translate into Mandarin: "))
        #r1 these are the words for each of the digits from 0-10
        if number < 11:
            r1 = str(number)
            a = trans[r1]
            return a  #returns the value a for the key r1

        #r2 for numbers 11-19 number is "ten digit" ex: 16 = ten six
        if number > 10 and number < 20:
            r2 = number - 10
            r1 = str(r2)
            b = trans[r1]
            return 'shi' + ' ' + b

        #r3.a for numbers between 20 and 99 number is digit ten digit ex: 37 = three ten seven
        #r3.b if digit is a zero it is not included and it is digit ten ex: 50 = five ten
        if number > 19 and number < 100:
            if number % 10 != 0:
                r3_a = str(number)
                for number in r3_a:
                    left = r3_a[0]
                    tleft = trans[left]
                    right = r3_a[-1]
                    tright = trans[right]
                    return tleft + " " + "shi" + " " + tright
            else:
                r3_b = int(number/10)
                d = str('{:d}'.format(r3_b))
                c = trans[d]
                return c + ' ' + "shi"

        #r4 number 100 is one hundred
        if number % 100 == 0:
            r4 = int(number/100)
            d = str('{:d}'.format(r4))
            c = trans[d]
            return c + ' ' + "bai"

        #r5 for numbers between 101 and 999 if second digit is 0 then its digit hundred zero digit
        #ex 307 is three hundred zero seven
        if number > 100 and number < 1000:
            r5 = str(number)
            if r5[1] == 0 and r5[-1] != 0:
                left = r5[0]
                tleft = trans[left]
                right = r5[-1]
                tright = trans[right]
                return tleft + " " + "bai" + " " + "ling" + " " + tright
        #r6.a if second digit is not zero then its digit hundred digit ten digit
        #ex 537 is five hundred three ten seven
        #r6.b if the last digit is a zero then its not included
        #ex 450 is four hundred five ten
            elif r5[1] != 0 and r5[-1] != 0:
                left = r5[0]
                tleft = trans[left]
                right = r5[-1]
                tright = trans[right]
                mid = r5[1]
                tmid = trans[mid]
                return tleft + " " + "bai" + " " + tmid + " " + "shi" + " " + tright
            else:
                left = r5[0]
                tleft = trans[left]
                mid = r5[1]
                tmid = trans[mid]
                return tleft + " " + "bai" + " " + tmid + "shi"
    # else:
    #     return "Sorry, I can't translate numbers above 999, try again"
    ## added the while loop in case i had time to retouch it

# For testing
def main():
    print(speak_Chinese(36))
    print('In Chinese: 36 = san shi liu')
    print(speak_Chinese(20))
    print('In Chinese: 20 = er shi')
    print(speak_Chinese(16))
    print('In Chinese: 16 = shi liu')
    print(speak_Chinese(200))
    print('In Chinese: 200 = er bai')
    print(speak_Chinese(109))
    print('In Chinese: 109 = yi bai ling jiu')
    print(speak_Chinese(999))
    print('In Chinese: 999 = jiu bai jiu shi jiu')

if __name__ == '__main__':
    main()


from . import Models

class AttendedModel:

    def CreateConfirmAttend(self, payloads):
        query = "INSERT INTO attended (customer_id, counter_id, reader_payloads) VALUE "
        query += "("
        query += "'{}', ".format(payloads['customer_id'])
        query += "'{}', ".format(payloads['counter_id'])
        query += "'{}'".format(payloads['reader_payloads'].replace("'","''"))
        query += ")"
        Models().mysql_insert_query(query)

    def create_confirm_trail(self, payloads):
        query = "INSERT INTO reader_trail (reader_payloads) VALUE "
        query += "("
        query += "'{}'".format(payloads['reader_payloads'].replace("'","''"))
        query += ")"
        Models().mysql_insert_query(query)
        self.__update_person_status(payloads['customer_id'])

    def __update_person_status(self, id):
        query = "UPDATE registered_person SET current_status = current_status + 1 WHERE id = {} ".format(int(id))
        Models().mysql_insert_query(query)

    def ReadAttendedCustomer(self):
        query = "SELECT count(id) AS total, "
        query += "reader_payloads->>\"$.sitting_zone\" AS sitting_zone "
        query += "FROM attended "
        query += "GROUP BY reader_payloads->>\"$.sitting_zone\" "
        return Models().mysql_execute_query(query)

    def get_attended_list(self, zone):
        query = "SELECT date_format(timestamp,'%d/%m/%Y %H:%i:%s') as clock_in, "
        query += "reader_payloads "
        query += "FROM attended WHERE reader_payloads->>'$.sitting_zone' = '{}'".format(zone)
        return Models().mysql_execute_query(query)

    def get_customer_filter(self, filter_data):
        query = "SELECT c.*, "
        query += "(SELECT count(id) as total from attended where customer_id = c.id) as 'attended' "
        query += "FROM customer_real c "
        query += "WHERE 1 "
        query += "AND c.code = '{}' ".format(filter_data['qr_code']) if filter_data['qr_code'] != None else ""
        query += "AND c.phone LIKE \"%{}\" ".format(filter_data['phone']) if filter_data['phone'] != None else ""
        query += "AND c.name LIKE \"%{}%\" ".format(filter_data['name']) if filter_data['name'] != None else ""
        query += "AND c.email LIKE '%{}%' ".format(filter_data['email'])  if filter_data['email'] != None else ""
        print(query)
        return Models().mysql_execute_query(query)


import airsimdroneracinglab as adrl
import numpy as np
import threading
import time
import math

# taken from the ADRL repo "baselines"
class BaseRacer:
    def __init__(
            self,
            drone_name="drone_1",
            viz_traj=True,
            viz_traj_color_rgba=(1.0, 0.0, 0.0, 1.0)
    ):
        self.drone_name = drone_name
        self.gate_poses_ground_truth = None
        self.viz_traj = viz_traj
        self.viz_traj_color_rgba = viz_traj_color_rgba

        self.airsim_client = adrl.MultirotorClient()
        self.airsim_client.confirmConnection()

        self.airsim_client_odom = adrl.MultirotorClient()
        self.airsim_client_odom.confirmConnection()
        self.level_name = None

        self.odometry_callback_thread = threading.Thread(
            target=self.repeat_timer_odometry_callback,
            args=(self.odometry_callback, 0.02),
        )

        self.is_odometry_thread_active = False

        self.position = None
        self.linear_velocity = None
        self.angular_velocity = None
        self.orientation = None
        self.timestamp = 0

        self.MAX_NUMBER_OF_GETOBJECTPOSE_TRIALS = (
            10  # see https://github.com/microsoft/AirSim-Drone-Racing-Lab/issues/38
        )

    # loads desired level
    def load_level(self, level_name, sleep_sec=2.0):
        self.level_name = level_name
        self.airsim_client.simLoadLevel(self.level_name)
        self.airsim_client.confirmConnection()  # failsafe
        time.sleep(sleep_sec)  # let the environment load completely

    # Starts an instance of a race in your given level, if valid
    def start_race(self, tier=3):
        self.airsim_client.simStartRace(tier)

    # Resets a current race: moves players to start positions, timer and penalties reset
    def reset_race(self):
        self.airsim_client.simResetRace()

    # arms drone, enable APIs, set default traj tracker gains
    def initialize_drone(self):
        self.airsim_client.enableApiControl(vehicle_name=self.drone_name)
        self.airsim_client.arm(vehicle_name=self.drone_name)

        # set default values for trajectory tracker gains
        traj_tracker_gains = adrl.TrajectoryTrackerGains(
            kp_cross_track=5.0,
            kd_cross_track=0.0,
            kp_vel_cross_track=3.0,
            kd_vel_cross_track=0.0,
            kp_along_track=0.4,
            kd_along_track=0.0,
            kp_vel_along_track=0.04,
            kd_vel_along_track=0.0,
            kp_z_track=2.0,
            kd_z_track=0.0,
            kp_vel_z=0.4,
            kd_vel_z=0.0,
            kp_yaw=3.0,
            kd_yaw=0.1,
        )

        self.airsim_client.setTrajectoryTrackerGains(
            traj_tracker_gains, vehicle_name=self.drone_name
        )
        time.sleep(0.2)

    def takeoffSync(self):
        self.airsim_client.takeoffAsync().join()

    # like takeoffSync(), but with moveOnSpline()
    def takeoff_with_moveOnSpline(self, takeoff_height=1.0):
        start_position = self.airsim_client.simGetVehiclePose(
            vehicle_name=self.drone_name
        ).position
        takeoff_waypoint = adrl.Vector3r(
            start_position.x_val,
            start_position.y_val,
            start_position.z_val - takeoff_height,
        )

        self.airsim_client.moveOnSplineAsync(
            [takeoff_waypoint],
            vel_max=15.0,
            acc_max=5.0,
            add_position_constraint=True,
            add_velocity_constraint=False,
            add_acceleration_constraint=False,
            viz_traj=self.viz_traj,
            viz_traj_color_rgba=self.viz_traj_color_rgba,
            vehicle_name=self.drone_name,
        ).join()

    # stores gate ground truth poses as a list of airsim.Pose() objects in self.gate_poses_ground_truth
    def get_ground_truth_gate_poses(self):
        gate_names_sorted_bad = sorted(self.airsim_client.simListSceneObjects("Gate.*"))
        # gate_names_sorted_bad is of the form `GateN_GARBAGE`. for example:
        # ['Gate0', 'Gate10_21', 'Gate11_23', 'Gate1_3', 'Gate2_5', 'Gate3_7', 'Gate4_9', 'Gate5_11', 'Gate6_13', 'Gate7_15', 'Gate8_17', 'Gate9_19']
        # we sort them by their index of occurrence along the race track(N), and ignore the unreal garbage number after the underscore(GARBAGE)
        gate_indices_bad = [
            int(gate_name.split("_")[0][4:]) for gate_name in gate_names_sorted_bad
        ]
        gate_indices_correct = sorted(
            range(len(gate_indices_bad)), key=lambda k: gate_indices_bad[k]
        )
        gate_names_sorted = [
            gate_names_sorted_bad[gate_idx] for gate_idx in gate_indices_correct
        ]
        self.gate_poses_ground_truth = []
        for gate_name in gate_names_sorted:
            curr_pose = self.airsim_client.simGetObjectPose(gate_name)
            counter = 0
            while (
                    math.isnan(curr_pose.position.x_val)
                    or math.isnan(curr_pose.position.y_val)
                    or math.isnan(curr_pose.position.z_val)
            ) and (counter < self.MAX_NUMBER_OF_GETOBJECTPOSE_TRIALS):
                print(f"DEBUG: {gate_name} position is nan, retrying...")
                counter += 1
                curr_pose = self.airsim_client.simGetObjectPose(gate_name)
            assert not math.isnan(
                curr_pose.position.x_val
            ), f"ERROR: {gate_name} curr_pose.position.x_val is still {curr_pose.position.x_val} after {counter} trials"
            assert not math.isnan(
                curr_pose.position.y_val
            ), f"ERROR: {gate_name} curr_pose.position.y_val is still {curr_pose.position.y_val} after {counter} trials"
            assert not math.isnan(
                curr_pose.position.z_val
            ), f"ERROR: {gate_name} curr_pose.position.z_val is still {curr_pose.position.z_val} after {counter} trials"
            self.gate_poses_ground_truth.append(curr_pose)

    # this is utility function to get a velocity constraint which can be passed to moveOnSplineVelConstraints()
    # the "scale" parameter scales the gate facing vector accordingly, thereby dictating the speed of the velocity constraint
    def get_gate_facing_vector_from_quaternion(self, airsim_quat, scale=1.0):
        # convert gate quaternion to rotation matrix.
        # ref: https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion; https://www.lfd.uci.edu/~gohlke/code/transformations.py.html
        q = np.array(
            [
                airsim_quat.w_val,
                airsim_quat.x_val,
                airsim_quat.y_val,
                airsim_quat.z_val,
            ],
            dtype=np.float64,
        )
        n = np.dot(q, q)
        if n < np.finfo(float).eps:
            return adrl.Vector3r(0.0, 1.0, 0.0)
        q *= np.sqrt(2.0 / n)
        q = np.outer(q, q)
        rotation_matrix = np.array(
            [
                [1.0 - q[2, 2] - q[3, 3], q[1, 2] - q[3, 0], q[1, 3] + q[2, 0]],
                [q[1, 2] + q[3, 0], 1.0 - q[1, 1] - q[3, 3], q[2, 3] - q[1, 0]],
                [q[1, 3] - q[2, 0], q[2, 3] + q[1, 0], 1.0 - q[1, 1] - q[2, 2]],
            ]
        )
        gate_facing_vector = rotation_matrix[:, 1]
        return adrl.Vector3r(
            scale * gate_facing_vector[0],
            scale * gate_facing_vector[1],
            scale * gate_facing_vector[2],
        )

    def fly_through_all_gates_at_once_with_moveOnSpline(self):
        vel_max = 30.0
        acc_max = 15.0
        if self.level_name in [
            "Soccer_Field_Medium",
            "Soccer_Field_Easy",
            "ZhangJiaJie_Medium",
            "Qualifier_Tier_1",
            "Qualifier_Tier_2",
            "Qualifier_Tier_3",
            "Final_Tier_1",
            "Final_Tier_2",
            "Final_Tier_3",
        ]:
            vel_max = 30.0
            acc_max = 15.0

        if self.level_name == "Building99_Hard":
            vel_max = 4.0
            acc_max = 1.0

        return self.airsim_client.moveOnSplineAsync(
            [gate_pose.position for gate_pose in self.gate_poses_ground_truth],
            vel_max=vel_max,
            acc_max=acc_max,
            add_position_constraint=True,
            add_velocity_constraint=False,
            add_acceleration_constraint=False,
            viz_traj=self.viz_traj,
            viz_traj_color_rgba=self.viz_traj_color_rgba,
            vehicle_name=self.drone_name,
        )

    def fly_through_all_gates_at_once_with_moveOnSplineVelConstraints(self):
        vel_max = 15.0
        acc_max = 7.5
        speed_through_gate = 2.5

        if self.level_name in [
            "Soccer_Field_Easy",
            "Soccer_Field_Medium",
            "ZhangJiaJie_Medium",
        ]:
            vel_max = 15.0
            acc_max = 7.5
            speed_through_gate = 2.5

        if self.level_name == "Building99_Hard":
            vel_max = 5.0
            acc_max = 2.0
            speed_through_gate = 1.0

        return self.airsim_client.moveOnSplineVelConstraintsAsync(
            [gate_pose.position for gate_pose in self.gate_poses_ground_truth],
            [
                self.get_gate_facing_vector_from_quaternion(
                    gate_pose.orientation, scale=speed_through_gate
                )
                for gate_pose in self.gate_poses_ground_truth
            ],
            vel_max=vel_max,
            acc_max=acc_max,
            add_position_constraint=True,
            add_velocity_constraint=True,
            add_acceleration_constraint=False,
            viz_traj=self.viz_traj,
            viz_traj_color_rgba=self.viz_traj_color_rgba,
            vehicle_name=self.drone_name,
        )

    def odometry_callback(self):
        drone_state = self.airsim_client_odom.getMultirotorState()
        # in world frame:
        self.position = drone_state.kinematics_estimated.position
        self.orientation = drone_state.kinematics_estimated.orientation
        self.linear_velocity = drone_state.kinematics_estimated.linear_velocity
        self.angular_velocity = drone_state.kinematics_estimated.angular_velocity
        self.timestamp = drone_state.timestamp

    def repeat_timer_odometry_callback(self, task, period):
        while self.is_odometry_thread_active:
            task()
            time.sleep(period)

    def start_odometry_callback_thread(self):
        if not self.is_odometry_thread_active:
            self.is_odometry_thread_active = True
            self.odometry_callback_thread.start()
            print("Started odometry callback thread")

    def stop_odometry_callback_thread(self):
        if self.is_odometry_thread_active:
            self.is_odometry_thread_active = False
            self.odometry_callback_thread.join()
            print("Stopped odometry callback thread.")


# Find Optimal Learning Rate for 3 layer network designed using 5-fold cross-validation

import tensorflow as tf
import numpy as np
import pylab as plt
from sklearn import model_selection
from sklearn import preprocessing
import multiprocessing as mp

# Proceed to data location
import os
os.chdir('/Users/Charlene/Desktop/REP 4/Neural Networks and Deep Learning/Assignment')

NUM_FEATURES = 8
no_labels=1

# Parameters
epochs = 500
batch_size = 32
num_neuron = 30 # number of neurons in hidden layer
beta=10**-3 # weight decay parameter
no_folds=5 # 5 fold cross validation

# Initialise random seed
seed = 10
tf.set_random_seed(seed)
np.random.seed(seed)

# Load data from dataset for analysis
cal_housing = np.loadtxt('cal_housing.data', delimiter=',')
X_data, Y_data = cal_housing[:, :8], cal_housing[:, -1]
Y_data = (np.asmatrix(Y_data)).transpose()
idx = np.arange(X_data.shape[0])

# randomly shuffle the idx
np.random.shuffle(idx)
X_data, Y_data = X_data[idx], Y_data[idx]

# experiment with small datasets
X_data, Y_data = X_data[:1000], Y_data[:1000]

# split into testing and validation dataset
trainXV, testXV, trainYV, testYV = model_selection.train_test_split(X_data, Y_data, test_size=0.3, random_state=42)

#Calculate the number of datapoints in a fold
fold_data = int(0.2 * len(trainXV))

#Neural Network
def ffn(x, y_):

    # Hidden layer: Relu Layer
    with tf.name_scope('hidden'):
        w1 = tf.Variable(tf.truncated_normal([NUM_FEATURES, num_neuron], stddev=1.0 / np.sqrt(float(NUM_FEATURES))),
                         name='weights')
        b1 = tf.Variable(tf.zeros([num_neuron]), dtype=tf.float32, name='biases')
        h1 = tf.nn.relu(tf.matmul(x, w1) + b1)

    # Output layer: Linear Layer
    with tf.name_scope('linear'):
        w2 = tf.Variable(tf.truncated_normal([num_neuron, no_labels], stddev=1.0 / np.sqrt(float(num_neuron))),
                         name='weights')
        b2 = tf.Variable(tf.zeros([no_labels]), name='biases')
        prediction = tf.matmul(h1, w2) + b2

    # tabulate the loss
    loss = tf.reduce_mean(tf.reduce_sum(tf.square(y_ - prediction), axis=1))

    # loss with regularisation term
    regularization = tf.nn.l2_loss(w1) + tf.nn.l2_loss(w2)
    losswithreg = tf.reduce_mean(loss + beta * regularization)

    return losswithreg, loss

# Training with different learning rates
def train(learning_rate):

    cv_err=[]

    # Use 5-fold Cross Validation
    for fold in range (no_folds):
        # Taking 1 fold
        start, end=fold*fold_data,(fold+1)*fold_data
        testX, testY = trainXV[start:end], trainYV[start:end]
        trainX = np.append(trainXV[:start], trainXV[end:], axis=0)
        trainY = np.append(trainYV[:start], trainYV[end:], axis=0)

        trainY_ = trainY.reshape(len(trainY), no_labels)
        testY_ = testY.reshape(len(testY), no_labels)

        # standardise the input data
        scaler = preprocessing.StandardScaler()
        trainX_ = scaler.fit_transform(trainX)
        testX_ = scaler.transform(testX)

        # Define the placeholder value
        x = tf.placeholder(tf.float32, [None, NUM_FEATURES])
        y_ = tf.placeholder(tf.float32, [None, no_labels])

        # Create the model
        losswithreg, loss=ffn(x,y_)

        # Create the gradient descent optimizer with the given learning rate.
        train_op = tf.train.GradientDescentOptimizer(learning_rate).minimize(losswithreg)

        N=len(trainX_)
        idx=np.arange(N)

        # Start the session
        with tf.Session() as sess:

            sess.run(tf.global_variables_initializer())
            test_err = []
            batch_test_err=[]

            # Iterate through a number of epochs
            for i in range(epochs):
                np.random.shuffle(idx)
                trainXX=trainX_[idx]
                trainYY=trainY_[idx]

                # Use mini-batch gradient descent learning
                for start, end in zip(range(0, N, batch_size), range(batch_size, N, batch_size)):
                    train_op.run(feed_dict={x: trainXX[start:end], y_: trainYY[start:end]})

                    # Error for 1 batch
                    batch_test_err.append(loss.eval(feed_dict={x: testX_, y_: testY_}))

                # Error for epochs: Mean Batch Error
                test_err.append(sum(batch_test_err)/len(batch_test_err))

        # Error for 1 fold
        cv_err.append(test_err)

    # Mean error across all folds
    cv_err=np.mean(np.array(cv_err),axis=0)

    return cv_err

def main():

    # test out different learning rates
    no_threads=mp.cpu_count()
    learning_rate = [0.5*10**-6, 10 ** -7, 0.5*10**- 8, 10**-9, 10 ** -10]
    p=mp.Pool(processes=no_threads)
    cv_err= p.map(train, learning_rate)

    # plot learning curves
    plt.figure(1)
    for i in range(len(learning_rate)):
        plt.plot(range(epochs), cv_err[i], label= 'Learning Rate= {}'.format(learning_rate[i]))

    plt.xlabel('Number of Epochs')
    plt.ylabel('Mean Cross-Validation Error')
    # also the values for y is very high
    plt.title('Mini-Batch GD Learning')
    plt.legend()
    plt.show()

    # Compare the final CV Errors across Learning Rates after a certain number of epochs
    cv_err=np.array(cv_err)
    cv_err_final=cv_err[: , epochs-1]

    plt.figure(2)
    plt.plot(learning_rate, cv_err_final)
    plt.xlabel('Learning Rate')
    plt.ylabel('Final Cross-Validation Error')
    figure_title="Cross-Validation Errors with Different Learning Rates"
    plt.title(figure_title, y=1.08)
    plt.show()

    # Optimal learning rate is the one that gives the lowest CV error
    bestlr=learning_rate[np.argmin(cv_err_final)]
    print('learning rate that gives lowest error: {}'.format(bestlr))

    # Standardise test data
    stdtrainXV= (trainXV-np.mean(trainXV,axis=0))/np.std(trainXV, axis=0)
    stdtestXV= (testXV- np.mean(trainXV, axis=0))/ np.std(trainXV, axis=0)

    # Define placeholders
    x = tf.placeholder(tf.float32, [None, NUM_FEATURES])
    y_ = tf.placeholder(tf.float32, [None, no_labels])

    # Build the model
    losswithreg, loss= ffn(x,y_)
    train_op = tf.train.GradientDescentOptimizer(bestlr).minimize(losswithreg)

    N = len(stdtrainXV)
    idx = np.arange(N)

    #Start the session and record test errors
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())

        test_err=[]
        for i in range(epochs):
            # randomly shuffle the training set
            np.random.shuffle(idx)
            stdtrainXV=stdtrainXV[idx]

            batch_test_err = []
            for start, end in zip(range(0, N, batch_size), range(batch_size, N, batch_size)):
                # train it again with the training set 70%
                train_op.run(feed_dict={x: stdtrainXV[start:end], y_: trainYV[start:end]})

                #Tests error for 1 batch
                batch_test_err.append(loss.eval(feed_dict={x: stdtestXV, y_:testYV}))

            #Test error for epochs: Mean batch error
            test_err.append(sum(batch_test_err)/len(batch_test_err))

    plt.figure(3)
    plt.plot(range(epochs), test_err, label='Learning Rate= {}'.format(bestlr))
    plt.xlabel('Number of Epochs')
    plt.ylabel('Mean Test Error')
    plt.title('Mini-Batch GD Learning')
    plt.legend()
    plt.show()

if __name__ == '__main__':
  main()


open_file = open("CupcakeInvoices.csv")
#print each row
for row in open_file:
    print(row)

open_file.seek(0)

#print each flavor
for line in open_file:
    line = line.rstrip('\n').split(',')
    cupcakes = line[2]
    print(cupcakes)

open_file.seek(0)

#print each invoice
for line in open_file:
    line = line.rstrip('\n').split(',')
    quantity = int(line[3])
    price = float(line[4]) #has decimals
    total = quantity * price
    print(total)

open_file.seek(0)
#print total invoice

total = 0
for line in open_file:
    line = line.rstrip('\n').split(',')
    quantity = int(line[3])
    price = float(line[4]) #has decimals
    total += quantity * price

print(total)

open_file.close()


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import re
import seaborn as sns
import spacy
import yelp_tool
from spacy_readability import Readability
from gensim.models.doc2vec import TaggedDocument
from gensim.corpora import Dictionary
from gensim.similarities import Similarity
from gensim.models import LsiModel
from gensim.test.utils import get_tmpfile
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.manifold import TSNE
from sklearn.decomposition import PCA
from joblib import dump, load

# Basic text cleaning
def fix_nl(mytext):
    text = re.sub(r'\n\n', '', mytext)
    text = re.sub(r'\n', '', text)
    final = re.sub(r'  ', ' ', text)
    return final

# Basic lemmatize function
def lemma_sent(sent):
    return ' '.join(word.lemma_.lower() for word in sent if not word.is_punct and not word.is_stop)

# Preprocessor
def preproc(test, n, nlp, noval_index, val_index, mydct, pca8):
    test_sub = test.sample(n=n)
    X1, X2, y = [], [], []
    # Preprocess readability and length
    doc = nlp.pipe(test_sub.text)
    read_len = [(txt._.flesch_kincaid_reading_ease, len(txt)) for txt in doc]
    # Preprocess embeddings
    test_sub.text = test_sub.text.apply(fix_nl)
    for row in test_sub.itertuples():
        X1.append(noval_index[mydct.doc2bow(fix_nl(row.text).split())])
        X2.append(val_index[mydct.doc2bow(fix_nl(row.text).split())])
        y.append(row.useful)
    # PCA8 transform **ONLY**
    Xa = np.concatenate([X1, X2], axis=1)[:,:900000] # Restrict size with index
    pca8_test_X = pca8.transform(Xa)
    return pca8_test_X, y, read_len

# Modeler
def modeler(X, y, read_len, vec_model, rnl_model):
    # TSNE for graphing
    tsne = TSNE()
    graph = tsne.fit_transform(X)
    test_y = np.array(y)
    # Dicationary values
    vec_proba = vec_model.predict_proba(X=X)
    rnl_proba = rnl_model.predict_proba(np.array(read_len))
    comb_proba = rnl_proba + vec_proba
    pred = None
    success = None
    # Return variables
    score_and_y = {'proba':comb_proba, 'y':y, 'comb_pred':pred, 'success':success, 'graph':graph}
    score_and_y['pred'] = score_and_y['proba'][:,1] > score_and_y['proba'][:,0]
    score_and_y['success'] = score_and_y['y'] == score_and_y['pred']
    return score_and_y

# Load variables
def vars():
	mydct = load('mydct.joblib')
	noval_corp = load('noval_corp.joblib')
	noval_ind = get_tmpfile('index')
	noval_index = Similarity(noval_ind, noval_corp, len(mydct))
	val_corp = load('val_corp.joblib')
	val_ind = get_tmpfile('index')
	val_index = Similarity(val_ind, val_corp, len(mydct))
	pca8 = load('pca8.joblib')
	nlp = yelp_tool.spacy.load('en_core_web_md', disable=['tagger', 'ner'])
	read = yelp_tool.Readability()
	nlp.add_pipe(read, last=True)
	return mydct, noval_index, val_index, pca8, nlp


"""
Impute missing short descriptions by promtping GPT2 with the headlines
"""
import pandas as pd
from transformers import pipeline, set_seed
from tqdm import tqdm
import argparse

def main(args):
    set_seed(args.seed)
    generator = pipeline("text-generation", model="gpt2")
    df = pd.read_csv("data/news.csv")
    df_missing = df[df["short_description"].isna()]

    for i, row in tqdm(df_missing.iterrows(), total=len(df_missing)):
        headline = row["headline"]
        # Arguments set to stochastically generate short texts sticking to the topic
        gen = generator(headline, max_length=50, do_sample=True, top_k=50)
        # Remove headline from generated text
        short_description = gen[0]["generated_text"][len(headline) :].lstrip()
        df.loc[i, "short_description"] = short_description
    df.to_csv("data/news_imputed.csv", index=False)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--seed", type=int, default=123)
    args = parser.parse_args()
    main(args)


#  숫자 뒤집기 Number Reverse

"""
문제
Reverse 함수에 정수인 숫자를 인자로 받는다. 숫자를 뒤집어 return한다.
"""

number = input('input number: ')    # 숫자 입력, 문자열 전달

def reverse(num):
    number_int = int(num)
    if number_int < 0:                  # 음수에 대한 경우의 수
        number_int = -number_int        # 양수 치환
    number_str = str(number_int)        # 문자열 변환
    reverse_str = number_str[::-1]      # 슬라이싱, 역순
    reverse_number = int(reverse_str)   # 숫자 변환
    return reverse_number               # 결과 반환

print(reverse(number))


# -*- coding: utf-8 -*-
from plone import api
from plone import schema
from rer.newsletter import _
from rer.newsletter import logger
from rer.newsletter.adapter.subscriptions import IChannelSubscriptions
from rer.newsletter.utils import SUBSCRIBED
from rer.newsletter.utils import UNHANDLED
from z3c.form import button
from z3c.form import field
from z3c.form import form
from zope.component import getMultiAdapter
from zope.interface import Interface

class IAddForm(Interface):
    """define field for add user to a channel"""

    email = schema.Email(
        title=_("add_user_admin", default="Add User"),
        description=_(
            "add_user_admin_description",
            default="Insert email for add user to a Channel",
        ),
        required=True,
    )

class AddForm(form.Form):
    ignoreContext = True
    fields = field.Fields(IAddForm)

    @button.buttonAndHandler(_("add_user_admin_button", default="Add"))
    def handleSave(self, action):
        status = UNHANDLED
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return

        channel = self.context.id_channel
        mail = data["email"]

        channel = getMultiAdapter(
            (self.context, self.request), IChannelSubscriptions
        )
        status = channel.addUser(mail)

        if status == SUBSCRIBED:
            status = _("generic_add_message_success", default="User Added.")
            api.portal.show_message(
                message=status, request=self.request, type="info"
            )
        else:
            logger.exception("unhandled error add user")
            api.portal.show_message(
                message="Problems...{0}".format(status),
                request=self.request,
                type="error",
            )


# make a basic 3D unet architecture ... simple 3D vanilla unet ...
from torch import nn
import numpy as np
from torch.nn import functional as F
import torch

class ConvMe3d(nn.Module):
    def __init__(self, in_: int, out_:int, relu=True, kernel_size=(3, 3, 3), padding = 0, last=False, drop=True, drop_rate=0.1):
        super().__init__()
        self.conv3d = nn.Conv3d(in_, out_, kernel_size=kernel_size, padding=padding, bias=False)
        self.activation = nn.LeakyReLU(0.1) if relu else nn.SELU(inplace=True)
        self.is_last = last
        self.to_drop = drop
        self.drop = nn.Dropout3d(drop_rate)
        # self.activation = nn.SELU(inplace=True)
        # use relu except for last output

    def forward(self, x):
        x = self.conv3d(x)
        # add RELU baby ...
        x = self.activation(x) if self.is_last is False else x
        # add dropout
        x = self.drop(x) if self.to_drop is True else x
        return x

class EncoderBlock1(nn.Module):

    """
    Link: https://arxiv.org/pdf/1809.04430.pdf
    Have to yet make the DeepDecoderBlock class...
    # original block 3x3x3 convolutions...
    """

    def __init__(self, in_:int, out_:int, pool=True, norm=True, selu=False, deconv=False):
        super(EncoderBlock1, self).__init__()
        self.block = nn.Sequential(
            ConvMe3d (in_,  out_, kernel_size = (1, 3, 3), padding = (0, 1, 1)),
            ConvMe3d (out_, out_, kernel_size = (1, 3, 3), padding = (0, 1, 1)),
            ConvMe3d (out_, out_, kernel_size = (1, 3, 3), padding = (0, 1, 1)),
            ConvMe3d (out_, out_, kernel_size = (1, 3, 3), padding = (0, 1, 1), last=True)
        )

        # maxpool if true
        self.pool = nn.MaxPool3d(kernel_size=(1, 2, 2)) if pool is True else None
        self.bn = nn.BatchNorm3d(out_) # tackle the question is batch norm best before or after RELU?
        self.elu = nn.SELU(inplace=True) if selu is True else nn.LeakyReLU(0.1)
        # turn batch normalization on...
        self.norm = norm

    def forward(self, x):

        x = self.pool (x) if self.pool is not None else x
        x_init = self.block(x)
        x_init = self.elu(x_init)
        x_init = self.bn(x_init) if self.norm is not False else x_init

        return x_init

class EncoderBlock2(nn.Module):

    """
    Link: https://arxiv.org/pdf/1809.04430.pdf
    Have to yet make the DeepDecoderBlock class...
    """

    def __init__(self, in_:int, out_:int, selu=False, norm=True):
        super(EncoderBlock2, self).__init__()
        self.block = nn.Sequential(
            ConvMe3d(in_, out_, kernel_size =  (1, 3, 3), padding = (0, 1, 1)),
            ConvMe3d(out_, out_, kernel_size = (1, 3, 3), padding = (0, 1, 1)),
            ConvMe3d(out_, out_, kernel_size = (1, 3, 3), padding = (0, 1, 1)),
            ConvMe3d(out_, out_, kernel_size = (1, 3, 3), padding = (0, 1, 1)),
            ConvMe3d(out_, out_, kernel_size = (3, 3, 3), padding = (0, 1, 1), last=True),
        )

        self.pool = nn.MaxPool3d(kernel_size=(1, 2, 2))  # 1x2x2 Pooling
        self.bn = nn.BatchNorm3d(out_)
        self.elu = nn.SELU(inplace=True) if selu is True else nn.LeakyReLU(0.1)
        self.norm = norm

    def forward(self, x):

        x = self.pool(x)
        x_init = self.block(x)
        x_init = self.elu(x_init)
        x_init = self.bn(x_init) if self.norm is True else x_init

        return x_init

class EncoderBlock3(nn.Module):

    """
    Link: https://arxiv.org/pdf/1809.04430.pdf
    Have to yet make the DeepDecoderBlock class...
    """

    def __init__(self, in_:int, out_:int, selu=False, norm=True):
        super(EncoderBlock3, self).__init__()
        # can add padded x,y convs before/after zconvs here...
        self.block = nn.Sequential(
            ConvMe3d(in_, out_, kernel_size =  (3, 1, 1)),
            ConvMe3d(out_, out_, kernel_size = (3, 1, 1)),
            ConvMe3d(out_, out_, kernel_size = (3, 1, 1), last = True)
        )

        self.pool = nn.MaxPool3d(kernel_size=(1,2,2)) # 1x2x2 Pooling
        self.bn = nn.BatchNorm3d(out_)
        self.elu = nn.SELU(inplace=True) if selu is True else nn.LeakyReLU(0.1)
        self.norm=norm

    def forward(self, x):

        x = self.pool(x)
        x_init = self.block(x)
        x_init = self.elu(x_init)
        x_init = self.bn(x_init) if self.norm is True else x_init

        return x_init

# Model's main decoder class
# Default mode uses center crop in z plane after upsampling ...
# See Teranusnet for another implementation ...
class DecoderBlock1(nn.Module):
    def __init__(self, in_:int, out_:int, up_scale=True, selu=False, mode='default', last=False, norm=True):
        super(DecoderBlock1, self).__init__()
        self.up = nn.ConvTranspose3d(in_, in_, kernel_size=(1, 2, 2), stride=(1, 2, 2))
        # self.up_ = nn.ConvTranspose3d(in_, in_, kernel_size=(3,2,2), stride=(1, 2, 2))
        # Why would we not want to upconv in the Z plane?
        # concat on channels then in_*2
        self.elu = nn.SELU(inplace=True) if selu is True else nn.LeakyReLU(0.1)
        self.bn = nn.BatchNorm3d(out_)
        self.conv = EncoderBlock1(in_*2, out_, pool=False, deconv=True)
        self.last_conv = ConvMe3d(in_*2, out_, kernel_size=(1,1,1))
        self.mode = mode
        self.up_scale = up_scale
        self.last=last
        self.norm = norm

    def forward(self, x1, x2):

        # upsampling
        x1 = self.elu(self.up(x1))
        # cropping volume from skip connection
        x2_center = x2.size()[2]//2  # stack in channel(s) dimension
        x = x2[:, :, x2_center, :, :]
        x = x.unsqueeze(2)
        # completes skip connection (concatonation)
        x = torch.cat([x1, x], dim=1)
        # apply EncoderBlock1 convolutional filter
        x = self.conv(x) if self.last is False else self.last_conv(x)
        x = self.elu(x)
        x = self.bn(x) if self.norm is True else x

        return x


# -*- coding: utf-8 -*-
"""
Created on Mon Aug  2 21:05:47 2021

@author: Thanakorn
"""

def LargeNumber(number):
    Cal = ""
    List = []

    for i in number:
        x = str(i)*2
        List.append((x, i))
        List.sort(reverse= True)

    for i in List:
        Cal += str(i[1])

    return Cal

list1 = [50,20,1,9]
list2 = [10,1]
print(LargeNumber(list1))
print(LargeNumber(list2))


"""
Framework   : OpenCV Aruco
Description : Calibration of camera and using that for finding pose of multiple markers
Status      : Working
References  :
    1) https://docs.opencv.org/3.4.0/d5/dae/tutorial_aruco_detection.html
    2) https://docs.opencv.org/3.4.3/dc/dbb/tutorial_py_calibration.html
    3) https://docs.opencv.org/3.1.0/d5/dae/tutorial_aruco_detection.html
"""

import numpy as np
import cv2
import cv2.aruco as aruco
import glob
import freenect
# cap = cv2.VideoCapture(-1)

import os
import time
from datetime import datetime

# Photo session settings
total_photos = 50             # Number of images to take
countdown = 5                 # Interval for count-down timer, seconds
font=cv2.FONT_HERSHEY_SIMPLEX # Cowntdown timer font

# Final image capture settings
scale_ratio = 1

# function to get RGB image from kinect
def get_video():
    array, _ = freenect.sync_get_video()
    array = cv2.cvtColor(array, cv2.COLOR_BGR2GRAY)
    # array = cv2.cvtColor(array, cv2.COLOR_RGB2BGRA)
    return array

# # Camera settimgs
# cam_width = 1280              # Cam sensor width settings
# cam_height = 480              # Cam sensor height settings

# # Camera resolution height must be dividable by 16, and width by 32
# cam_width = int((cam_width+31)/32)*32
# cam_height = int((cam_height+15)/16)*16
# print ("Camera resolution: "+str(cam_width)+" x "+str(cam_height))
#
# # Buffer for captured image settings
# img_width = int (cam_width * scale_ratio)
# img_height = int (cam_height * scale_ratio)
# Lets start taking photos!
counter = 0
t2 = datetime.now()
###------------------ ARUCO TRACKER ---------------------------
while (True):
    frame = get_video()
    t1 = datetime.now()
    cntdwn_timer = countdown - int((t1 - t2).total_seconds())

    # If cowntdown is zero - let's record next image
    if cntdwn_timer == -1:
        counter += 1
        filename = './scenes/scene_' + str(counter) + '.jpg'
        cv2.imwrite(filename, frame)
        print(' [' + str(counter) + ' of ' + str(total_photos) + '] ' + filename)
        t2 = datetime.now()
        time.sleep(1)
        cntdwn_timer = 0  # To avoid "-1" timer display
        next

    # Draw cowntdown counter, seconds
    cv2.putText(frame, str(cntdwn_timer), (50, 50), font, 2.0, (0, 0, 255), 4, cv2.LINE_AA)
    cv2.imshow("pair", frame)
    key = cv2.waitKey(1) & 0xFF

    # Press 'Q' key to quit, or wait till all photos are taken
    if (key == ord("q")) | (counter == total_photos):
        break

# When everything done, release the capture
# cap.release()
cv2.destroyAllWindows()