#!/usr/bin/env python3

import telebot
from telebot import types
import sqlite3

sqll = [0]

bot = telebot.TeleBot("TOKEN", parse_mode=None)

conn = sqlite3.connect('SQLdb.db', check_same_thread=False)
cursor = conn.cursor()

def updateUserBalance (id: int, balans: int):
    cursor.execute('UPDATE users SET balans=? WHERE id=?', (balans, id))
    conn.commit()

def createUser (id: int, user_name: str, user_login: str, balans: int):
    cursor.execute('INSERT INTO users (id, user_name, user_login, balans) VALUES (?, ?, ?, ?)', (id, user_name, user_login, balans))
    conn.commit()

def getUserBalans (id: int):
    balans = cursor.execute('SELECT balans FROM users WHERE id = ?', (id,))
    conn.commit()
    return balans.fetchone()[0]

def getUserName (id: int):
    userData = cursor.execute('SELECT user_name FROM users WHERE id = ?', (id,))
    conn.commit()
    return userData.fetchone()[0]

def selectAll_id ():
    all_id = cursor.execute('SELECT id FROM users')
    conn.commit()
    return all_id.fetchall()

def idINFOMRER (ID):        # вытаскиваем список ID-шников из картежа sqlite
    allin = selectAll_id()
    print(allin)
    num = 0
    # usId = call.from_user.id
    print(ID, '- user')
    new_base = []
    for el in allin:
        print(num)
        print(ID, allin[num][0])
        new_base.insert(num, allin[num][0]) #такой способ вытащить ID из кортежа
        num = num+1
        print(new_base)
        print('==========================================')
    return new_base

def select_all_base ():
    all_base = cursor.execute('SELECT * FROM users')
    conn.commit()
    return all_base.fetchall()

@bot.message_handler(commands=['start', 'help'])
def send_welcome(message):
    bot.reply_to(message, "Этот бот призван читать круче Кендрика Ламара.")
    stick = open('sticker.webp', 'rb')
    bot.send_sticker(message.chat.id, stick)
    markup = types.ReplyKeyboardRemove(selective=False)
    markup = types.InlineKeyboardMarkup(row_width=1)
    itembtm1 = types.InlineKeyboardButton('Правила', callback_data='inc_1')
    itembtm2 = types.InlineKeyboardButton('Пользовательское соглашение', callback_data='inc_2')
    itembtm3 = types.InlineKeyboardButton('Пополнение баланса', callback_data='inc_3')
    itembtm4 = types.InlineKeyboardButton('Личный кабинет', callback_data='inc_4')
    markup.add(itembtm1, itembtm2, itembtm3, itembtm4)
    bot.send_message(message.chat.id, "Меню:", reply_markup=markup)

"""--------------------------- Обработчик кнопок -----------------------------------------------------------"""
@bot.callback_query_handler(func=lambda call: True)
def test_callback(call):
    if call.message:
        if call.data == "inc_0":
            markup = types.InlineKeyboardMarkup(row_width=1)
            itembtm1 = types.InlineKeyboardButton('Правила', callback_data='inc_1')
            itembtm2 = types.InlineKeyboardButton('Пользовательское соглашение', callback_data='inc_2')
            itembtm3 = types.InlineKeyboardButton('Пополнение баланса', callback_data='inc_3')
            itembtm4 = types.InlineKeyboardButton('Личный кабинет', callback_data='inc_4')
            markup.add(itembtm1, itembtm2, itembtm3, itembtm4)
            bot.edit_message_text("Меню:", call.message.chat.id, call.message.message_id, reply_markup=markup)

        elif call.data == "inc_1":
            user_ID = call.from_user.id
            if user_ID in idINFOMRER(user_ID):
                print('Hello, friend')
            else:
                us_id = call.from_user.id
                us_name = call.from_user.first_name
                us_sname = call.from_user.username
                createUser(id=us_id, user_name=us_name, user_login=us_sname, balans=0)
                print('new user')
                # bot.send_message(call.from_user.id, 'Привет! Ваше имя добавленно в базу данных!')

            markup = types.InlineKeyboardMarkup(row_width=1)
            item1 = types.InlineKeyboardButton('Отправить отзыв', callback_data='la_2')
            item2 = types.InlineKeyboardButton('Назад', callback_data='inc_0')
            markup.add(item1, item2)
            bot.edit_message_text("Мы тут не в игры играем, никаких правил", call.message.chat.id, call.message.message_id, reply_markup=markup)

        elif call.data == "inc_2":
            user_ID = call.from_user.id
            if user_ID in idINFOMRER(user_ID):
                print('Hello, friend')
            else:
                us_id = call.from_user.id
                us_name = call.from_user.first_name
                us_sname = call.from_user.username
                createUser(id=us_id, user_name=us_name, user_login=us_sname, balans=0)
                print('new user')
                # bot.send_message(call.from_user.id, 'Привет! Ваше имя добавленно в базу данных!')
            markup = types.InlineKeyboardMarkup(row_width=1)
            item_for_block_1 = types.InlineKeyboardButton('Инверсировать игру', callback_data='item_block_2')
            item_for_block_2 = types.InlineKeyboardButton('Назад', callback_data='inc_0')
            markup.add(item_for_block_1, item_for_block_2)
            bot.edit_message_text("Можем просто заблокировать, если ты нам не понравишься", call.message.chat.id, call.message.message_id, reply_markup=markup)

        elif call.data == "inc_3":
            user_ID = call.from_user.id
            if user_ID in idINFOMRER(user_ID):

                print('Hello, friend')
            else:
                us_id = call.from_user.id
                us_name = call.from_user.first_name
                us_sname = call.from_user.username
                createUser(id=us_id, user_name=us_name, user_login=us_sname, balans=0)
                # bot.send_message(call.from_user.id, 'Привет! Ваше имя добавленно в базу данных!')
                print('new user')

            us_id = call.from_user.id
            us_name = call.from_user.first_name
            us_sname = call.from_user.username
            currentUserBalance = getUserBalans(us_id)
            # print(currentUserBalance.fetchone()[0])
            currentUserBalance = currentUserBalance+100
            updateUserBalance(id=us_id, balans=currentUserBalance)
            markup = types.InlineKeyboardMarkup(row_width=1)
            balansbtn = types.InlineKeyboardButton('Назад', callback_data='inc_0')
            markup.add(balansbtn)
            bot.edit_message_text("Баланс пополнен!", call.message.chat.id, call.message.message_id, reply_markup=markup)

        elif call.data == "inc_4":
            user_ID = call.from_user.id
            if user_ID in idINFOMRER(user_ID):
                print('Hello, friend')
            else:
                us_id = call.from_user.id
                us_name = call.from_user.first_name
                us_sname = call.from_user.username
                createUser(id=us_id, user_name=us_name, user_login=us_sname, balans=0)
                print('new user')
                # bot.send_message(call.from_user.id, 'Привет! Ваше имя добавленно в базу данных!')
            if user_ID == 795675764 or user_ID == 5510951877:
                markup = types.InlineKeyboardMarkup(row_width=1)
                lkbtn1 = types.InlineKeyboardButton('Назад', callback_data='inc_0')
                lkbtn2 = types.InlineKeyboardButton('База данных', callback_data='admin_base')
                markup.add(lkbtn1, lkbtn2)
                us_id = call.from_user.id
                bot.edit_message_text('Привет, создатель!\n'+'Игрок: '+str(getUserName(us_id))+'\nБаланс: '+str(getUserBalans(us_id)),
                    call.message.chat.id, call.message.message_id, reply_markup=markup)
            else:
                markup = types.InlineKeyboardMarkup(row_width=1)
                lkbtn1 = types.InlineKeyboardButton('Назад', callback_data='inc_0')
                markup.add(lkbtn1)
                us_id = call.from_user.id
                bot.edit_message_text('Игрок: '+str(getUserName(us_id))+'\nБаланс: '+str(getUserBalans(us_id)),
                    call.message.chat.id, call.message.message_id, reply_markup=markup)

        elif call.data == "la_2":
            markup = types.InlineKeyboardMarkup(row_width=1)
            otzyv = types.InlineKeyboardButton('Назад', callback_data='inc_0')
            markup.add(otzyv)
            bot.edit_message_text("info@xcloudclub.com", call.message.chat.id, call.message.message_id, reply_markup=markup)

        elif call.data == 'item_block_2':
            markup = types.InlineKeyboardMarkup(row_width=1)
            inv_1 = types.InlineKeyboardButton('Назад', callback_data='inc_0')
            markup.add(inv_1)
            bot.edit_message_text("Инверсированно", call.message.chat.id, call.message.message_id, reply_markup=markup)

        elif call.data == 'admin_base':
            my_list = []
            for x in select_all_base():
                my_list.append(''.join(str(x)))    #https://ru.stackoverflow.com/questions/1178388
            my_str = '\n'.join(my_list)
            # print(select_all_base())
            # for item in select_all_base():
            #     print(item)
            markup = types.InlineKeyboardMarkup(row_width=1)
            button_back = types.InlineKeyboardButton('Назад', callback_data='inc_0')
            markup.add(button_back)
            bot.edit_message_text('База данных\n'+my_str, call.message.chat.id, call.message.message_id, reply_markup=markup)

"""------------------------- Обработчики текста и стикеров --------------------------------------------------"""
@bot.message_handler(content_types=['text'])
def text_up(message):
    bot.reply_to(message, message.text)
    bot.send_message(message.chat.id, "Давай без самодеятельности. Мы для кого кнопки сделали?")

@bot.message_handler(content_types=['sticker'])
def text_down(message):
    bot.send_message(message.chat.id, "Козырный стикер!")

"""--------------------------------- Start ------------------------------------------------------------------"""
bot.infinity_polling()


# coding:utf-8

from PyQt5.QtWidgets import QWidget, QGridLayout, QVBoxLayout, QSizePolicy, QListWidgetItem, QAbstractItemView
from PyQt5.QtCore import pyqtSignal

from qfluentwidgets import ListWidget, PrimaryPushButton, PillPushButton, FluentIcon, InfoBar

from common.style_sheet import StyleSheet
from common.config import cfg
from globalvar.vars import set_value, get_value
from threads.pkthread import PKThread
from utils.logger import Logger
from view.frame import Frame
from view.widget.operate_toolbar import OperateToolBar

class OperateInterface(QWidget):
    """ View interface """
    calculate_started_signal = pyqtSignal(str)
    calculate_finished_signal = pyqtSignal(str)

    def __init__(self, parent=None):
        super().__init__(parent=parent)
        self.setObjectName("operate_interface")
        self.widget = QWidget(self)
        self.gridLayout = QGridLayout(self)
        self.verticalLayout = QVBoxLayout()

        self.toolBar = OperateToolBar(self.tr("Variables"), self.tr("Calculate and compare the PK values of the variables."), self)
        self.listWidget_all = ListWidget(self)
        self.listWidget_y = ListWidget(self)
        self.listWidget_x = ListWidget(self)

        self.frame_all = Frame(self)
        self.frame_x = Frame(self)
        self.frame_y = Frame(self)

        self.pushButton_y = PrimaryPushButton(self.tr("Add"), self)
        self.pushButton_all = PrimaryPushButton(self.tr("Add all"), self)
        self.pushButton_x = PrimaryPushButton(self.tr("Add"), self)

        self.variables_all = PillPushButton(self.tr("Available variables"), self, FluentIcon.TAG)
        self.variables_x = PillPushButton(self.tr("Test variables"), self, FluentIcon.TAG)
        self.variables_y = PillPushButton(self.tr("Independent variables"), self, FluentIcon.TAG)

        self.list_all = []

        self.add_to_x = True
        self.add_to_y = True

        self.pkThread = PKThread()

        self.logger = Logger().get_logger()

        self.__initWidget()
        self.__initListWidgets()
        self.__initConnects()

    def __initWidget(self):
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.listWidget_y.sizePolicy().hasHeightForWidth())
        self.listWidget_y.setSizePolicy(sizePolicy)

        self.frame_all.addWidget(self.listWidget_all)
        self.frame_x.addWidget(self.listWidget_x)
        self.frame_y.addWidget(self.listWidget_y)

        self.gridLayout.addWidget(self.toolBar, 0, 0, 1, 3)
        self.gridLayout.addWidget(self.frame_all, 2, 0, 4, 1)
        self.gridLayout.addWidget(self.pushButton_y, 3, 1, 1, 1)
        self.gridLayout.addWidget(self.frame_y, 3, 2, 1, 1)

        self.gridLayout.addWidget(self.variables_all, 1, 0, 1, 1)
        self.gridLayout.addWidget(self.variables_y, 1, 2, 1, 1)
        self.gridLayout.addWidget(self.variables_x, 4, 2, 1, 1)

        self.verticalLayout.addWidget(self.pushButton_all)
        self.verticalLayout.addWidget(self.pushButton_x)
        self.gridLayout.addLayout(self.verticalLayout, 5, 1, 1, 1)
        self.gridLayout.addWidget(self.frame_x, 5, 2, 1, 1)

        self.variables_all.setCheckable(False)
        self.variables_y.setCheckable(False)
        self.variables_x.setCheckable(False)

        self.listWidget_all.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.listWidget_x.setSelectionMode(QAbstractItemView.ExtendedSelection)

        StyleSheet.GALLERY_INTERFACE.apply(self)

    def __initListWidgets(self):
        self.pushButton_x.setEnabled(False)
        self.pushButton_y.setEnabled(False)
        self.pushButton_all.setEnabled(False)

        self.resetLists()

    def __initButtons(self):
        self.pushButton_x.setEnabled(True)
        self.pushButton_y.setEnabled(True)
        self.pushButton_all.setEnabled(True)

        self.pushButton_x.setText(self.tr("Add"))
        self.pushButton_y.setText(self.tr("Add"))
        self.pushButton_all.setText(self.tr("Add all"))

        self.add_to_x = True
        self.add_to_y = True

    def enbaleAllButtons(self, enabled):
        self.pushButton_all.setEnabled(enabled)
        self.pushButton_x.setEnabled(enabled)
        self.pushButton_y.setEnabled(enabled)
        self.toolBar.compareButton.setEnabled(enabled)
        self.toolBar.calcaulateButton.setEnabled(enabled)
        self.toolBar.resetButton.setEnabled(enabled)

    def __initConnects(self):
        self.toolBar.resetButton.clicked.connect(self.resetLists)
        self.listWidget_all.clicked.connect(self.__initButtons)
        self.listWidget_x.clicked.connect(self.remove_from_x)
        self.listWidget_y.clicked.connect(self.remove_from_y)
        self.pushButton_x.clicked.connect(self.clicked_button_x)
        self.pushButton_y.clicked.connect(self.clicked_button_y)
        self.pushButton_all.clicked.connect(self.clicked_button_all)
        self.toolBar.calcaulateButton.clicked.connect(self.calculate)
        self.toolBar.compareButton.clicked.connect(self.compare)
        self.pkThread.finished_signal.connect(self.calculate_compare_finished)
        self.pkThread.error_signal.connect(self.error_occurred)
        self.pkThread.warn_signal.connect(self.warn_occurred)
        self.pkThread.success_signal.connect(self.success_occurred)
        self.pkThread.task_percentage_changed_signal.connect(self.toolBar.progressbar.setValue)
        self.pkThread.task_percentage_changed_signal.connect(self.toolBar.update_percentage)

    def resetLists(self):
        self.setList(self.listWidget_x, [])
        self.setList(self.listWidget_y, [])
        self.setList(self.listWidget_all, self.list_all)

    def setList(self, list_widget, list_content):
        while list_widget.count() > 0:
            list_widget.takeItem(0)
        for content in list_content:
            if not isinstance(content, str):
                content = str(content)
            list_widget.addItem(QListWidgetItem(content))
        list_widget.clearSelection()

    def updateList(self):
        df = get_value("current_workbook")
        self.list_all = df.columns
        self.resetLists()
        self.__initButtons()

        set_value("pk", None)
        set_value("pk_dict", {})
        set_value("pk_name_dict", {})
        set_value("pk_n", 0)

        set_value("pks", None)
        set_value("pks_dict", {})
        set_value("pks_name_dict", {})
        set_value("pks_n", 0)

        self.logger.info(self.tr("Update the available variables in the data. All the storage cache has been reset."))
        self.logger.info(self.tr("The available variables list as {0}").format(self.list_all))

    def remove_from_x(self):
        self.pushButton_x.setText(self.tr("Remove"))
        self.pushButton_all.setText(self.tr("Remove all"))
        self.add_to_x = False

    def remove_from_y(self):
        self.pushButton_y.setText(self.tr("Remove"))
        self.add_to_y = False

    def exchange_selected(self, source, destination):
        selected = source.selectedIndexes()
        idx = [x.row() for x in selected]
        idx.sort(reverse=True)
        for num in idx:
            it = source.takeItem(num)
            destination.addItem(it)
        source.clearSelection()
        destination.clearSelection()

    def remove_all(self, source, destination):
        while source.count() > 0 :
            it = source.takeItem(0)
            destination.addItem(it)

    def clicked_button_x(self):
        if self.add_to_x:
            self.exchange_selected(self.listWidget_all, self.listWidget_x)
        else:
            self.exchange_selected(self.listWidget_x, self.listWidget_all)

    def clicked_button_y(self):
        if self.add_to_y:
            if self.listWidget_y.count() == 0 and len(self.listWidget_all.selectedItems()) == 1:
                self.exchange_selected(self.listWidget_all, self.listWidget_y)
            else:
                pass
        else:
            self.exchange_selected(self.listWidget_y, self.listWidget_all)

    def clicked_button_all(self):
        if self.add_to_x:
            self.remove_all(self.listWidget_all, self.listWidget_x)
        else:
            self.remove_all(self.listWidget_x, self.listWidget_all)

    def collect_xy(self):
        x = []
        y = []
        n = self.listWidget_x.count()
        for i in range(n):
            x.append(self.listWidget_x.item(i).text())

        n = self.listWidget_y.count()
        for i in range(n):
            y.append(self.listWidget_y.item(i).text())

        set_value("x_names", x)
        set_value("y_names", y)
        set_value("output_dir", cfg.get(cfg.outputFolder))

        self.logger.info(self.tr("The test variables include the following:"))
        self.logger.info(x)
        self.logger.info(self.tr("The independent variable includes the following:"))
        self.logger.info(y)

    def calculate(self):
        self.logger.info(self.tr("Start calculating PKs."))
        self.toolBar.textButton.setText(self.tr("Calculating"))
        self.enbaleAllButtons(False)
        self.collect_xy()
        self.pkThread.set_work_type("PK")
        self.pkThread.start()
        self.calculate_started_signal.emit(self.tr("Calculating PKs"))

    def compare(self):
        self.logger.info(self.tr("Start comparing PKs."))
        self.toolBar.textButton.setText(self.tr("Comparing"))
        self.enbaleAllButtons(False)
        self.collect_xy()
        self.pkThread.set_work_type("PKC")
        self.pkThread.start()
        self.calculate_started_signal.emit(self.tr("Comparing PKs"))

    def calculate_compare_finished(self):
        self.enbaleAllButtons(True)
        self.toolBar.createTopLeftInfoBar(self.tr("Success!"), self.tr("The operation success and write the results to files finished!! Please refer the output for details."), InfoBar.success, 2000)
        self.calculate_finished_signal.emit(self.tr("Open the file {0}").format(get_value("last_work_file")))

    def success_occurred(self, str):
        self.toolBar.createTopLeftInfoBar(self.tr("Success!"), str, InfoBar.success)

    def error_occurred(self, str):
        self.enbaleAllButtons(True)
        self.toolBar.createTopRightInfoBar(self.tr("Error!"), str,InfoBar.error)

    def warn_occurred(self, str):
        self.toolBar.createTopRightInfoBar(self.tr("Warn!"), str,InfoBar.warning)


from django.conf.urls import url, include
from . import views

#app_name = 'dmlpolls'
urlpatterns = [

	url(r'^$', views.index, name='poll_index'),
	url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='poll_detail'),
	url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='poll_results'),
	url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='poll_vote'),
	url(r'^polls/', include('dmlpolls.urls')),
#    url(r'^admin/', admin.site.urls),
]


#신입사원*
import sys
input = sys.stdin.readline

t = int(input())
for _ in range(t):
    grade = []
    n = int(input())
    cnt = n
    for _ in range(n):
        paper, interview = map(int, input().split())
        grade.append([paper, interview])
    grade = sorted(grade, key= lambda a: a[0])
    temp = grade[0][1]
    for i in range(1, n):
        if grade[i][1] > temp:
            cnt -= 1
        else:
            temp = grade[i][1]
    print(cnt)


import money
from exceptions import *
from tkinter import *
from datetime import *
from decimal import Decimal
import math
import re
from tkinter import messagebox
from dateutil.rrule import *
from parkomat_interface import ParkomatInterface

class ParkomatFunctions:
    """ Klasa realizująca funkcjonalności programu """

    __global_date = datetime.now()  # zmienna przechowująca aktualnie ustawioną datę w parkomacie
    __departure_time = __global_date  # zmienna przechowująca czas wyjazdu
    __previous_time = 0  # zmienna przechowująca poprzednio zwrócony czas w sekundach dla wrzuconych pieniędzy dla metody seconds_for_money
    __inserted_money_by_user = Decimal("0.00")  # zmienna przechowująca liczbę wrzuconych pieniędzy przez aktualnego użytkownika

    def __init__(self):
        self.__window = Tk()  # Toplevel widget reprezentujący główne okno programu
        self.__interface = ParkomatInterface(self.window)  # interfejs programu
        self.__moneyHolder = self.interface.moneyHolder  # instancja przechowywacza pieniędzy
        self.buttons_onclick()  # metoda dodające wydarzenia do przycisków
        self.actual_date()  # metoda aktualizująca datę parkomatu oraz wyjazdu

    @property
    def window(self):
        """ Getter zwracający Toplevel widget reprezentujący główne okno programu """
        return self.__window

    @window.setter
    def window(self, window):
        """ Setter ustawiający Toplevel widget reprezentujący główne okno programu """
        self.__window = window

    @property
    def interface(self):
        """ Getter zwracający odwołanie do interfejsu programu """
        return self.__interface

    @interface.setter
    def interface(self, interface):
        """ Setter ustawiające odwołanie do interfejsu programu """
        self.__interface = interface

    @property
    def moneyHolder(self):
        """ Getter zwracający przechowywacz pieniędzy """
        return self.__moneyHolder

    @moneyHolder.setter
    def moneyHolder(self, moneyHolder):
        """ Setter ustawiający przechowywacz pieniędzy """
        self.__moneyHolder = moneyHolder

    @property
    def global_date(self):
        """ Getter zwracający aktualnie ustawioną datę w parkomacie """
        return self.__global_date

    @property
    def departure_time(self):
        """ Getter zwracający datę wyjazdu """
        return self.__departure_time

    @global_date.setter
    def global_date(self, global_date):
        """ Setter ustawiający aktualną datę w parkomacie """
        self.__global_date = global_date

    @departure_time.setter
    def departure_time(self, departure_time):
        """ Setter ustawiający datę wyjazdu  """
        self.__departure_time = departure_time

    @property
    def previous_time(self):
        """ Getter zwracający poprzednio dodany czas """
        return self.__previous_time

    @previous_time.setter
    def previous_time(self, previous_time):
        """ SSetter ustawiający poprzednio dodany czas """
        self.__previous_time = previous_time

    @property
    def inserted_money_by_user(self):
        """ Getter zwracający poprzednio dodany czas """
        return self.__inserted_money_by_user

    @inserted_money_by_user.setter
    def inserted_money_by_user(self, inserted_money_by_user):
        """ SSetter ustawiający poprzednio dodany czas """
        self.__inserted_money_by_user = inserted_money_by_user

    def main_loop(self):
        """ Nieskończona pętla służąca do uruchomienia aplikacji trwająca, dopóki okno nie zostanie zamknięte """
        self.window.mainloop()

    def buttons_onclick(self):
        """ Metoda obsługująca wydarzenia, gdy przycisk zostanie wciśnięty """

        self.interface.window.button1.bind("<ButtonRelease-1>", lambda event: self.add_number_of_money(self.moneyHolder.available_values[0]))
        self.interface.window.button2.bind("<ButtonRelease-1>", lambda event: self.add_number_of_money(self.moneyHolder.available_values[1]))
        self.interface.window.button3.bind("<ButtonRelease-1>", lambda event: self.add_number_of_money(self.moneyHolder.available_values[2]))
        self.interface.window.button4.bind("<ButtonRelease-1>", lambda event: self.add_number_of_money(self.moneyHolder.available_values[3]))
        self.interface.window.button5.bind("<ButtonRelease-1>", lambda event: self.add_number_of_money(self.moneyHolder.available_values[4]))
        self.interface.window.button6.bind("<ButtonRelease-1>", lambda event: self.add_number_of_money(self.moneyHolder.available_values[5]))
        self.interface.window.button7.bind("<ButtonRelease-1>", lambda event: self.add_number_of_money(self.moneyHolder.available_values[6]))
        self.interface.window.button8.bind("<ButtonRelease-1>", lambda event: self.add_number_of_money(self.moneyHolder.available_values[7]))
        self.interface.window.button9.bind("<ButtonRelease-1>", lambda event: self.add_number_of_money(self.moneyHolder.available_values[8]))
        self.interface.window.button10.bind("<ButtonRelease-1>", lambda event: self.add_number_of_money(self.moneyHolder.available_values[9]))
        self.interface.window.button11.bind("<ButtonRelease-1>", lambda event: self.add_number_of_money(self.moneyHolder.available_values[10]))
        self.interface.window.button12.bind("<ButtonRelease-1>", lambda event: self.add_number_of_money(self.moneyHolder.available_values[11]))
        self.bind_button_confirm(lambda event: self.button_confirm(event))
        self.bind_change_actual_time(lambda event: self.button_change_actual_time(event))

    def actual_date(self):
        """ Metoda aktualizująca aktualną datę parkomatu oraz datę wyjazdu"""

        self.global_date = self.global_date + timedelta(seconds=1)  # dodanie sekundy do aktualnej daty parkomatu
        self.departure_time = self.departure_time + timedelta(seconds=1)  # dodanie sekundy do daty wyjazdu

        # wyświetlenie aktualnej daty parkomatu
        self.interface.window.actual_date_label.config(text=self.global_date.strftime("%Y-%m-%d %H:%M"))
        # wyświetlenie daty wyjazdu
        self.interface.window.date_of_departure_label.config(text=self.departure_time.strftime("%Y-%m-%d %H:%M"))

        # powtarzanie funkcji actual_date() co sekundę
        self.interface.window.actual_date_label.after(1000, self.actual_date)

    def button_confirm(self, event):
        """ Funkcja odpowiadająca na naciśnięcie przycisku 'Zatwierdź' """
        try:
            self.confirm()
        except Exception as err:
            messagebox.showerror("Błąd", str(err))

    def button_change_actual_time(self, event):
        """ Funkcja odpowiadająca na naciśnięcie przycisku zmieniającego godzinę """
        try:
            self.change_actual_time()
        except Exception as err:
            messagebox.showerror("Błąd", str(err))

    def bind_button_confirm(self, f):
        """ Funkcja bindująca przycisk 'Zatwierdź' """
        self.interface.window.confirm_button.bind("<ButtonRelease-1>", f)

    def bind_change_actual_time(self, f):
        """ Funkcja bindująca przycisk 'Przestaw' """
        self.interface.window.change_actual_date_button.bind("<ButtonRelease-1>", f)

    def change_actual_time(self):
        """ Metoda ustawiająca godzinę wprowadzoną przez użytkownika """

        #  sprawdzenie, czy wpisano poprawnie czas
        if self.inserted_money_by_user != Decimal("0.00"):
            messagebox.showerror("Error", "Nie można zmienić czasu, gdy wrzucono już pieniądze.")
        else:
            if self.interface.window.hour_entry.get().isdigit() is False or self.interface.window.minute_entry.get().isdigit() is False or int(
                    self.interface.window.hour_entry.get()) < 0 or int(
                self.interface.window.hour_entry.get()) > 23 or int(
                self.interface.window.minute_entry.get()) < 0 or int(
                self.interface.window.minute_entry.get()) > 59:
                raise IncorrectTime("Wpisano niepoprawny czas.")
            else:
                h1 = int(self.interface.window.hour_entry.get())  # pobranie godziny z entry i przekonwertowanie na int
                m1 = int(self.interface.window.minute_entry.get())  # pobranie minuty z entry i przekonwertowanie na int
                self.global_date = self.global_date.replace(hour=h1, minute=m1)  # ustawienie nowego czasy dla parkomatu
                self.departure_time = self.global_date  # przypisanie aktualnej daty parkomatu do daty wyjazdu
                self.previous_time = 0  # reset wcześniejszego czasu, gdy zmieniamy czas

    def add_number_of_money(self, value: Decimal):
        """ Metoda dodająca wybraną liczbę monet """

        number_of_money = self.interface.window.number_of_money_entry.get()  # pobranie wprowadzonej liczby monet
        try:
            if self.interface.window.number_of_money_entry == "" or number_of_money.isdigit() is False:  # jeśli nie wpisano wartości lub nie jest liczbą
                raise IncorrectValueError
            else:  # w przeciwnym wypadku
                number_of_money = int(number_of_money)
                if value < 10:  # jeśli wartość pieniądza wynosi poniżej 10 to tworzymy monetę
                    for x in range(number_of_money):
                        self.moneyHolder.add_money(money.Coin(value))  # dodanie monety do przechowywacza
                        self.inserted_money_by_user += value  # dodanie wartości monety do aktualnie wrzuconych przez użytkownika
                else:  # w przeciwnym wypadku tworzymy banknoty
                    for x in range(number_of_money):
                        self.moneyHolder.add_money(money.Bill(value))  # dodanie banknotu do przechowywacza
                        self.inserted_money_by_user += value  # dodanie wartości banknotu do aktualnie wrzuconych przez użytkownika
        except IncorrectValueError:  # przechwycenie wyjątku dla niepoprawnie wpisanej wartości
            messagebox.showerror("Error", "Wpisz poprawną liczbę pieniędzy którą chcesz wrzucić.")
        except TooMuchCoinsError as err:  # przechwycenie wyjątku, jeśli przekroczono limit nominałów
            messagebox.showerror("Error", str(err))
        finally:  # aktualizacja wrzuconej kwoty oraz daty wyjazdu
            self.interface.window.sum_of_money_label.config(text=self.inserted_money_by_user)  # wrzucona kwota
            self.departure_date()  # aktualizacja daty wyjazdu

    def input_validator(self):
        """ Metoda walidująca numer rejestracyjny """

        # porównanie numeru do wyrażenia regularnego
        pattern = re.match("^[A-Z0-9]+$", self.interface.window.registration_number_entry.get())
        if self.interface.window.registration_number_entry.get() == "":  # błąd jeśli nie wpisano numeru rejestracyjnego
            raise RegistrationNumberError("Wpisz numer rejestracyjny.")
        elif bool(pattern) is False:  # błąd, jeśli numer nie pasuje do wyrażenia regularnego
            raise RegistrationNumberError("Numer rejestracyjny może składać się tylko z wielkich liter od A do Z i cyfr")

    def confirmation_of_payment(self):
        """ Metoda wyświetlająca okno z potwierdzeniem opłacenia parkingu """

        messagebox.showinfo("Potwierdzenie opłacenia parkingu",
                            "Numer rejestracyjny: {} \n\nCzas zakupu: {} \n\nTermin wyjazdu: {}"
                            .format(self.interface.window.registration_number_entry.get(),
                                    self.interface.window.actual_date_label.cget("text"),
                                    self.interface.window.date_of_departure_label.cget("text")))

    def rules(self, departure_date, seconds):
        """ Zasady strefy płatnego parkowania obowiązuje w godzinach od 8 do 20 od poniedziałku do piątku """

        rr = rrule(SECONDLY, byweekday=(MO, TU, WE, TH, FR), byhour=(8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19),
                   dtstart=departure_date, interval=seconds)
        return rr.after(departure_date)

    def seconds_for_money(self, amount: Decimal):
        """ Metoda zwracająca liczbę sekund dla wrzuconych pieniędzy """

        total_seconds = 0  # zmienna przechowująca sumę dodanych sekund
        grosz_1h = 60 * 60 / 200  # sekunda za jednego grosza pierwszej godziny
        grosz_2h = 60 * 60 / 400  # sekunda za jednego grosza drugiej godziny
        grosz_xh = 60 * 60 / 500  # sekunda za jednego grosza lub większej godziny

        if total_seconds < 3600:  # jeśli suma sekund jest mniejsza od godziny zapisanej w sekundach
            if amount >= 2:  # jeśli suma jest większa lub równa 2
                total_seconds += 3600  # dodaj godzinę
                amount -= 2  # odejmij od sumy koszt jednej godziny
            else:
                seconds = amount * 100 * Decimal(grosz_1h)  # obliczona liczba sekund
                total_seconds += seconds  # dodanie obliczonych sekund do całościowej liczby sekund
                amount = 0  # zerowanie sumy

        if total_seconds < 7200:  # jeśli suma sekund jest mniejsza od dwóch godzin zapisanej w sekundach
            if amount >= 4:  # jeśli suma jest większa lub równa 4
                total_seconds += 3600  # dodaj godzinę
                amount -= 4  # odejmij od sumy koszt jednej godziny
            else:
                seconds = amount * 100 * Decimal(grosz_2h)  # obliczona liczba sekund
                total_seconds += seconds  # dodanie obliczonych sekund do całościowej liczby sekund
                amount = 0  # zerowanie sumy

        while amount > 0:  # wykonuj, dopóki suma wrzuconych pieniędzy jest większa od zera
            if total_seconds >= 7200:  # jeśli suma sekund jest większa lub równa dwóch godzin zapisanej w sekundach
                if amount >= 5:  # jeśli suma jest większa lub równa 5
                    total_seconds += math.floor((amount / 5)) * 60 * 60  # dodanie całkowitej liczby godzin
                    amount -= 5 * math.floor((amount / 5))  # odjęcia całkowitej liczby godzin od sumy
                else:
                    seconds = amount * 100 * Decimal(grosz_xh)  # obliczona liczba sekund
                    total_seconds += seconds  # dodanie obliczonych sekund do całościowej liczby sekund
                    amount = 0  # zerowanie sumy

        temp_seconds = total_seconds
        total_seconds -= self.previous_time  # od całkowitego czasu odjęcie wcześniejszego
        self.previous_time = temp_seconds  # ustawienie nowego wcześniejszego czasu

        return int(total_seconds)

    def departure_date(self):
        """ Metoda ustawiająca datę wyjazdu """

        free_hours = [x for x in range(0, 24) if x not in range(8, 20)]  # lista z darmowymi godzinami
        amount = self.inserted_money_by_user  # suma przechowywanych pieniędzy
        seconds_paid = self.seconds_for_money(amount)  # liczba zapłaconych sekund
        if seconds_paid > 0:  # jeśli liczba zapłaconych sekund jest większa od zera
            if self.departure_time.weekday() == 5:  # jeśli jest sobota
                self.departure_time = self.departure_time.replace(hour=8, minute=00) + timedelta(days=2)

            elif self.departure_time.weekday() == 6:  # jeśli jest niedziela
                self.departure_time = self.departure_time.replace(hour=8, minute=00) + timedelta(days=1)

            elif self.departure_time.hour in free_hours:  # jeśli są dni robocze i aktualna godzina jest darmowa
                if self.departure_time.hour > 19:  # jeśli jest po godzinie 19:00
                    self.departure_time = self.departure_time.replace(hour=8, minute=00) + timedelta(days=1)
                else:  # jeśli jest godzina między 0 a 8
                    self.departure_time = self.departure_time.replace(hour=8, minute=00)

            # wyświetlenie w label zaktualizowanej daty wyjazdu
            self.departure_time = self.rules(self.departure_time, seconds_paid)
            self.interface.window.date_of_departure_label.config(text=self.departure_time.strftime("%Y-%m-%d %H:%M"))

    def confirm(self):
        """ Funkcja włączająca się przy kliknięciu przycisku 'Zatwierdź' """

        self.input_validator()  # sprawdzenie walidacji numeru rejestracyjnego
        if self.inserted_money_by_user > 0:  # wykonanie, jeśli suma monet jest większa od 0
            self.confirmation_of_payment()  # wykonanie funkcji potwierdzającej płatność
            self.reset()  # po potwierdzeniu rezerwacji reset parkomatu do stanu początkowego
        else:  # w przeciwnym wypadku wyświetl błąd
            raise NotInsertedMoney("Nie wrzucono pieniędzy.")

    def reset(self):
        """ Funkcja resetująca parkomat do stanu początkowego """

        self.interface.window.registration_number_entry.delete(0, "end")  # reset pola z numerem rejestracyjnym
        self.interface.window.sum_of_money_label.config(text="0.00")  # reset pola z wrzuconymi pieniędzmi
        self.interface.window.date_of_departure_label.config(text="")  # reset pola z datą wyjazdu
        self.global_date = datetime.now()  # reset czasu parkomatu do stanu początkowego
        self.departure_time = self.global_date  # ustawienie z powrotem czasu wyjazdy do stanu początkowego
        self.interface.window.number_of_money_entry.delete(0, "end")  # reset pola z liczbą monet
        self.interface.window.number_of_money_entry.insert(0, "1")  # wpisanie domyślnej wartości
        self.interface.window.hour_entry.delete(0, "end")  # reset entry z godziną
        self.interface.window.hour_entry.insert(0, "0")  # wpisanie domyślnej wartości
        self.interface.window.minute_entry.delete(0, "end")  # reset entry z minutą
        self.interface.window.minute_entry.insert(0, "0")  # wpisanie domyślnej wartości
        self.previous_time = 0  # reset poprzednio dodanego czasu
        self.inserted_money_by_user = Decimal("0.00")  # reset wrzuconych pieniędzy dla użytkownika


from subprocess import call
from metux.util.specobject import SpecError

def rsync_ssh(username, hostname, source, path):
    return (call([
        'rsync',
        '--progress',
        '--rsh=ssh',
        '-r',
        source+"/",
        username+"@"+hostname+":/"+path ]) == 0)

def run_upload(param):
    if param['protocol'] == 'rsync+ssh':
        return rsync_ssh(param['username'], param['hostname'], param['source'], param['path']);

    raise SpecError("unknown upload protocol: %s" % param['protocol'])


from django.urls import path, re_path
from app import views

urlpatterns = [
    # Matches any html file - to be used for gentella
    # Avoid using your .html in your resources.
    # Or create a separate django app.
    re_path(r'^.*\.html', views.gentella_html, name='index'),

    # The home page
    path('', views.index, name='index'),
    path('outliers', views.outliers, name='outliers'),
    path('data_fresh', views.data_fresh, name="data_fresh"),
    path('data_fresh\\', views.data_fresh, name="data_fresh"),
    path('data_fresh/', views.data_fresh, name="data_fresh"),
    path('data_fresh_tem_table', views.data_table_tem_fresh_with_pred, name='data_table_tem_fresh'),
    path('data_live_tem', views.live_tem, name='data_live_tem'),
]


# pylint:disable=unused-argument
# pylint:disable=redefined-outer-name

from contextlib import contextmanager
from typing import Any, AsyncIterable, Callable, Iterator
from unittest.mock import AsyncMock

import pytest
from faker import Faker
from fastapi import FastAPI, status
from httpx import HTTPError, Response
from models_library.sidecar_volumes import VolumeCategory, VolumeStatus
from pydantic import AnyHttpUrl, parse_obj_as
from pytest import LogCaptureFixture, MonkeyPatch
from pytest_mock import MockerFixture
from pytest_simcore.helpers.typing_env import EnvVarsDict
from simcore_service_director_v2.core.settings import AppSettings
from simcore_service_director_v2.modules.dynamic_sidecar.api_client._errors import (
    ClientHttpError,
    UnexpectedStatusError,
)
from simcore_service_director_v2.modules.dynamic_sidecar.api_client._public import (
    SidecarsClient,
    get_sidecars_client,
)
from simcore_service_director_v2.modules.dynamic_sidecar.api_client._public import (
    setup as api_client_setup,
)
from simcore_service_director_v2.modules.dynamic_sidecar.api_client._public import (
    shutdown,
)
from simcore_service_director_v2.modules.dynamic_sidecar.errors import (
    EntrypointContainerNotFoundError,
)

@pytest.fixture
def dynamic_sidecar_endpoint() -> AnyHttpUrl:
    return parse_obj_as(AnyHttpUrl, "http://missing-host:1111")

@pytest.fixture
def mock_env(monkeypatch: MonkeyPatch, mock_env: EnvVarsDict) -> None:
    monkeypatch.setenv("S3_ACCESS_KEY", "")
    monkeypatch.setenv("S3_SECRET_KEY", "")
    monkeypatch.setenv("S3_BUCKET_NAME", "")
    monkeypatch.setenv("R_CLONE_PROVIDER", "MINIO")

    monkeypatch.setenv("POSTGRES_HOST", "")
    monkeypatch.setenv("POSTGRES_USER", "")
    monkeypatch.setenv("POSTGRES_PASSWORD", "")
    monkeypatch.setenv("POSTGRES_DB", "")

    # reduce number of retries to make more reliable
    monkeypatch.setenv("DYNAMIC_SIDECAR_CLIENT_REQUEST_TIMEOUT_S", "3")
    monkeypatch.setenv("S3_ENDPOINT", "")

@pytest.fixture
async def sidecars_client(
    mock_env: EnvVarsDict, faker: Faker
) -> AsyncIterable[SidecarsClient]:
    app = FastAPI()
    app.state.settings = AppSettings.create_from_envs()

    # WARNING: pytest gets confused with 'setup', use instead alias 'api_client_setup'
    await api_client_setup(app)
    yield get_sidecars_client(app, faker.uuid4())
    await shutdown(app)

@pytest.fixture
def request_timeout() -> int:
    # below refer to exponential wait step duration
    return 1 + 2

@pytest.fixture
def raise_request_timeout(
    monkeypatch: MonkeyPatch, request_timeout: int, mock_env: EnvVarsDict
) -> None:
    monkeypatch.setenv("DYNAMIC_SIDECAR_CLIENT_REQUEST_TIMEOUT_S", f"{request_timeout}")

@pytest.fixture
def get_patched_client(
    sidecars_client: SidecarsClient, mocker: MockerFixture
) -> Callable:
    @contextmanager
    def wrapper(
        method: str,
        return_value: Any | None = None,
        side_effect: Callable | None = None,
    ) -> Iterator[SidecarsClient]:
        mocker.patch(
            f"simcore_service_director_v2.modules.dynamic_sidecar.api_client._thin.ThinSidecarsClient.{method}",
            return_value=return_value,
            side_effect=side_effect,
        )
        yield sidecars_client

    return wrapper

@pytest.mark.parametrize("is_healthy", [True, False])
@pytest.mark.parametrize("with_retry", [True, False])
async def test_is_healthy(
    get_patched_client: Callable,
    dynamic_sidecar_endpoint: AnyHttpUrl,
    is_healthy: bool,
    with_retry: bool,
) -> None:
    mock_json = {"is_healthy": is_healthy}
    with get_patched_client(
        "get_health" if with_retry else "get_health_no_retry",
        return_value=Response(status_code=status.HTTP_200_OK, json=mock_json),
    ) as client:
        assert (
            await client.is_healthy(dynamic_sidecar_endpoint, with_retry=with_retry)
            == is_healthy
        )

async def test_is_healthy_times_out(
    raise_request_timeout: None,
    sidecars_client: SidecarsClient,
    dynamic_sidecar_endpoint: AnyHttpUrl,
    caplog_info_level: LogCaptureFixture,
) -> None:
    assert await sidecars_client.is_healthy(dynamic_sidecar_endpoint) is False
    # check if the right amount of messages was captured by the logs
    unexpected_counter = 1
    for log_message in caplog_info_level.messages:
        if log_message.startswith("Retrying"):
            assert "as it raised" in log_message
            continue
        assert log_message.startswith(f"Request timed-out after {unexpected_counter}")
        unexpected_counter += 1

@pytest.mark.parametrize(
    "side_effect",
    [
        pytest.param(
            UnexpectedStatusError(
                Response(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    content="some mocked error",
                    request=AsyncMock(),
                ),
                status.HTTP_200_OK,
            ),
            id="UnexpectedStatusError",
        ),
        pytest.param(
            ClientHttpError(HTTPError("another mocked error")), id="HTTPError"
        ),
    ],
)
async def test_is_healthy_api_error(
    get_patched_client: Callable,
    dynamic_sidecar_endpoint: AnyHttpUrl,
    side_effect: Exception,
) -> None:
    with get_patched_client(
        "get_health",
        side_effect=side_effect,
    ) as client:
        assert await client.is_healthy(dynamic_sidecar_endpoint) == False

async def test_containers_inspect(
    get_patched_client: Callable, dynamic_sidecar_endpoint: AnyHttpUrl
) -> None:
    mock_json = {"ok": "data"}
    with get_patched_client(
        "get_containers",
        return_value=Response(status_code=status.HTTP_200_OK, json=mock_json),
    ) as client:
        assert await client.containers_inspect(dynamic_sidecar_endpoint) == mock_json

async def test_containers_docker_status_api_ok(
    get_patched_client: Callable, dynamic_sidecar_endpoint: AnyHttpUrl
) -> None:
    mock_json = {"container_id": {"ok": "data"}}
    with get_patched_client(
        "get_containers",
        return_value=Response(status_code=status.HTTP_200_OK, json=mock_json),
    ) as client:
        assert (
            await client.containers_docker_status(dynamic_sidecar_endpoint) == mock_json
        )

async def test_containers_docker_status_api_error(
    get_patched_client: Callable, dynamic_sidecar_endpoint: AnyHttpUrl
) -> None:
    with get_patched_client(
        "get_containers",
        side_effect=UnexpectedStatusError(
            Response(
                status_code=status.HTTP_400_BAD_REQUEST,
                content="some mocked error",
                request=AsyncMock(),
            ),
            status.HTTP_200_OK,
        ),
    ) as client:
        assert await client.containers_docker_status(dynamic_sidecar_endpoint) == {}

async def test_disable_service_ports_io(
    get_patched_client: Callable, dynamic_sidecar_endpoint: AnyHttpUrl
) -> None:
    with get_patched_client(
        "patch_containers_ports_io",
        return_value=Response(status_code=status.HTTP_204_NO_CONTENT),
    ) as client:
        assert await client.disable_service_ports_io(dynamic_sidecar_endpoint) is None

async def test_enable_service_ports_io(
    get_patched_client: Callable, dynamic_sidecar_endpoint: AnyHttpUrl
) -> None:
    with get_patched_client(
        "patch_containers_ports_io",
        return_value=Response(status_code=status.HTTP_204_NO_CONTENT),
    ) as client:
        assert await client.enable_service_ports_io(dynamic_sidecar_endpoint) is None

@pytest.mark.parametrize("outputs_labels", [{}, {"ok": "data"}])
async def test_service_outputs_create_dirs(
    get_patched_client: Callable,
    dynamic_sidecar_endpoint: AnyHttpUrl,
    outputs_labels: dict[str, Any],
) -> None:
    with get_patched_client(
        "post_containers_ports_outputs_dirs",
        return_value=Response(status_code=status.HTTP_204_NO_CONTENT),
    ) as client:
        assert (
            await client.service_outputs_create_dirs(
                dynamic_sidecar_endpoint, outputs_labels
            )
            is None
        )

@pytest.mark.parametrize("dynamic_sidecar_network_name", ["a_test_network"])
async def test_get_entrypoint_container_name_ok(
    get_patched_client: Callable,
    dynamic_sidecar_endpoint: AnyHttpUrl,
    dynamic_sidecar_network_name: str,
) -> None:
    with get_patched_client(
        "get_containers_name",
        return_value=Response(status_code=status.HTTP_200_OK, json="a_test_container"),
    ) as client:
        assert (
            await client.get_entrypoint_container_name(
                dynamic_sidecar_endpoint, dynamic_sidecar_network_name
            )
            == "a_test_container"
        )

@pytest.mark.parametrize("dynamic_sidecar_network_name", ["a_test_network"])
async def test_get_entrypoint_container_name_api_not_found(
    get_patched_client: Callable,
    dynamic_sidecar_endpoint: AnyHttpUrl,
    dynamic_sidecar_network_name: str,
) -> None:
    with get_patched_client(
        "get_containers_name",
        side_effect=UnexpectedStatusError(
            Response(status_code=status.HTTP_404_NOT_FOUND, request=AsyncMock()),
            status.HTTP_204_NO_CONTENT,
        ),
    ) as client:
        with pytest.raises(EntrypointContainerNotFoundError):
            await client.get_entrypoint_container_name(
                dynamic_sidecar_endpoint, dynamic_sidecar_network_name
            )

@pytest.mark.parametrize("network_aliases", [[], ["an-alias"], ["alias-1", "alias-2"]])
async def test_attach_container_to_network(
    get_patched_client: Callable,
    dynamic_sidecar_endpoint: AnyHttpUrl,
    network_aliases: list[str],
) -> None:
    with get_patched_client(
        "post_containers_networks_attach",
        return_value=Response(status_code=status.HTTP_204_NO_CONTENT),
    ) as client:
        assert (
            # pylint:disable=protected-access
            await client._attach_container_to_network(
                dynamic_sidecar_endpoint,
                container_id="container_id",
                network_id="network_id",
                network_aliases=network_aliases,
            )
            is None
        )

async def test_detach_container_from_network(
    get_patched_client: Callable,
    dynamic_sidecar_endpoint: AnyHttpUrl,
) -> None:
    with get_patched_client(
        "post_containers_networks_detach",
        return_value=Response(status_code=status.HTTP_204_NO_CONTENT),
    ) as client:
        assert (
            # pylint:disable=protected-access
            await client._detach_container_from_network(
                dynamic_sidecar_endpoint,
                container_id="container_id",
                network_id="network_id",
            )
            is None
        )

@pytest.mark.parametrize("volume_category", VolumeCategory)
@pytest.mark.parametrize("volume_status", VolumeStatus)
async def test_update_volume_state(
    get_patched_client: Callable,
    dynamic_sidecar_endpoint: AnyHttpUrl,
    volume_category: VolumeCategory,
    volume_status: VolumeStatus,
) -> None:
    with get_patched_client(
        "put_volumes",
        return_value=Response(status_code=status.HTTP_204_NO_CONTENT),
    ) as client:
        assert (
            await client.update_volume_state(
                dynamic_sidecar_endpoint,
                volume_category=volume_category,
                volume_status=volume_status,
            )
            is None
        )


import os.path

from compiler import compile_file
from interpreter import VirtualMachine
import sys

if __name__ == '__main__':
    if len(sys.argv) < 2:
        raise RuntimeError("Not enough argument to start the compiler")
    else:
        if sys.argv[1] == "--version":
            print("0.2.0-dev")
        else:
            compiled = compile_file(sys.argv[1])
            vm = VirtualMachine()
            vm.load_bytecode(compiled, path=os.path.abspath(sys.argv[1]))
            vm.init_eval_loop()


import argparse
import copy
import csv
import os
import warnings

import numpy
import torch
import tqdm
import yaml
from torch.utils import data

from nets import nn
from utils import util
from utils.dataset import Dataset

warnings.filterwarnings("ignore")

def learning_rate(args, params):
    def fn(x):
        return (1 - x / args.epochs) * (1.0 - params['lrf']) + params['lrf']

    return fn

def train(args, params):
    # Model
    model = nn.yolo_v5_n(len(params['names'].values())).cuda()

    # Model attributes
    params['box'] *= 3 / model.head.nl
    params['obj'] *= (args.input_size / 640) ** 2 * 3 / model.head.nl
    params['cls'] *= len(params['names'].values()) / 80 * 3 / model.head.nl

    # Optimizer
    accumulate = max(round(64 / (args.batch_size * args.world_size)), 1)
    params['weight_decay'] *= args.batch_size * args.world_size * accumulate / 64

    p = [], [], []
    for v in model.modules():
        if hasattr(v, 'bias') and isinstance(v.bias, torch.nn.Parameter):
            p[2].append(v.bias)
        if isinstance(v, torch.nn.BatchNorm2d):
            p[1].append(v.weight)
        elif hasattr(v, 'weight') and isinstance(v.weight, torch.nn.Parameter):
            p[0].append(v.weight)

    optimizer = torch.optim.SGD(p[2], params['lr0'], params['momentum'], nesterov=True)

    optimizer.add_param_group({'params': p[0], 'weight_decay': params['weight_decay']})
    optimizer.add_param_group({'params': p[1]})
    del p

    # Scheduler
    lr = learning_rate(args, params)
    scheduler = torch.optim.lr_scheduler.LambdaLR(optimizer, lr, last_epoch=-1)

    # EMA
    ema = util.EMA(model) if args.local_rank == 0 else None

    filenames = []
    with open('../Dataset/COCO/train2017.txt') as reader:
        for filename in reader.readlines():
            filename = filename.rstrip().split('/')[-1]
            filenames.append('../Dataset/COCO/images/train2017/' + filename)

    dataset = Dataset(filenames, args.input_size, params, True)

    if args.world_size <= 1:
        sampler = None
    else:
        sampler = data.distributed.DistributedSampler(dataset)

    loader = data.DataLoader(dataset, args.batch_size, sampler is None, sampler,
                             num_workers=8, pin_memory=True, collate_fn=Dataset.collate_fn)

    util.check_anchors(dataset, model, args, params)
    model.half().float()  # pre-reduce anchor precision

    if args.world_size > 1:
        # DDP mode
        model = torch.nn.SyncBatchNorm.convert_sync_batchnorm(model)
        model = torch.nn.parallel.DistributedDataParallel(module=model,
                                                          device_ids=[args.local_rank],
                                                          output_device=args.local_rank)

    # Start training
    best = 0
    num_batch = len(loader)
    amp_scale = torch.cuda.amp.GradScaler()
    criterion = util.ComputeLoss(model, params)
    num_warmup = max(round(params['warmup_epochs'] * num_batch), 100)
    with open('weights/step.csv', 'w') as f:
        if args.local_rank == 0:
            writer = csv.DictWriter(f, fieldnames=['epoch', 'mAP@50', 'mAP'])
            writer.writeheader()
        for epoch in range(args.epochs):
            model.train()

            m_loss = util.AverageMeter()
            if args.world_size > 1:
                sampler.set_epoch(epoch)
            p_bar = enumerate(loader)
            if args.local_rank == 0:
                print(('\n' + '%10s' * 3) % ('epoch', 'memory', 'loss'))
            if args.local_rank == 0:
                p_bar = tqdm.tqdm(p_bar, total=num_batch)  # progress bar

            optimizer.zero_grad()

            for i, (samples, targets, _) in p_bar:
                x = i + num_batch * epoch  # number of iterations
                samples = samples.cuda().float() / 255
                targets = targets.cuda()

                # Warmup
                if x <= num_warmup:
                    xp = [0, num_warmup]
                    fp = [1, 64 / (args.batch_size * args.world_size)]
                    accumulate = max(1, numpy.interp(x, xp, fp).round())
                    for j, y in enumerate(optimizer.param_groups):
                        if j == 0:
                            fp = [params['warmup_bias_lr'], y['initial_lr'] * lr(epoch)]
                        else:
                            fp = [0.0, y['initial_lr'] * lr(epoch)]
                        y['lr'] = numpy.interp(x, xp, fp)
                        if 'momentum' in y:
                            fp = [params['warmup_momentum'], params['momentum']]
                            y['momentum'] = numpy.interp(x, xp, fp)

                # Forward
                with torch.cuda.amp.autocast():
                    outputs = model(samples)  # forward
                loss = criterion(outputs, targets)

                m_loss.update(loss.item(), samples.size(0))

                loss *= args.batch_size  # loss scaled by batch_size
                loss *= args.world_size  # gradient averaged between devices in DDP mode

                # Backward
                amp_scale.scale(loss).backward()

                # Optimize
                if x % accumulate == 0:
                    amp_scale.step(optimizer)  # optimizer.step
                    amp_scale.update()
                    optimizer.zero_grad()
                    if ema:
                        ema.update(model)

                # Log
                if args.local_rank == 0:
                    memory = f'{torch.cuda.memory_reserved() / 1E9:.3g}G'  # (GB)
                    s = ('%10s' * 2 + '%10.4g') % (f'{epoch + 1}/{args.epochs}', memory, m_loss.avg)
                    p_bar.set_description(s)
            # Scheduler
            scheduler.step()

            if args.local_rank == 0:
                # mAP
                last = test(args, params, ema.ema)
                writer.writerow({'mAP': str(f'{last[1]:.3f}'),
                                 'epoch': str(epoch + 1).zfill(3),
                                 'mAP@50': str(f'{last[0]:.3f}')})
                f.flush()

                # Update best mAP
                if last[1] > best:
                    best = last[1]

                # Save model
                ckpt = {'model': copy.deepcopy(ema.ema).half()}

                # Save last, best and delete
                torch.save(ckpt, './weights/last.pt')
                if best == last[1]:
                    torch.save(ckpt, './weights/best.pt')
                del ckpt

    if args.local_rank == 0:
        util.strip_optimizer('./weights/best.pt')  # strip optimizers
        util.strip_optimizer('./weights/last.pt')  # strip optimizers

    torch.cuda.empty_cache()

@torch.no_grad()
def test(args, params, model=None):
    filenames = []
    with open('../Dataset/COCO/val2017.txt') as reader:
        for filename in reader.readlines():
            filename = filename.rstrip().split('/')[-1]
            filenames.append('../Dataset/COCO/images/val2017/' + filename)

    dataset = Dataset(filenames, args.input_size, params, False)
    loader = data.DataLoader(dataset, 4, False, num_workers=4,
                             pin_memory=True, collate_fn=Dataset.collate_fn)

    if model is None:
        model = torch.load('./weights/best.pt', map_location='cuda')['model']

    model.half()

    # Configure
    model.eval()
    iou_v = torch.linspace(0.5, 0.95, 10).cuda()  # iou vector for mAP@0.5:0.95
    n_iou = iou_v.numel()

    m_pre = 0.
    m_rec = 0.
    map50 = 0.
    mean_ap = 0.
    metrics = []
    p_bar = tqdm.tqdm(loader, desc=('%10s' * 3) % ('precision', 'recall', 'mAP'))
    for samples, targets, shapes in p_bar:
        samples = samples.cuda()
        targets = targets.cuda()

        samples = samples.half()  # uint8 to fp16/32
        samples = samples / 255.0  # 0 - 255 to 0.0 - 1.0

        _, _, h, w = samples.shape  # batch size, channels, height, width

        # Inference
        outputs = model(samples)

        # NMS
        targets[:, 2:] *= torch.tensor((w, h, w, h)).cuda()  # to pixels
        outputs = util.non_max_suppression(outputs, 0.001, 0.6)

        # Metrics
        for i, output in enumerate(outputs):
            labels = targets[targets[:, 0] == i, 1:]
            correct = torch.zeros(output.shape[0], n_iou, dtype=torch.bool).cuda()

            if output.shape[0] == 0:
                if labels.shape[0]:
                    metrics.append((correct, *torch.zeros((3, 0)).cuda()))
                continue

            detections = output.clone()
            util.scale(detections[:, :4], samples[i].shape[1:], shapes[i][0], shapes[i][1])

            # Evaluate
            if labels.shape[0]:
                tbox = labels[:, 1:5].clone()  # target boxes
                tbox[:, 0] = labels[:, 1] - labels[:, 3] / 2  # top left x
                tbox[:, 1] = labels[:, 2] - labels[:, 4] / 2  # top left y
                tbox[:, 2] = labels[:, 1] + labels[:, 3] / 2  # bottom right x
                tbox[:, 3] = labels[:, 2] + labels[:, 4] / 2  # bottom right y
                util.scale(tbox, samples[i].shape[1:], shapes[i][0], shapes[i][1])

                correct = numpy.zeros((detections.shape[0], iou_v.shape[0]))
                correct = correct.astype(bool)

                t_tensor = torch.cat((labels[:, 0:1], tbox), 1)
                iou = util.box_iou(t_tensor[:, 1:], detections[:, :4])
                correct_class = t_tensor[:, 0:1] == detections[:, 5]
                for j in range(len(iou_v)):
                    x = torch.where((iou >= iou_v[j]) & correct_class)
                    if x[0].shape[0]:
                        matches = torch.cat((torch.stack(x, 1), iou[x[0], x[1]][:, None]), 1)
                        matches = matches.cpu().numpy()
                        if x[0].shape[0] > 1:
                            matches = matches[matches[:, 2].argsort()[::-1]]
                            matches = matches[numpy.unique(matches[:, 1], return_index=True)[1]]
                            matches = matches[numpy.unique(matches[:, 0], return_index=True)[1]]
                        correct[matches[:, 1].astype(int), j] = True
                correct = torch.tensor(correct, dtype=torch.bool, device=iou_v.device)
            metrics.append((correct, output[:, 4], output[:, 5], labels[:, 0]))

    # Compute metrics
    metrics = [torch.cat(x, 0).cpu().numpy() for x in zip(*metrics)]  # to numpy
    if len(metrics) and metrics[0].any():
        tp, fp, m_pre, m_rec, map50, mean_ap = util.compute_ap(*metrics)

    # Print results
    print('%10.3g' * 3 % (m_pre, m_rec, mean_ap))

    # Return results
    model.float()  # for training
    return map50, mean_ap

@torch.no_grad()
def demo(args):
    import cv2

    # Load model
    model = torch.load('./weights/best.pt', map_location='cuda')['model'].float()
    model.half()
    model.eval()

    camera = cv2.VideoCapture(0)
    # Check if camera opened successfully
    if not camera.isOpened():
        print("Error opening video stream or file")
    # Read until video is completed
    while camera.isOpened():
        # Capture frame-by-frame
        success, frame = camera.read()
        if success:
            image = frame.copy()
            shape = image.shape[:2]

            r = args.input_size / max(shape[0], shape[1])
            if r != 1:
                resample = cv2.INTER_LINEAR if r > 1 else cv2.INTER_AREA
                image = cv2.resize(image, dsize=(int(shape[1] * r), int(shape[0] * r)), interpolation=resample)
            height, width = image.shape[:2]

            # Scale ratio (new / old)
            r = min(1.0, args.input_size / height, args.input_size / width)

            # Compute padding
            pad = int(round(width * r)), int(round(height * r))
            w = (args.input_size - pad[0]) / 2
            h = (args.input_size - pad[1]) / 2

            if (width, height) != pad:  # resize
                image = cv2.resize(image, pad, interpolation=cv2.INTER_LINEAR)
            top, bottom = int(round(h - 0.1)), int(round(h + 0.1))
            left, right = int(round(w - 0.1)), int(round(w + 0.1))
            image = cv2.copyMakeBorder(image, top, bottom, left, right, cv2.BORDER_CONSTANT)  # add border

            # Convert HWC to CHW, BGR to RGB
            x = image.transpose((2, 0, 1))[::-1]
            x = numpy.ascontiguousarray(x)
            x = torch.from_numpy(x)
            x = x.unsqueeze(dim=0)
            x = x.cuda()
            x = x.half()
            x = x / 255
            # Inference
            outputs = model(x)
            # NMS
            outputs = util.non_max_suppression(outputs, 0.25, 0.7)
            for output in outputs:
                output[:, [0, 2]] -= w  # x padding
                output[:, [1, 3]] -= h  # y padding
                output[:, :4] /= min(height / shape[0], width / shape[1])

                output[:, 0].clamp_(0, shape[1])  # x1
                output[:, 1].clamp_(0, shape[0])  # y1
                output[:, 2].clamp_(0, shape[1])  # x2
                output[:, 3].clamp_(0, shape[0])  # y2

                for box in output:
                    box = box.cpu().numpy()
                    x1, y1, x2, y2, score, index = box
                    cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), int(y2)), (0, 255, 0), 2)

            cv2.imshow('Frame', frame)
            # Press Q on keyboard to  exit
            if cv2.waitKey(25) & 0xFF == ord('q'):
                break
        # Break the loop
        else:
            break
    # When everything done, release the video capture object
    camera.release()

    # Closes all the frames
    cv2.destroyAllWindows()

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--input-size', default=640, type=int)
    parser.add_argument('--batch-size', default=32, type=int)
    parser.add_argument('--local_rank', default=0, type=int)
    parser.add_argument('--epochs', default=600, type=int)
    parser.add_argument('--train', action='store_true')
    parser.add_argument('--test', action='store_true')
    parser.add_argument('--demo', action='store_true')

    args = parser.parse_args()

    args.local_rank = int(os.getenv('LOCAL_RANK', 0))
    args.world_size = int(os.getenv('WORLD_SIZE', 1))

    if args.world_size > 1:
        torch.cuda.set_device(device=args.local_rank)
        torch.distributed.init_process_group(backend='nccl', init_method='env://')

    if args.local_rank == 0:
        if not os.path.exists('weights'):
            os.makedirs('weights')

    util.setup_seed()
    util.setup_multi_processes()

    with open(os.path.join('utils', 'args.yaml'), errors='ignore') as f:
        params = yaml.safe_load(f)

    if args.train:
        train(args, params)
    if args.test:
        test(args, params)
    if args.demo:
        demo(args)

if __name__ == "__main__":
    main()


#!/usr/bin/env python
"""
    Usage:
        python detectface.py -i image.jpg
"""

from argparse import ArgumentParser
import boto3
from pprint import pprint
import sys

def get_client(endpoint):
    client = boto3.client('rekognition')
    return client

def get_args():
    parser = ArgumentParser(description='Detect faces')
    parser.add_argument('-e', '--endpoint')
    parser.add_argument('-i', '--image')
    return parser.parse_args()

if __name__ == '__main__':
    args = get_args()
    if (args.image is None):
        print('''
        Usage:
            python detectface.py --help
            ''')
        sys.exit(-1)
    client = get_client(args.endpoint)
    with open(args.image, 'rb') as image:
        response = client.detect_faces(Image={'Bytes': image.read()},Attributes=['ALL'])
        pprint(response)


#三方库  xlrd /xlwt / xlutils
import  xlrd
import  xlwt
import  xlutils
wb = xlrd.open_workbook('table/阿里巴巴2020年股票数据.xls')
#获取所有工作表的名字
# print(wb.sheet_names())

# sheet1 = wb.sheet_names('表格1')   #通过工作表名获取
sheet = wb.sheet_by_index(0) #通过工作表的下标ID获取工作表

#获取工作表的行数，列数
# print(sheet.nrows,sheet.ncols)

#获取单元格数据 第一行的第一列
for i in range(sheet.nrows):
    for j in range(sheet.ncols):
        value1 = sheet.cell(i,j).value
        if i >0 :
            print(f"{value1:.2f}", end='\t')
        else:
            print(value1, end=' \t')
    print()
        # print(sheet.row(i)[j].value , end=' ')


import math

def isLeapYear(x):
	if (x % 4 != 0):
		return False
	elif (x % 100 != 0):
		return True
	elif (x % 400 != 0):
		return False
	else:
		return True

try:
	y = int(input("Enter number to test: "))
	if (y < 0):
		raise ValueError()
except ValueError:
		print("Input is not an positive integer.")
else:
	if (isLeapYear(y)):
		print("{} is a leap year.".format(y))
	else:
		print("{} is not a leap year.".format(y))
finally:
	input("Press ENTER to exit")


import configparser
import os

from core.constants import CONFIG_FILE_PATH

__all__ = [
    'BotConfigurator'
]

class BotConfigurator(object):
    """ Объект-конфигуратор приложения. """

    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, 'instance'):
            cls.instance = super(BotConfigurator, cls).__new__(cls)
        return cls.instance

    def __init__(self):
        config_path = os.path.join(CONFIG_FILE_PATH)

        if os.path.isfile(config_path):
            self._app_config = configparser.ConfigParser()
            self._app_config.read(config_path)

        else:
            self._app_config = {
                'telegram': {
                    'token': os.environ['TELEGRAM_TOKEN'],
                    'proxy_url': os.environ.get('PROXY_URL', None)
                },
                'dialog_flow': {
                    'token': os.environ['DIALOG_FLOW_TOKEN'],
                    'lang': os.environ['DIALOG_FLOW_LANG'],
                    'session_id': os.environ['DIALOG_FLOW_SESSION_ID']
                }
            }

    @property
    def app_config(self):
        return self._app_config


import os
from flask import Flask, flash, request, redirect, url_for, send_from_directory, jsonify
from werkzeug.utils import secure_filename
from excel import Excel
from translator import Translator

UPLOAD_FOLDER = './text_files'
DOWNLOAD_FOLDER = './excel_files'
ALLOWED_EXTENSIONS = {'txt'}

app = Flask(__name__, static_folder='./client/build', static_url_path='/')
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['DOWNLOAD_FOLDER'] = DOWNLOAD_FOLDER
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY')

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/')
def index():
    return app.send_static_file('index.html')

@app.route('/api/', methods=["POST"])
def create_terminology():
    if 'file' not in request.files:
        code = 400
        msg = "file not in request"
        return code, msg

    file = request.files['file']

    if file.filename == '':
        code = 400
        msg = "file name empty"
        return code, msg

    if file and allowed_file(file.filename):
        filename = secure_filename(file.filename)
        file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))

        text = open(os.path.join(
            app.config['UPLOAD_FOLDER'], filename), 'r').read()

        if len(text) == 0:
            code = 400
            msg = "File is empty, please provide a valid '.txt' file."
            return code, msg
        else:
            translator = Translator(text)
            translator.detect_source_language(" ".join(text.split(" ")[:5]))
            translator.set_stop_words()
            tokenized_text = translator.tokenize_text()

            words = translator.parse_words_alpha(tokenized_text)
            terms = translator.translate(words)

            source_language, target_language = translator.get_source_and_target()

            terminology_excel = Excel(os.path.splitext(filename)[0])
            terminology_excel.write_worksheet(
                terms, source_language, target_language)
            terminology_excel.close_workbook()

            response = send_from_directory(
                app.config['DOWNLOAD_FOLDER'], f'{os.path.splitext(filename)[0]}.xlsx', as_attachment=True)

            os.remove(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            os.remove(os.path.join(
                app.config['DOWNLOAD_FOLDER'], f'{os.path.splitext(filename)[0]}.xlsx'))

            return response

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=int(os.environ.get('PORT', 5000)))


# cython:language_level=3

import numpy as np
from scipy import optimize
import matplotlib.pyplot as plt

deltas = 2000
a = 215
r = 290
def fx(n):
    global deltas, a, r
    x1 = a+n
    x2 = a-n
    return deltas - (area(x2, r) - area(x1, r))

def fx1(n):
    a = 215
    r = 290

    x1 = a+n
    x2 = a-n
    return (area(x2, r) - area(x1, r))

def area(x,r):
    S = (r**2)*np.arccos(x/r) - x*np.sqrt(r**2 - x**2)
    return S

# x = [x * 2.77 for x in range(11)]
# x1 = [x * 0.02 for x in range(0, 11)]
# y = []
# for i in range(11):
#     a = x[i]
#     y.append(fx1(a)+4909)
#
# print(y)
#
# plt.plot(x1,y)
# plt.xlabel('offset_pixel')
# plt.ylabel('pixel_different')
# x_ticks = np.arange(0,0.23,0.02)
# plt.xticks(x_ticks)
# plt.show()
# plt.savefig('plot_fig.jpg')

# print(fx1(2.56))
# print(area(0, 290))

# print(fx(0))

def main(x1, x2, x3):
    global deltas, a, r
    deltas = x1
    a = x2
    r = x3

root = optimize.bisect(fx, 0, 30)
print(root)
root = root * 0.0024
# #
print(root)


T = int(input())

RS_list = []
for _ in range(T):
    R, S = input().split()
    temp = [i*int(R) for i in list(S)]
    RS_list.append(''.join(temp))

for i in RS_list:
    print(i)


# ############################################################################ #
# This is part of the PPLT project.                                            #
#                                                                              #
# Copyright (C) 2003-2006 Hannes Matuschek <hmatuschek@gmx.net>                #
#                                                                              #
# This library is free software; you can redistribute it and/or                #
# modify it under the terms of the GNU Lesser General Public                   #
# License as published by the Free Software Foundation; either                 #
# version 2.1 of the License, or (at your option) any later version.           #
#                                                                              #
# This library is distributed in the hope that it will be useful,              #
# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU             #
# Lesser General Public License for more details.                              #
#                                                                              #
# You should have received a copy of the GNU Lesser General Public             #
# License along with this library; if not, write to the Free Software          #
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA    #
# ############################################################################ #

import S7Register;
import S7Message;
import pyDCPU;
import struct;

class Object(pyDCPU.MasterObject):
    def setup(self):
        self.Logger.info("Setup Simatic-S7");
        return(True);

    def connect(self,AddrStr):
        RegAddr = S7Register.S7Register(AddrStr);
        self.Logger.debug("MkConnect for %s(%s)"%(AddrStr, str(RegAddr)));
        if not RegAddr:
            raise pyDCPU.ModuleError("Can't split Address \"%s\", my wrong format or not supported address range."%AddrStr);

        #map s7-types to pplt-type-names:
        if RegAddr.GetType() in (S7Register.S7Bit,): Type = pyDCPU.TBool;
        elif RegAddr.GetType() in (S7Register.S7Byte, S7Register.S7Word, S7Register.S7DWord): Type = pyDCPU.TInteger;

        Connection = pyDCPU.ValueConnection(self, Type, RegAddr);
        return(Connection);

    def write(self, Connection, Value):
        if Value == None: raise pyDCPU.ModuleError("No value given to write!");

        Data = Value2Raw(Value, Connection.Address.GetType());          # convert Value to raw byte-data
        DataSet = S7Message.S7DataSet(Data, Connection.Address);        # assamble dataset
        CommSet = S7Message.S7CommandSet(S7Message.S7FunctionWrite, Connection.Address);    # assamble command set
        Message = S7Message.S7Message(CommSet, DataSet);                # assamble message

        self.Logger.debug("Will send a %i byte message."%len(Message.GetString()));

        self.Connection.flush()
        # write cmd-message:
        self.Connection.write(Message.GetString());

        # read response:
        MsgString = self.Connection.read_seq();

        Message = S7Message.S7Message(MsgString = MsgString);
        CommSet = Message.GetCommandSet();
        DataSet = Message.GetDataSet();
        if DataSet.GetErrCode() == 0xff: return(True);       # 0xff means: all ok.

        self.Logger.error("S7 returned error code: %x"%ord(DataSet.GetErrCode()));
        raise pyDCPU.ModuleError("S7 returned error code: %x"%ord(DataSet.GetErrCode()));

    def read(self, Connection, Len=None):
        self.Logger.debug("Read... Function %s, Addr: %s"%(str(S7Message.S7FunctionRead),str(Connection.Address)));
        CommSet = S7Message.S7CommandSet(S7Message.S7FunctionRead, Connection.Address);
        Message = S7Message.S7Message(CommSet);

        self.Connection.flush();
        ret = self.Connection.write(Message.GetString());

        MsgString = self.Connection.read_seq();

        Message = S7Message.S7Message(MsgString = MsgString);
        CommSet = Message.GetCommandSet();
        DataSet = Message.GetDataSet();

        if DataSet.GetErrCode() == 0xff:
            return Raw2Value(DataSet.GetDataString(), Connection.Address.GetType());

        self.Logger.error("S7 returned error-code: %x"%ord(DataSetGetErrorCode()));
        raise pyDCPU.ModuleError("S7 returned error-code: %x"%ord(DataSetGetErrorCode()));

def Raw2Value(Data, Type):
    if Type == S7Register.S7Bit: (value,) = struct.unpack("B",Data);
    elif Type == S7Register.S7Byte: (value,) = struct.unpack("B",Data);
    elif Type == S7Register.S7Word: (value,) = struct.unpack("H",Data);
    elif Type == S7Register.S7DWord: (value,) = struct.unpack("I",Data);
    return value;

def Value2Raw(Value, Type):
    if Type == S7Register.S7Bit: return struct.pack("B", int(Value));
    elif Type == S7Register.S7Byte: return struct.pack("B", int(Value));
    elif Type == S7Register.S7Word: return struct.pack("H", int(Value));
    elif Type == S7Register.S7DWord: return struct.pack("I", int(Value));


#!/usr/bin/python3.5
# -*-coding:Utf-8 -*
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_moons
from sklearn.decomposition import PCA
from matplotlib.ticker import FormatStrFormatter
from RBFKernelPCA import RBF_Kernel_PCA

# We create a dataset of two half moons and project them on 1 dimensional space
values, classes = make_moons(n_samples = 100, random_state = 123)
kernel_pca_values, lambdas = RBF_Kernel_PCA(values, gamma = 15, n_components = 1)

# We consider that the 26th point is a new point to project
new_value = values[25]
print('New value: {}'.format(new_value))
original_projected_value = kernel_pca_values[25]
print('Original projection: {}'.format(original_projected_value))

# We define a projection function for new values
def project_value(new_value, values, gamma, kernel_pca_values, lambdas):
    pairwise_distances = np.array([np.sum((new_value - row)**2) for row in values])
    kernel = np.exp(-gamma * pairwise_distances)
    return kernel.dot(kernel_pca_values / lambdas)

# We use the projection to recalculate the projection of the 26th point
new_projected_value = project_value(new_value, values, 15, kernel_pca_values, lambdas)
print('New projection: {}'.format(new_projected_value))

# Now we visualize the projection on the first principal components
plt.scatter(kernel_pca_values[classes == 0, 0], np.zeros((50)), color = 'red', marker = '^',alpha = 0.5)
plt.scatter(kernel_pca_values[classes == 1, 0], np.zeros((50)), color = 'blue', marker = 'o', alpha = 0.5)
plt.scatter(original_projected_value, 0, color = 'black', label = 'original projection of point X[25]', marker = '^', s = 100)
plt.scatter(new_projected_value, 0, color = 'green', label = 'remapped point X[25]', marker = 'x', s = 500)
plt.legend(scatterpoints = 1)
plt.show()


#right now, I am using this script to play around w/ differnt definitions of signal and control regions

import ROOT
from TIMBER.Analyzer import HistGroup, CutGroup
from TIMBER.Tools.Common import CompileCpp
from argparse import ArgumentParser
from XHYbbWW_class import XHYbbWW
from collections import OrderedDict

def KinematicLepton(self): #bringing this function in here so I can select lepton w/o quality/isolation cuts

    self.a.Define('kinEleIdx','kinElectron(Electron_pt,Electron_eta,Electron_phi,Higgs_phi,Wqq_phi)')
    self.a.Define('kinMuIdx','kinMuon(Muon_pt,Muon_eta,Muon_phi,Higgs_phi,Wqq_phi)')
    self.a.Cut('kinLepton_cut','kinEleIdx != -1 || kinMuIdx != -1') #at least one good lepton
    self.a.Define('LeptonType','LeptonIdx(kinEleIdx,kinMuIdx,Electron_pt,Muon_pt)') #picks higher pt signal lepton - output = 0 (lepton is electron) or 1 (lepton is muon)

    self.SIGLEP = self.getNweighted()
    self.AddCutflowColumn(self.SIGLEP,'SIGLEP')

    #For ease, merge some lepton columns that will be useful later (for lepton-type specific variables, use LeptonType to determine if electron or muon)
    self.a.Define('Lepton_pt','LeptonType == 1 ? Muon_pt[kinMuIdx] : Electron_pt[kinEleIdx]')
    self.a.Define('Lepton_eta','LeptonType == 1 ? Muon_eta[kinMuIdx] : Electron_eta[kinEleIdx]')
    self.a.Define('Lepton_phi','LeptonType == 1 ? Muon_phi[kinMuIdx] : Electron_phi[kinEleIdx]')
    self.a.Define('Lepton_mass','LeptonType == 1 ? Muon_mass[kinMuIdx] : Electron_mass[kinEleIdx]')

    return self.a.GetActiveNode()

def MXvsMY_studies(self):

    ##### NEW VARIABLES FOR LATER USE #####

    #W_leptonic transverse mass
    self.a.Define('W_massTran','TransverseMass(MET_pt,Lepton_pt,MET_phi,Lepton_phi)') #Transverse W mass
#   self.a.Define('W_massTran_genMET','TransverseMass(MET_fiducialGenPt,Lepton_pt,MET_fiducialGenPhi,Lepton_phi)') #using generator-level MET variables

    #Lorentz 4-vectors
    self.a.Define('MET_vect','hardware::TLvector(MET_pt,0,MET_phi,0)') #neutrino mass negligable, for now assuming MET_eta = 0 (p_z = 0)
    self.a.Define('Lepton_vect','hardware::TLvector(Lepton_pt,Lepton_eta,Lepton_phi,Lepton_mass)')
    self.a.Define('Wqq_vect','hardware::TLvector(Wqq_pt,Wqq_eta,Wqq_phi,Wqq_msoftdrop)')
    self.a.Define('Hbb_vect','hardware::TLvector(Higgs_pt,Higgs_eta,Higgs_phi,Higgs_msoftdrop)')

    #Invariant masses of W/Y/X
    self.a.Define('W_massInv','hardware::InvariantMass({MET_vect,Lepton_vect})') #full invariant mass
    self.a.Define('Y_mass','hardware::InvariantMass({Lepton_vect,MET_vect,Wqq_vect})')
    self.a.Define('X_mass','hardware::InvariantMass({Lepton_vect,MET_vect,Wqq_vect,Hbb_vect})')

    studiesPlots = HistGroup('studiesPlots')

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

    #First lets make some plots examining the lepton quality cuts in the different MC samples
    #Muon_mediumId, Electron_mvaFall17V2noIso vs eta, Electron_mvaFall17V2noIso_WP80, Electron_mvaFall17V2noIso_WP90, Electron_mvaFall17V2noIso_WPL

    start=self.a.GetActiveNode()
    muonEvents=self.a.Cut('Muon_events','LeptonType == 1')
    self.a.SetActiveNode(muonEvents)
    self.a.ObjectFromCollection('kinMu','Muon','kinMuIdx')

    #studiesPlots.Add('kinMu_mediumId',self.a.GetActiveNode().DataFrame.Histo1D(('kinMu_mediumId','kinMu_mediumId',2,0,2),'kinMu_mediumId','weight__nominal')) #bins may not work

    self.a.SetActiveNode(start)
    electronEvents=self.a.Cut('Electron_events','LeptonType == 0')
    self.a.SetActiveNode(electronEvents)
    self.a.ObjectFromCollection('kinEle','Electron','kinEleIdx')

    #studiesPlots.Add('kinEle_mvaFall17V2noIso vs eta',self.a.DataFrame.Histo2D(('kinEle_mvaFall17V2noIso vs eta','kinEle_mvaFall17V2noIso vs eta',1000,0,1,250,0,2.5),'kinEle_mvaFall17V2noIso', 'kinEle_eta','weight__nominal'))

    #Make three plots for electron mva (for different etas/ECAL regions)
    no_eta = self.a.GetActiveNode()
    inner_barrel = self.a.Cut('inner_barrel','abs(kinEle_eta) < 0.8')
    self.a.SetActiveNode(inner_barrel)
    studiesPlots.Add('kinEle_mvaFall17V2noIso (inner barrel)',self.a.DataFrame.Histo1D(('kinEle_mvaFall17V2noIso (|eta| < 0.8)','kinEle_mvaFall17V2noIso (inner barrel - |eta| < 0.8)',100,0,1),'kinEle_mvaFall17V2noIso', 'weight__nominal'))

    self.a.SetActiveNode(no_eta)
    outer_barrel = self.a.Cut('outer_barrel','abs(kinEle_eta) > 0.8 && abs(kinEle_eta) < 1.479')
    self.a.SetActiveNode(outer_barrel)
    studiesPlots.Add('kinEle_mvaFall17V2noIso (outer barrel)',self.a.DataFrame.Histo1D(('kinEle_mvaFall17V2noIso (0.8 < |eta| < 1.479)','kinEle_mvaFall17V2noIso (outer barrel - 0.8 < |eta| < 1.479)',100,0,1),'kinEle_mvaFall17V2noIso', 'weight__nominal'))

    self.a.SetActiveNode(no_eta)
    endcap = self.a.Cut('endcap','abs(kinEle_eta) > 1.479 && abs(kinEle_eta) < 2.5')
    self.a.SetActiveNode(endcap)
    studiesPlots.Add('kinEle_mvaFall17V2noIso (endcap)',self.a.DataFrame.Histo1D(('kinEle_mvaFall17V2noIso (1.479 < |eta| < 2.5)','kinEle_mvaFall17V2noIso (endcap - 1.479 < |eta| < 2.5)',100,0,1),'kinEle_mvaFall17V2noIso', 'weight__nominal'))

    '''
    studiesPlots.Add('kinEle_mvaFall17V2noIso_WP80',self.a.GetActiveNode().DataFrame.Histo1D(('kinEle_mvaFall17V2noIso_WP80','kinEle_mvaFall17V2noIso_WP80',2,0,2),'kinEle_mvaFall17V2noIso_WP80','weight__nominal').GetValue())
    print('kinele_mvaWP80 plot made')
    studiesPlots.Add('kinEle_mvaFall17V2noIso_WP90',self.a.GetActiveNode().DataFrame.Histo1D(('kinEle_mvaFall17V2noIso_WP90','kinEle_mvaFall17V2noIso_WP90',2,0,2),'kinEle_mvaFall17V2noIso_WP90','weight__nominal').GetValue())
    print('kinele_mvaWP90 plot made')
    studiesPlots.Add('kinEle_mvaFall17V2noIso_WPL',self.a.GetActiveNode().DataFrame.Histo1D(('kinEle_mvaFall17V2noIso_WPL','kinEle_mvaFall17V2noIso_WPL',2,0,2),'kinEle_mvaFall17V2noIso_WPL','weight__nominal').GetValue())
    print('kinele_mvaWPL plot made')
    '''

    self.a.SetActiveNode(start)

    taggers = ['particleNetMD']

    # now we want to plot mX vs mY for QCD, ttbar, and signal
    for t in taggers:
        self.ApplyMassCuts()
        start=self.a.GetActiveNode()

        # We use Wqq tagging scores to divide data into two regions: signal (enriched in signal) and control (enriched in background)
        #    - Signal:    Wqq > 0.8, pass lepton medium ID
        #    - Control:    Wqq < 0.8, fail lepton medium ID
        # We define a pass/fail criteria for the Hbb score within each region
        #   - Region 1 (fail):      Hbb < 0.94
        #   - Region 2 (pass):      Hbb > 0.94

        SR=self.ApplySRorCR('SR',t)
        SR_FP=self.ApplyPassFail('SR',t)

        self.a.SetActiveNode(start)
        CR=self.ApplySRorCR('CR',t)
        CR_FP=self.ApplyPassFail('CR',t)

        nodes=OrderedDict()
        nodes.update(SR_FP)
        nodes.update(CR_FP)

        bins = [80,0,4500]

        for node in nodes.keys():
            self.a.SetActiveNode(nodes[node])
            print('MX vs MY: Plotting for {}'.format(node))
            studiesPlots.Add('MXvsMY_{}'.format(node), self.a.DataFrame.Histo2D(('MXvsMY_{}'.format(node), 'X vs Y Invariant Mass - {} {}'.format(node.split('_')[1],node.split('_')[0]), bins[0], bins[1], bins[2], bins[0], bins[1], bins[2]), 'X_mass', 'Y_mass', 'weight__nominal'))
    outFile = ROOT.TFile.Open('{}_{}_{}_MXvsMYstudies.root'.format(self.setname,self.year,self.ijob),'RECREATE')
    outFile.cd()
    studiesPlots.Do('Write')
    #self.a.PrintNodeTree('NodeTree.pdf',verbose=True)
    outFile.Close()

if __name__ == "__main__":
    parser = ArgumentParser()
    parser.add_argument('-s', type=str, dest='setname',
        action='store',help='name of data set to run on')
    parser.add_argument('-y', type=str, dest='year',
        action='store', help='year',required=False)
    parser.add_argument('-j', type=int, dest='ijob',required=False,
        action='store', help='current job')
    parser.add_argument('-n', type=int, dest='njobs',required=False,
        action='store', help='number of jobs')
    args = parser.parse_args()

    setname=args.setname
    year=args.year
    ijob=args.ijob
    njobs=args.njobs

    filename='snapshots/{}_{}_snapshot.txt'.format(setname,year)
    ana = XHYbbWW(filename,ijob,njobs)

#   ana.ApplyStandardCorrections(post_snapshot=True)
    ana.Dijets()
    KinematicLepton(ana)

    MXvsMY_studies(ana)


from simplejson import dumps
from webob import Response
from pycurl import Curl

from subprocess import Popen, PIPE
from multiprocessing import Queue
from traceback import format_exc
from time import sleep
import logging
import tarfile
import os
import os.path
import urllib
import uuid
import sys
import os

from config import conf
from common import RequestHandler

class GitRepository(object):
    def __init__(self, path=None):
        self.path = path

    def _cmd(self, args, shell=False):
        try:
            os.chdir(self.path)
        except: pass
        logging.debug('cwd: %s    exec: %s' % (os.getcwd(), ' '.join(args)))
        p = Popen(args, stdout=PIPE, stderr=PIPE, shell=shell)
        ret = (p.communicate(), p.returncode)
        if ret[0][0]:
            logging.debug('\n'.join(ret[0]))
        return ret

    def _git(self, args):
        return self._cmd(['/usr/bin/git'] + args)

    def clone(self, gitpath):
        return self._git(['clone', gitpath, self.path])

    def checkout(self, ref):
        return self._git(['checkout', ref])

    def submodule_init(self):
        return self._git(['submodule', 'init'])

    def submodule_update(self):
        return self._git(['submodule', 'update'])

    def ls_remote(self, gitpath):
        output, retcode = self._git(['ls-remote', '--heads', '--tags', gitpath])
        stdout, stderr = output
        return [x.split('\t') for x in stdout.split('\n') if x]

    def show_ref(self):
        output, retcode = self._git(['show-ref', '--heads', '--tags'])
        stdout, stderr = output
        return [x.split(' ', 1) for x in stdout.split('\n') if x]

    def build(self, signkey, pbuilderrc, resultsdir):
        if 'refs/heads/upstream' in [x[1] for x in self.show_ref()]:
            cmd = ['/usr/bin/git-buildpackage', '--git-sign', '--git-cleaner="fakeroot debian/rules clean"', '--git-keyid="%s"' % signkey, '--git-builder="pdebuild --debsign-k %s --auto-debsign --configfile %s --debbuildopts "-i.git -I.git -sa" --buildresult %s' % (signkey, pbuilderrc, resultsdir)]
        else:
            cmd = ['/usr/bin/pdebuild', '--debsign-k', signkey, '--auto-debsign', '--debbuildopts', '-i.git -I.git -sa', '--configfile', pbuilderrc, '--buildresult', resultsdir]
        return self._cmd(cmd)

class PackageHandler(RequestHandler):
    def get(self, gitpath, gitrepo):
        gitpath = os.path.join(conf('buildbot.gitpath.%s' % gitpath), gitrepo)

        repo = GitRepository()
        refs = repo.ls_remote(gitpath)
        return Response(status=200, body=dumps(refs))

    def post(self, gitpath, gitrepo):
        if not 'ref' in self.request.params:
            return Response(status=400, body='Required parameter "ref" is missing. You must pass a git tag, branch, or commit ID to be built.\n')

        gitpath = os.path.join(conf('buildbot.gitpath.%s' % gitpath), gitrepo)
        ref = self.request.params['ref']
        cburl = self.request.params.get('cburl', None)
        submodules = self.request.params.get('submodules', None)

        buildid = uuid.uuid4().hex

        build_worker(gitpath, ref, buildid, cburl, submodules)
        return Response(status=200, body=buildid + '\n')

class RepoListHandler(RequestHandler):
    def get(self, gitpath):
        try:
            gitindex = conf('buildbot.gitindex.%s' % gitpath)
        except KeyError:
            return Response(status=404, body='Unknown git path')
        response = urllib.urlopen(gitindex)
        index = response.read()
        index = [x.strip('\r\n ').split(' ')[0].rsplit('.')[0] for x in index.split('\n') if x.strip('\r\n ')]
        return Response(status=200, body=dumps(index))

class TarballHandler(RequestHandler):
    def get(self, buildid):
        builddir = os.path.join(conf('buildbot.buildpath'), buildid)
        if not os.path.exists(builddir):
            return Response(status=404, body='The build ID does not exist.\n')

        tarpath = os.path.join(builddir, 'package.tar.gz')
        if not os.path.exists(tarpath):
            return Response(status=400, body='The build is not done yet.\n')
        else:
            fd = file(tarpath, 'rb')
            data = fd.read()
            fd.close()
            return Response(status=200, body=data, content_type='application/x-tar-gz')

class StatusHandler(RequestHandler):
    def get(self, buildid):
        builddir = os.path.join(conf('buildbot.buildpath'), buildid)
        if not os.path.exists(builddir):
            return Response(status=404, body='The build ID does not exist.\n')

        try:
            log = file('%s/build.log' % builddir, 'r').read()
        except:
            log = ''
        if not os.path.exists(builddir + '/package.tar.gz'):
            return Response(status=400, body='The build is not done yet.\n' + log)
        else:
            return Response(status=200, body='Build complete.\n' + log)

def buildlog(buildid, message):
    filename = os.path.join(conf('buildbot.buildpath'), '%s/build.log' % buildid)
    fd = file(filename, 'a+')
    fd.write(message + '\n')
    fd.close()
    logging.debug(message)

def build_thread(gitpath, ref, buildid, cburl=None, submodules=False):
    tmpdir = os.path.join(conf('buildbot.buildpath'), buildid)
    repo = GitRepository(tmpdir)

    output, retcode = repo.clone(gitpath)
    if retcode:
        buildlog(buildid, 'Unable to clone %s. %s\n' % (gitpath, '\n'.join(output)))
        return

    output, retcode = repo.checkout(ref)
    if retcode:
        buildlog(buildid, 'Unable to checkout %s. %s\n' % (ref, '\n'.join(output)))
        return

    if submodules:
        output, retcode = repo.submodule_init()
        buildlog(buildid, output[0])
        buildlog(buildid, output[1])
        output, retcode = repo.submodule_update()
        buildlog(buildid, output[0])
        buildlog(buildid, output[1])

    resultsdir = os.path.join(tmpdir, '.build_results')
    os.makedirs(resultsdir)
    output, retcode = repo.build(conf('buildbot.signkey'), conf('buildbot.pbuilderrc'), resultsdir)

    buildlog(buildid, output[0])
    buildlog(buildid, output[1])
    #logging.debug(output[0])
    #logging.debug(output[1])

    os.chdir(resultsdir)
    if not os.listdir(resultsdir) or retcode != 0:
        buildlog(buildid, 'Nothing in results directory. Giving up.')
        return

    tarpath = os.path.join(tmpdir, 'package.tar.gz')
    tar = tarfile.open(tarpath, 'w:gz')
    for name in os.listdir(resultsdir):
        tar.add(name)
    tar.close()

    buildlog(buildid, 'Build complete. Results in %s\n' % tarpath)
    data = file(tarpath, 'rb').read()
    buildlog(buildid, 'Built %i byte tarball' % len(data))

    if cburl:
        buildlog(buildid, 'Performing callback: %s' % cburl)
        req = Curl()
        req.setopt(req.POST, 1)
        req.setopt(req.URL, str(cburl))
        req.setopt(req.HTTPPOST, [('package', (req.FORM_FILE, str(tarpath)))])
        req.setopt(req.WRITEDATA, file('%s/build.log' % tmpdir, 'a+'))
        req.perform()
        req.close()

def build_worker(gitpath, ref, buildid, cburl, submodules):
    if os.fork() == 0:
        build_thread(gitpath, ref, buildid, cburl, submodules)