import sys
import os
import re
import logging
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QComboBox, QPushButton, QLabel, QFileDialog, QMainWindow, QMessageBox, QCheckBox
from gui import Ui_MainWindow
from function import *

project_file         = ".project"
cproject_file        = ".cproject"
recovery_file_sufix  = "_old"

HAL_project          = "STM32Cube HAL Driver"
Base_project         = "Base CMSIS Driver"
EDF_PATH_VAR         = "EDF_PATH"

device_cortex_series = {
    'STM32F0': 'M0',
    'STM32C0': 'M0+',
    'STM32L0': 'M0+',
    'STM32G0': 'M0+',
    'STM32F1': 'M3',
    'STM32F2': 'M3',
    'STM32L1': 'M3',
    'STM32F3': 'M4',
    'STM32F4': 'M4',
    'STM32G4': 'M4',
    'STM32L4': 'M4',
    'STM32F7': 'M7',
    'STM32h7': 'M7',
}

logging.basicConfig(level=logging.INFO, format='[%(asctime)s] %(levelname)s: %(message)s')

#----------------------------------------------------------------------------------------------------------------------------------------------------------------
class installer_app(Ui_MainWindow, QWidget):
    def __init__(self, window, app):
        self._window = window
        self._app = app
        super().__init__()
        self.setupUi(self._window)
        logging.info("Setup tools statting up.")

    # Add widget event handler.
        self.Btn_Browser.clicked.connect(self.onButtonBrowserClicked)
        self.Btn_Setup.clicked.connect(self.onButtonSetupClicked)
        self.Btn_Restore.clicked.connect(self.onButtonRestoreClicked)
        self.Btn_Quit.clicked.connect(self.onButtonQuitClicked)
        self.Enable_Widget(False)

    # Get EDF_PATH environment variable, exit if EDF_PATH is not define.
        self._edf_path = get_EDF_PATH()
        if self._edf_path == None:
            sys.exit()

    # Check argument.
        if len(sys.argv) > 1:
            arg_project_dir = sys.argv[1]
            if arg_project_dir:
                self.onButtonBrowserClicked(arg_project_dir)

    # Show installer application.
        self._window.show()
        sys.exit(self._app.exec_())

    # Enable/disable widget function.
    def Enable_Widget(self, en):
        self.Btn_Setup.setDisabled(not en)
        self.Btn_Restore.setDisabled(not en)
        self.Box_Optimize.setDisabled(not en)
        self.CB_Printf_Float.setDisabled(not en)
        self.CB_Scanf_Float.setDisabled(not en)

#----------------------------------------------------------------------------------------------------------------------------------------------------------------
# Quit button clickec handler.
    def onButtonQuitClicked(self):
        sys.exit()

#----------------------------------------------------------------------------------------------------------------------------------------------------------------
# Browser button clicked handler.
    def onButtonBrowserClicked(self, arg):
        # Get project directory in line edit.
        if arg:
            self._project_dir = arg
        else:
            self._project_dir = QFileDialog.getExistingDirectory(self, "Project browser", os.path.expanduser("~"), QFileDialog.ShowDirsOnly)

        if self._project_dir:
            self.LE_Project_Dir.setText(self._project_dir) # Set show directory.

            self._project_file_dir = self._project_dir + "/" + project_file
            self._cproject_file_dir = self._project_dir + "/" + cproject_file

        # Get project background.
            self._project_bgr = get_project_background(self._cproject_file_dir)
            self.Btn_Project_Bgr.setText(self._project_bgr)

        # Get project name.
            self._project_name = get_project_name(self._project_file_dir)
            if self._project_name != None:
            # Get .ioc file name.
                if self._project_bgr == HAL_project:
                    self._ioc_file_dir = self._project_dir + "/" + self._project_name + ".ioc"
            else:
                logging.error("Can't get project name.")
                make_message_box(QMessageBox.Critical, "Error", "Can't get project name.")
                return

        # Get device full name in .cproject file.
            self._device_full_name = get_file_target_name(self._cproject_file_dir)
        # Get device series.
            self._device_family_series = self._device_full_name[:7]
        # Get device cortex series.
            self._device_cortex_series = device_cortex_series[self._device_family_series]
        # Get project install state.
            if get_install_state(self._cproject_file_dir) != True:
                self.Btn_Setup.setDisabled(True)
            else:
                self.Btn_Setup.setDisabled(False)

            if self._device_full_name == None:
                self.Btn_Device_Full_Name.setText("STM32xxxxxxxxx")
                self.Btn_Device_Series.setText("Unknown")
                make_message_box(QMessageBox.Critical, "Error", "Unknown STM32 device name.")
                logging.error("Unknown device name in project.")
                self.Enable_Widget(False)
                return
            else:
                self.Btn_Device_Full_Name.setText(self._device_full_name)
                self.Btn_Device_Series.setText(self._device_full_name[:7] + f'(Cortex-{self._device_cortex_series})')
                self.Enable_Widget(True)

#----------------------------------------------------------------------------------------------------------------------------------------------------------------
# Setup button handler.
    def onButtonSetupClicked(self):
        logging.info(f"Project Information:")
        logging.info(f"\tDirectory: {self._project_dir}")
        logging.info(f"\tName:      {self._project_name}")
        logging.info(f"\tDevice:    {self._device_full_name}")
        logging.info(f"\tSeries:    {self._device_family_series}")
        logging.info(f"\Core:       {self._device_cortex_series}")

    # Create recovery file.
        copy_file(self._cproject_file_dir, self._cproject_file_dir + recovery_file_sufix, False)
        copy_file(self._project_file_dir,  self._project_file_dir  + recovery_file_sufix, False)
        if self._project_bgr == HAL_project:
            copy_file(self._ioc_file_dir,  self._ioc_file_dir + recovery_file_sufix,      False)

    # Get build option optimize.
        sel_opt = self.Box_Optimize.currentText()
        start_index = sel_opt.find("(") + 1
        end_index = sel_opt.find(")", start_index)
        self.build_optimize_level = sel_opt[start_index:end_index]
        logging.info(f"\tOptimize level: {self.build_optimize_level}")
    # Get option printf float.
        if self.CB_Printf_Float.checkState() == 0:
            self.printf_float = "false"
        else:
            self.printf_float = "true"
        logging.info(f"\tPrintf float: {self.printf_float}")
    # Get option scanf float.
        if self.CB_Scanf_Float.checkState() == 0:
            self.scanf_float = "false"
        else:
            self.scanf_float = "true"
        logging.info(f"\tScanf float: {self.scanf_float}")

# Config .cproject file.
        c_symbols_replace   = "<listOptionValue builtIn=\"false\" value=\"DEBUG\"/>\n"
        symbols_insert = (    "\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"DEBUG\"/>\n"
                                "\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"_GNU_SOURCE\"/>\n"
                                "\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"__STM32__\"/>\n"
                               f"\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"{self._device_family_series}\"/>\n"
                               f"\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"{self._device_full_name}\"/>\n"
                               f"\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"DEVICE_NAME="{self._device_full_name}"\"/>")
        symbols_insert_HAL = ("\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"USE_HAL_DRIVER\"/>")

        source_folder_replace = "<sourceEntries>"
        source_folder_insert = ("\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH|RESOLVED\" kind=\"sourcePath\" name=\"edf_core\"/>\n"
                                "\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH|RESOLVED\" kind=\"sourcePath\" name=\"edf_rtos\"/>\n"
                                "\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH|RESOLVED\" kind=\"sourcePath\" name=\"edf_middlewares\"/>\n"
                                "\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH|RESOLVED\" kind=\"sourcePath\" name=\"main\"/>")

        c_include_path_replace   = "name=\"Include paths (-I)\" superClass=\"com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.includepaths\" useByScannerDiscovery=\"false\" valueType=\"includePath\">"
        cpp_include_path_replace = "name=\"Include paths (-I)\" superClass=\"com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.includepaths\" useByScannerDiscovery=\"false\" valueType=\"includePath\">"
        include_path_insert = ( "\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"../buildconfig\"/>\n"
                               f"\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\""${{{EDF_PATH_VAR}}}/components/core/include"\"/>\n"
                               f"\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\""${{{EDF_PATH_VAR}}}/components/freertos/os_c{self._device_cortex_series.lower()}"\"/>\n")

        c_optimize_level_replace   =  'name="Optimization level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level" useByScannerDiscovery="false"/>'
        cpp_optimize_level_replace =  'name="Optimization level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.optimization.level" useByScannerDiscovery="false"/>'
        c_optimize_level_pattern   = r'name="Optimization level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level" useByScannerDiscovery="false" value="com\.st\.stm32cube\.ide\.mcu\.gnu\.managedbuild\.tool\.c\.compiler\.option\.optimization\.level\.value\..*?\" valueType="enumerated"/>'
        cpp_optimize_level_pattern = r'name="Optimization level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.optimization.level" useByScannerDiscovery="false" value="com\.st\.stm32cube\.ide\.mcu\.gnu\.managedbuild\.tool\.cpp\.compiler\.option\.optimization\.level\.value\..*?\" valueType="enumerated"/>'
        c_optimize_level_insert    = f'name="Optimization level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level.value.{self.build_optimize_level}\" valueType="enumerated"/>'
        cpp_optimize_level_insert  = f'name="Optimization level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.optimization.level" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.optimization.level.value.{self.build_optimize_level}\" valueType="enumerated"/>'

        printf_float_pattern = r'<option id="com\.st\.stm32cube\.ide\.mcu\.gnu\.managedbuild\.option\.nanoprintffloat\.\d+" name="Use float with printf from newlib-nano \(-u _printf_float\)" superClass="com\.st\.stm32cube\.ide\.mcu\.gnu\.managedbuild\.option\.nanoprintffloat" useByScannerDiscovery="false" value=".+" valueType="boolean"/>'
        printf_float_replace = f'<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.nanoprintffloat.1816458521" name="Use float with printf from newlib-nano (-u _printf_float)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.nanoprintffloat" useByScannerDiscovery="false" value="{self.printf_float}" valueType="boolean"/>'

        scanf_float_pattern =  r'<option id="com\.st\.stm32cube\.ide\.mcu\.gnu\.managedbuild\.option\.nanoscanffloat\.\d+" superClass="com\.st\.stm32cube\.ide\.mcu\.gnu\.managedbuild\.option\.nanoscanffloat" value=".+" valueType="boolean"/>'
        scanf_float_replace =  f'<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.nanoscanffloat.653624109" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.nanoscanffloat" value="{self.scanf_float}" valueType="boolean"/>'

        try:
            with open(self._cproject_file_dir, 'r') as f:
                file_content = f.read()
                new_file_content = file_content
                # Xóa hết các symbols hiện có.
                # pattern = re.compile(c_symbols_pattern, re.DOTALL)
                # new_file_content = re.sub(pattern, r'\1\n\t\t\t\t\t\t\t\t\2', file_content)
                # pattern = re.compile(cpp_symbols_pattern, re.DOTALL)
                # new_file_content = re.sub(pattern, r'\1\n\t\t\t\t\t\t\t\t\2', new_file_content)
                # Insert symbols
                if self._project_bgr == HAL_project:
                    new_file_content = new_file_content.replace(c_symbols_replace, c_symbols_replace + symbols_insert + symbols_insert_HAL)
                    # new_file_content = new_file_content.replace(cpp_symbols_replace, cpp_symbols_replace + symbols_insert + symbols_insert_HAL)
                else:
                    new_file_content = new_file_content.replace(c_symbols_replace, c_symbols_replace + symbols_insert)
                    # new_file_content = new_file_content.replace(cpp_symbols_replace, cpp_symbols_replace + symbols_insert)
                # Insert c include path
                new_file_content = new_file_content.replace(c_include_path_replace, c_include_path_replace + "\n" + include_path_insert)
                # Insert cpp include path
                new_file_content = new_file_content.replace(cpp_include_path_replace, cpp_include_path_replace + "\n" + include_path_insert)
                # Insert source folder directory
                new_file_content = new_file_content.replace(source_folder_replace, source_folder_replace + "\n" + source_folder_insert)
                # Insert c optimize level
                if new_file_content.find(c_optimize_level_replace) != -1:
                    new_file_content = new_file_content.replace(c_optimize_level_replace, c_optimize_level_insert)
                else:
                    new_file_content = re.sub(c_optimize_level_pattern, c_optimize_level_insert, new_file_content, count=1)
                # Insert cpp optimize level
                if new_file_content.find(cpp_optimize_level_replace) != -1:
                    new_file_content = new_file_content.replace(cpp_optimize_level_replace, cpp_optimize_level_insert)
                else:
                    new_file_content = re.sub(cpp_optimize_level_pattern, cpp_optimize_level_insert, new_file_content, count=1)

                # Change printf float option.
                new_file_content = find_and_replace_printf_or_scanf(new_file_content, printf_float_pattern, printf_float_replace)
                # Change scanf float option.
                new_file_content = find_and_replace_printf_or_scanf(new_file_content, scanf_float_pattern, scanf_float_replace)

                with open(self._cproject_file_dir, 'w') as f:
                    f.write(new_file_content)
                logging.info(f"Config .cproject file successful")

        except FileNotFoundError:
            make_message_box(QMessageBox.Critical, "Error", f"{self._cproject_file_dir}: No such file in directory.")
            logging.error(f"{self._cproject_file_dir} -> No such file in directory.")
            return

# Config .project file.
        project_desciption_replace = "</projectDescription>"
        project_desciption_insert = ("\t<linkedResources>\n"
                                        "\t\t<link>\n"
                                        "\t\t\t<name>edf_core</name>\n"
                                        "\t\t\t<type>2</type>\n"
                                       f"\t\t\t<location>{self._edf_path}/components/core/source</location>\n"
                                        "\t\t</link>\n"
                                        "\t\t<link>\n"
                                        "\t\t\t<name>edf_rtos</name>\n"
                                        "\t\t\t<type>2</type>\n"
                                       f"\t\t\t<location>{self._edf_path}/components/freertos/os_c{self._device_cortex_series.lower()}</location>\n"
                                        "\t\t</link>\n"
                                        "\t\t<link>\n"
                                        "\t\t\t<name>edf_middlewares</name>\n"
                                        "\t\t\t<type>2</type>\n"
                                       f"\t\t\t<location>{self._edf_path}/components/middlewares</location>\n"
                                        "\t\t</link>\n"
                                        "\t</linkedResources>\n"
                                        "</projectDescription>")

        linked_source_check = "<name>edf_core</name>"

        try:
            with open(self._project_file_dir, 'r') as f:
                file_content = f.read()

            if not (linked_source_check in file_content):
                new_file_content = file_content.replace(project_desciption_replace, project_desciption_insert)
                with open(self._project_file_dir, 'w') as file:
                    file.write(new_file_content)

            logging.info(f"Config .project file successful")

        except FileNotFoundError:
            make_message_box(QMessageBox.Critical, "Error", f"{self._project_file_dir}: No such file in directory.")
            logging.error(f"{self._project_file_dir} -> No such file in directory.")
            return

# Config .ioc file.
        if self._project_bgr == HAL_project:
            with open(self._ioc_file_dir, 'r') as f:
                file_content = f.read()

            busfault_handler_replace   = "NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false"
            debugmon_handler_replace   = "NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false"
            hardfault_handler_replace  = "NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false"
            memmanage_handler_replace  = "NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false"
            nmi_handler_replace        = "NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false"
            pendsv_handler_replace     = "NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false"
            svcall_handler_replace     = "NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false"
            systick_handler_replace    = "NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false"
            usagefault_handler_replace = "NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false"

            busfault_handler_insert   = "NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false"
            debugmon_handler_insert   = "NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false"
            hardfault_handler_insert  = "NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false"
            memmanage_handler_insert  = "NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false"
            nmi_handler_insert        = "NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false"
            pendsv_handler_insert     = "NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false"
            svcall_handler_insert     = "NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false"
            systick_handler_insert    = "NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:false\:false\:false\:false"
            usagefault_handler_insert = "NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false"

            if busfault_handler_replace in file_content:
                new_file_content = file_content.replace(busfault_handler_replace, busfault_handler_insert)
            if debugmon_handler_replace in file_content:
                new_file_content = new_file_content.replace(debugmon_handler_replace, debugmon_handler_insert)
            if hardfault_handler_replace in file_content:
                new_file_content = new_file_content.replace(hardfault_handler_replace, hardfault_handler_insert)
            if memmanage_handler_replace in file_content:
                new_file_content = new_file_content.replace(memmanage_handler_replace, memmanage_handler_insert)
            if nmi_handler_replace in file_content:
                new_file_content = new_file_content.replace(nmi_handler_replace, nmi_handler_insert)
            if pendsv_handler_replace in file_content:
                new_file_content = new_file_content.replace(pendsv_handler_replace, pendsv_handler_insert)
            if svcall_handler_replace in file_content:
                new_file_content = new_file_content.replace(svcall_handler_replace, svcall_handler_insert)
            if systick_handler_replace in file_content:
                new_file_content = new_file_content.replace(systick_handler_replace, systick_handler_insert)
            if usagefault_handler_replace in file_content:
                new_file_content = new_file_content.replace(usagefault_handler_replace, usagefault_handler_insert)

            with open(self._ioc_file_dir, 'w') as f:
                f.write(new_file_content)
            logging.info(f"Config .ioc file successful")

# Add edf_main_application into file main.c.
        if self._project_bgr == HAL_project:
            main_file_path = os.path.join(self._project_dir, "Core/Src/main.c")
            try:
                with open(main_file_path, 'r') as f:
                    file_content = f.read()

                # Lấy các hàm init của STM32 HAL Driver.
                pattern = re.compile(r'/\*\s*Initialize all configured peripherals\s*\*/\n\s*(.*?)\n\s*/\*\s*USER CODE BEGIN 2\s*\*/', re.DOTALL)
                match = pattern.search(file_content)
                if match:
                    HAL_init_func = match.group(1)
                    if file_content.find("/* USER CODE BEGIN 0 */") != -1:
                        new_file_content = file_content.replace("/* USER CODE BEGIN 0 */",
                                                                "/* USER CODE BEGIN 0 */\n"
                                                                "void HAL_driver_init(void){\n"
                                                               f"\t{HAL_init_func}"
                                                                "\n}"
                                                                )
                if file_content.find("main_application") == -1:
                    if file_content.find("/* USER CODE BEGIN 1 */") != -1:
                        new_file_content = new_file_content.replace("/* USER CODE BEGIN 1 */",
                                                                "/* USER CODE BEGIN 1 */\n"
                                                                "\textern int edf_main_application(void);\n"
                                                                "\treturn edf_main_application();"
                                                                )

                with open(main_file_path, 'w') as file:
                    file.write(new_file_content)

            # Hien message box neu khong mo duoc file.
            except FileNotFoundError:
                make_message_box(QMessageBox.Critical, "Error", "main.c: No such file in directory.")
                logging.error(f"/Core/main.c -> No such file in directory.")
                return

# Remove exception_interrupt_handler from file stm32fxxx_it.c.
        if self._project_bgr == HAL_project:
            it_file = "Core/Src/" + self._device_family_series.lower() + "xx_it.c"
            it_file_path = os.path.join(self._project_dir, it_file)

            start_marker = ("/**\n"
                            "  * @brief This function handles Non maskable interrupt.\n"
                            "  */\n"
                            "void NMI_Handler(void)")
            end_marker = "/* USER CODE END SysTick_IRQn 1 */\n}"

            try:
                with open(it_file_path, "r") as input_file:
                    content = input_file.read()

                start_index = content.find(start_marker)
                end_index = content.find(end_marker, start_index)

                if start_index != -1 and end_index != -1:
                    output_content = content[:start_index] + content[end_index + len(end_marker):]

                    with open(it_file_path, "w") as output_file:
                        output_file.write(output_content)
                else:
                    logging.error(f"{it_file_path}: Error during edit file.")

            except FileNotFoundError:
                make_message_box(QMessageBox.Critical, "Error", f"{it_file_path}: No such file in directory.")
                logging.error(f"{it_file_path}: No such file in directory.")
                return

# Create folder main.
        try:
            os.system(f"mkdir {self._project_dir}/main")
            os.system(f"cp {self._edf_path}/components/templates/source/app_main.cpp {self._project_dir}/main/")
        # Create folder config.
            os.system(f"mkdir {self._project_dir}/buildconfig")
            os.system(f"cp {self._edf_path}/components/templates/header/* {self._project_dir}/buildconfig")
            os.system(f"cp {self._edf_path}/components/templates/kconfig/* {self._project_dir}/buildconfig")
        except Exception as e:
            logging.error(f"Error creating folder: {e}")

        # Get project state.
        try:
            with open(self._cproject_file_dir, 'r') as f:
                file_content = f.read()
            if file_content.find("STM_EDF_VERSION") != -1:
                self.Btn_Setup.setDisabled(True)
            else:
                self.Btn_Setup.setDisabled(False)

        except FileNotFoundError:
            make_message_box(QMessageBox.Critical, "Error", ".cproject: No such file in directory.")
            logging.error(f"{self._cproject_file_dir} -> No such file in directory.")
            return

        make_message_box(QMessageBox.Information, "Progress", "Setup successful.")
        logging.info("Setup successful.")
        os.system(f"{self._edf_path}/tools/kconfig/dist/kconfig {self._project_dir}")

#----------------------------------------------------------------------------------------------------------------------------------------------------------------
# Restore button handler.
    def onButtonRestoreClicked(self):
        logging.info(f"Uninstall STM32 RTOSSDK form {self._project_dir}")

# Trả về cấu hình ban đầu cho .cproject và .project.
        if (not copy_file(self._cproject_file_dir + recovery_file_sufix, self._cproject_file_dir, True)) or \
            not copy_file(self._project_file_dir + recovery_file_sufix, self._project_file_dir, True) or \
            not copy_file(self._ioc_file_dir + recovery_file_sufix, self._ioc_file_dir, True) :
            make_message_box(QMessageBox.Critical, "Error", "Can't Restore from project.")
            logging.error("Can't uninstall from project.")

# Remove edf function main.c and stm32xxxxx_it.c
        if self._project_bgr == HAL_project:
    # main.c
            main_file_path = os.path.join(self._project_dir, "Core/Src/main.c")
            try:
                with open(main_file_path, 'r') as f:
                    file_content = f.read()

                    pattern = re.compile(r'\/\*\s*USER CODE BEGIN 0\s*\*\/\n.*?\n\s*\/\*\s*USER CODE END 0\s*\*\/', re.DOTALL)
                    main_c_replace = '/* USER CODE BEGIN 0 */\n\n/* USER CODE END 0 */'
                    new_file_content = re.sub(pattern, main_c_replace, file_content)

                    pattern = re.compile(r'\/\*\s*USER CODE BEGIN 1\s*\*\/\n.*?\n\s*\/\*\s*USER CODE END 1\s*\*\/', re.DOTALL)
                    main_c_replace = '/* USER CODE BEGIN 1 */\n\n  /* USER CODE END 1 */'
                    new_file_content = re.sub(pattern, main_c_replace, new_file_content)

                with open(main_file_path, 'w') as file:
                    file.write(new_file_content)

            # Hien message box neu khong mo duoc file.
            except FileNotFoundError:
                make_message_box(QMessageBox.Critical, "Error", "main.c: No such file in directory.")
                logging.error("main.c: No such file in directory.")
                return

        # Get project state.
        try:
            with open(self._cproject_file_dir, 'r') as f:
                file_content = f.read()
            if file_content.find("STM_EDF_VERSION") != -1:
                self.Btn_Setup.setDisabled(True)
            else:
                self.Btn_Setup.setDisabled(False)

        except FileNotFoundError:
            make_message_box(QMessageBox.Critical, "Error", ".cproject: No such file in directory.")

        make_message_box(QMessageBox.Information, "Progress", "Restore successful.")
        logging.info("Uninstall successful.")

#----------------------------------------------------------------------------------------------------------------------------------------------------------------
if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = QMainWindow()
    inst_gui = installer_app(window, app)

	# extern int main_application(void);
	# return main_application();

	# <linkedResources>
	# 	<link>
	# 		<name>rtossdk</name>
	# 		<type>2</type>
	# 		<location>/home/anh/Projects/CODE/STM32/RTOSSDK/rtossdk</location>
	# 	</link>
	# </linkedResources>

#         if self.projectbgr == HAL_project:
#             it_file = "Core/Src/" + self.device_series.lower() + "xx_it.c";
#             it_file_path = os.path.join(self.projectdir, it_file)
#             try:
#                 with open(it_file_path, 'r') as f:
#                     file_content = f.read()

#             # Include libary and declare variable
#                 if file_content.find("/* USER CODE BEGIN Includes */") != -1:
#                     new_file_content = file_content.replace("/* USER CODE BEGIN Includes */",
#                                                             "/* USER CODE BEGIN Includes */\n"
#                                                             "#include \"freertos_port/app_port/freertos_port.h\""
#                                                             )
#                 if file_content.find("/* USER CODE BEGIN EV */") != -1:
#                     new_file_content = new_file_content.replace("/* USER CODE BEGIN EV */",
#                                                             "/* USER CODE BEGIN EV */\n"
#                                                             "extern void exception_interrupt_handler(const char *tag, char *message);\n"
#                                                             "static const char *Excep_TAG = \"EXCEPTION\";"
#                                                             )
#             # Fault notify.
#                 if file_content.find("/* USER CODE BEGIN HardFault_IRQn 0 */") != -1:
#                     new_file_content = new_file_content.replace("/* USER CODE BEGIN HardFault_IRQn 0 */",
#                                                             "/* USER CODE BEGIN HardFault_IRQn 0 */\n"
#                                                             "\texception_interrupt_handler(Excep_TAG, (char *)\"Hard fault exception was unhandled(call HardFault_Handler)...\");"
#                                                             )
#                 if file_content.find("/* USER CODE BEGIN MemoryManagement_IRQn 0 */") != -1:
#                     new_file_content = new_file_content.replace("/* USER CODE BEGIN MemoryManagement_IRQn 0 */",
#                                                             "/* USER CODE BEGIN MemoryManagement_IRQn 0 */\n"
#                                                             "\texception_interrupt_handler(Excep_TAG, (char *)\"Memory management interrupt was unhandled(call MemManage_Handler)...\");"
#                                                             )
#                 if file_content.find("/* USER CODE BEGIN BusFault_IRQn 0 */") != -1:
#                     new_file_content = new_file_content.replace("/* USER CODE BEGIN BusFault_IRQn 0 */",
#                                                             "/* USER CODE BEGIN BusFault_IRQn 0 */\n"
#                                                             "\texception_interrupt_handler(Excep_TAG, (char *)\"Bus fault exception was unhandled(call BusFault_Handler)...\");"
#                                                             )
#                 if file_content.find("/* USER CODE BEGIN UsageFault_IRQn 0 */") != -1:
#                     new_file_content = new_file_content.replace("/* USER CODE BEGIN UsageFault_IRQn 0 */",
#                                                             "/* USER CODE BEGIN UsageFault_IRQn 0 */\n"
#                                                             "\texception_interrupt_handler(Excep_TAG, (char *)\"Usage fault exception was unhandled(call UsageFault_Handler)...\");"
#                                                             )
#             # Port freertos handler.
#                 if file_content.find("/* USER CODE BEGIN SVCall_IRQn 0 */") != -1:
#                     new_file_content = new_file_content.replace("/* USER CODE BEGIN SVCall_IRQn 0 */",
#                                                             "/* USER CODE BEGIN SVCall_IRQn 0 */\n"
#                                                             "\tfreertos_svc_handler();"
#                                                             )
#                 if file_content.find("/* USER CODE BEGIN PendSV_IRQn 0 */") != -1:
#                     new_file_content = new_file_content.replace("/* USER CODE BEGIN PendSV_IRQn 0 */",
#                                                             "/* USER CODE BEGIN PendSV_IRQn 0 */\n"
#                                                             "\tfreertos_pendsv_handler();"
#                                                             )
#                 if file_content.find("/* USER CODE BEGIN SysTick_IRQn 0 */") != -1:
#                     new_file_content = new_file_content.replace("/* USER CODE BEGIN SysTick_IRQn 0 */",
#                                                             "/* USER CODE BEGIN SysTick_IRQn 0 */\n"
#                                                             "\textern void systick_app_systick_process(void);\n"
#                                                             "\tsystick_app_systick_process();\n"
#                                                             "\tfreertos_tick_handler();"
#                                                             )

#                 with open(it_file_path, 'w') as file:
#                     file.write(new_file_content)

#             # Hien message box neu khong mo duoc file.
#             except FileNotFoundError:
#                 make_message_box(QMessageBox.Critical, "Error", f"{it_file}: No such file in directory.")
#                 return

    # # stm32xxxxx_it.c
    #         it_file = "Core/Src/" + self.device_series.lower() + "xx_it.c";
    #         it_file_path = os.path.join(self.projectdir, it_file)
    #         try:
    #             with open(it_file_path, 'r') as f:
    #                 file_content = f.read()

    #                 pattern = re.compile(r'\/\*\s*USER CODE BEGIN EV\s*\*\/\n.*?\n\s*\/\*\s*USER CODE END EV\s*\*\/', re.DOTALL)
    #                 main_c_replace = '/* USER CODE BEGIN EV */\n\n  /* USER CODE END EV */'
    #                 new_file_content = re.sub(pattern, main_c_replace, file_content)

    #                 pattern = re.compile(r'\/\*\s*USER CODE BEGIN HardFault_IRQn 0\s*\*\/\n.*?\n\s*\/\*\s*USER CODE END HardFault_IRQn 0\s*\*\/', re.DOTALL)
    #                 main_c_replace = '/* USER CODE BEGIN HardFault_IRQn 0 */\n\n  /* USER CODE END HardFault_IRQn 0 */'
    #                 new_file_content = re.sub(pattern, main_c_replace, new_file_content)

    #                 pattern = re.compile(r'\/\*\s*USER CODE BEGIN MemoryManagement_IRQn 0\s*\*\/\n.*?\n\s*\/\*\s*USER CODE END MemoryManagement_IRQn 0\s*\*\/', re.DOTALL)
    #                 main_c_replace = '/* USER CODE BEGIN MemoryManagement_IRQn 0 */\n\n  /* USER CODE END MemoryManagement_IRQn 0 */'
    #                 new_file_content = re.sub(pattern, main_c_replace, new_file_content)

    #                 pattern = re.compile(r'\/\*\s*USER CODE BEGIN BusFault_IRQn 0\s*\*\/\n.*?\n\s*\/\*\s*USER CODE END BusFault_IRQn 0\s*\*\/', re.DOTALL)
    #                 main_c_replace = '/* USER CODE BEGIN BusFault_IRQn 0 */\n\n  /* USER CODE END BusFault_IRQn 0 */'
    #                 new_file_content = re.sub(pattern, main_c_replace, new_file_content)

    #                 pattern = re.compile(r'\/\*\s*USER CODE BEGIN UsageFault_IRQn 0\s*\*\/\n.*?\n\s*\/\*\s*USER CODE END UsageFault_IRQn 0\s*\*\/', re.DOTALL)
    #                 main_c_replace = '/* USER CODE BEGIN UsageFault_IRQn 0 */\n\n  /* USER CODE END UsageFault_IRQn 0 */'
    #                 new_file_content = re.sub(pattern, main_c_replace, new_file_content)

    #                 pattern = re.compile(r'\/\*\s*USER CODE BEGIN SysTick_IRQn 0\s*\*\/\n.*?\n\s*\/\*\s*USER CODE END SysTick_IRQn 0\s*\*\/', re.DOTALL)
    #                 main_c_replace = '/* USER CODE BEGIN SysTick_IRQn 0 */\n\n  /* USER CODE END SysTick_IRQn 0 */'
    #                 new_file_content = re.sub(pattern, main_c_replace, new_file_content)

    #             with open(it_file_path, 'w') as file:
    #                 file.write(new_file_content)

    #         # Hien message box neu khong mo duoc file.
    #         except FileNotFoundError:
    #             make_message_box(QMessageBox.Critical, "Error", "main.c: No such file in directory.")
    #             return


t = int(input())
for _ in range(t):
  lst = input().split(" ")
  total = int(lst[0])
  diff = 0
  for i in range(1, len(lst)-1):
    add = int(lst[i])
    diff += max(add-total*2, 0)
    total = add
  print(diff)


from .gaussian_attention import gaussian_mask, gaussian_attention
from keras.layers import Layer

class VisualAttentionLayer(Layer):
    def __init__(self, output_dim, transpose=False, **kwargs):
        if len(output_dim) != 2:
            raise ValueError("`output_dim` has to be a 2D tensor [Height, Width].")
        self._output_dim = output_dim
        super(VisualAttentionLayer, self).__init__(**kwargs)

    def build(self, input_shape):
        super(VisualAttentionLayer, self).build(input_shape)

    def call(self, x):
        if len(x) != 2:
            raise ValueError("Input of the layer has to consist of 2 different inputs: the images and the parameters.")
        img_tensor, transform_params = x

        return gaussian_attention(img_tensor, transform_params, self._output_dim)

    def compute_output_shape(self, input_shape):
        if len(input_shape) == 2 and len(input_shape[0]) == 4:
            return (None, *self._output_dim, input_shape[0][-1])
        else:
            raise ValueError("The `input_shape` is not correct.")


from django.db import models

class Task(models.Model):
    username = models.CharField(verbose_name='Имя сотрудника', max_length=30)
    task_name = models.CharField(verbose_name='Текст задачи', max_length=100)
    per_day = models.PositiveIntegerField(
        default=1,
        verbose_name='Количество напоминаний за 1 день'
    )

    def time_dates(self):
        quantity = 24 / self.per_day
        time_list = [0, ]  # [0, 6, 12, 18]
        for num in range(self.per_day - 1):
            new_time = time_list[num] + quantity
            time_list.append(new_time)
        return time_list


from django.test import TestCase
from django.urls import reverse
from . import utils

class TestView(TestCase):
    """
    Test that access to views that accept get do not raise exception.
    """
    def setUp(self) -> None:
        self.views = [
            {"name": 'index', 'requires_authentication': False},
            {"name": 'about', 'requires_authentication': False},
        ]
        self.configuration = utils.createConfiguration()
        return super().setUp()

    def test_access_to_views(self):
        for view in self.views:
            view_name = view['name']
            response = self.client.get(reverse(f'core:{view_name}'))
            if view['requires_authentication']:
                self.assertEqual(response.status_code, 302, f"Access to core:{view_name} raised unexpected status code")
            else:
                self.assertEqual(response.status_code, 200, f"Access to core:{view_name} raised unexpected status code")


import pygame
import random

from Farm import Farm
from Lab import Lab
from Armor import Armor
from PowerPlant import PowerPlant
from Battery import Battery
from Engine import Engine
from Command_module import Comand_Module
from Warehouse import Warehouse
from Laser import Laser
from Biome import Biome
from Asteroid import Asteroid
from Container import Container

class Ship():
    def __init__(self, screen):
        self.x = 150
        self.y = 75
        self.distance = 0
        self.aim_distance = 1000000
        self.velocity = 10
        self.under_control = True
        self.map = [['n' for _ in range(30)] for _ in range(14)]
        self.resourses = {'Fe': 100, 'Cu': 50, 'O2': 50, 'CO2': 50, 'Al': 50, 'Si': 50, 'U': 50, 'H2O': 50,
                          'food': 50, 'energy': 0, 'science': 0}
        self.every_single_unit = {'energy': [], 'commands': [], 'food': [], 'storages': [], 'engines': [],
                                  'science': [], 'defense': [], 'cabins': [],
                                  'armor': []}
        self.storages = {'energy': [], 'science': [], 'storages': []}
        self.group = pygame.sprite.Group()
        self.cannons = []
        self.comand_modules = []
        self.humans = 10
        self.cell_size = 30
        self.screen = screen
        eng = Engine(self, 14, 7)
        eng1 = Engine(self, 14, 9)
        plant1 = PowerPlant(self, 18, 7)
        plant2 = PowerPlant(self, 18, 9)
        self.comand_module = Comand_Module(self, 16, 11)
        bat1 = Battery(self, 20, 7)
        bat2 = Battery(self, 20, 9)
        biome1 = Biome(self, 22, 7)
        biome2 = Biome(self, 22, 9)
        lab1 = Lab(self, 17, 6)
        farm = Farm(self, 24, 7)
        ware = Warehouse(self, 20, 6)
        ware.charges = {'Fe': 10000, 'Cu': 10000, 'O2': 10000, 'CO2': 10000, 'Al': 10000, 'Si': 10000, 'U': 10000,
                        'H2O': 10000, 'food': 10000}
        arm = Armor(self, 23, 6)
        arm = Armor(self, 23, 7)
        arm = Armor(self, 23, 8)
        laser1 = Laser(self, 3, 1)
        laser2 = Laser(self, 8, 12)
        for i in self.every_single_unit.keys():
            for a in self.every_single_unit[i]:
                self.group.add(a)
        for i in self.storages.keys():
            for unit in self.storages[i]:
                unit.input()
        self.new_group = pygame.sprite.Group()
        self.new_group.add(self.comand_module)
        self.storages_types = [Battery, Lab]

    def destroy(self, unit):
        self.group.remove(unit)
        self.every_single_unit[unit.cat].remove(unit)
        if type(unit) in self.storages_types:
            self.storages[unit.cat].remove(unit)
        unit.working = False

    def dfs(self, sprite, visited):
        visited.append(sprite)
        for i in pygame.sprite.spritecollide(sprite, self.group, False):
            if i not in visited:
                self.new_group.add(i)
                self.dfs(i, visited)

    def blt(self):
        self.surf = pygame.Surface((self.cell_size * len(self.map[0]), self.cell_size * len(self.map)), pygame.SRCALPHA)
        for i in self.every_single_unit.keys():
            for unit in self.every_single_unit[i]:
                unit.new_image()
        self.group.draw(self.screen)

    def all_systems_check(self):
        for i in self.group.sprites():
            if i.health <= 0:
                self.destroy(i)
        self.dfs(self.comand_module, [])
        for unit in self.group:
            if unit not in self.new_group.sprites():
                self.destroy(unit)
        self.new_group = pygame.sprite.Group()
        self.new_group.add(self.comand_module)
        self.resourses = {'Fe': 0, 'Cu': 0, 'O2': 0, 'CO2': 0, 'Al': 0, 'Si': 0, 'U': 0, 'H2O': 0,
                          'food': 0, 'energy': 0, 'science': 0}
        self.humans = 0
        for i in self.every_single_unit['cabins']:
            i.output()
        for i in self.storages.keys():
            for unit in self.storages[i]:
                unit.output()
        self.under_control = False
        for i in self.comand_modules:
            if i.working:
                self.under_control = True
        for cat in self.every_single_unit.keys():
            for unit in self.every_single_unit[cat]:
                unit.do()
        for i in self.storages.keys():
            for unit in self.storages[i]:
                unit.input()
        for i in self.every_single_unit['cabins']:
            i.input()

    def change(self, x, y):
        for unit in self.group.sprites():
            if unit.rect.collidepoint(x, y):
                if unit.working:
                    unit.working = False
                else:
                    unit.working = True

    def move(self, nx, ox, ny, oy):
        self.x = nx
        self.y = ny
        for cat in self.every_single_unit.keys():
            for unit in self.every_single_unit[cat]:
                unit.rect.move_ip(nx - ox, ny - oy)

    def shoot(self, event_group):
        for cannon in self.cannons:
            if pygame.sprite.spritecollideany(cannon, event_group, pygame.sprite.collide_circle_ratio(3.5)) != None:
                for i in [pygame.sprite.spritecollideany(cannon, event_group, pygame.sprite.collide_circle_ratio(3.5))]:
                    if type(i) == Asteroid:
                        cannon.shoot(i)
                    elif type(i) == Container:
                        cannon.grab(i)
                        for i in self.resourses.keys():
                            self.resourses[i] += random.randint(100, 100)


from matplotlib import pyplot as plt
font = {'family':'sans-serif', 'sans-serif':'Arial'}
plt.rc('font', **font)

plt.title('', fontsize='x-large', pad=None)
plt.xlabel('', fontsize='x-large')
plt.ylabel('', fontsize='x-large')
# plt.xscale('log')
plt.tick_params(axis="both",direction="in", labelsize='x-large')
plt.subplots_adjust(left=0.30, bottom=0.30, right=0.70, top=0.70, wspace=0.20, hspace=0.20)
plt.legend(fontsize='large').set_draggable(True)
plt.grid(alpha=0.5)


import os

import pytest

from dvclive.data.scalar import Scalar
from dvclive.keras import DvcLiveCallback
from tests.test_main import read_logs

# pylint: disable=unused-argument, no-name-in-module, redefined-outer-name

@pytest.fixture
def xor_model():
    import numpy as np
    from tensorflow.python.keras import Sequential
    from tensorflow.python.keras.layers import Activation, Dense

    def make():
        x = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
        y = np.array([[0], [1], [1], [0]])

        model = Sequential()
        model.add(Dense(8, input_dim=2))
        model.add(Activation("relu"))
        model.add(Dense(1))
        model.add(Activation("sigmoid"))

        model.compile(
            loss="binary_crossentropy", optimizer="sgd", metrics=["accuracy"]
        )

        return model, x, y

    yield make

def test_keras_callback(tmp_dir, xor_model, capture_wrap):
    model, x, y = xor_model()

    model.fit(
        x,
        y,
        epochs=1,
        batch_size=1,
        validation_split=0.2,
        callbacks=[DvcLiveCallback()],
    )

    assert os.path.exists("dvclive")
    logs, _ = read_logs(tmp_dir / "dvclive" / Scalar.subfolder)

    assert os.path.join("train", "accuracy") in logs
    assert os.path.join("eval", "accuracy") in logs

@pytest.mark.parametrize("save_weights_only", (True, False))
def test_keras_model_file(
    tmp_dir, xor_model, mocker, save_weights_only, capture_wrap
):
    model, x, y = xor_model()
    save = mocker.spy(model, "save")
    save_weights = mocker.spy(model, "save_weights")

    model.fit(
        x,
        y,
        epochs=1,
        batch_size=1,
        callbacks=[
            DvcLiveCallback(
                model_file="model.h5", save_weights_only=save_weights_only
            )
        ],
    )
    assert save.call_count != save_weights_only
    assert save_weights.call_count == save_weights_only

@pytest.mark.parametrize("save_weights_only", (True, False))
def test_keras_load_model_on_resume(
    tmp_dir, xor_model, mocker, save_weights_only, capture_wrap
):
    import dvclive.keras

    model, x, y = xor_model()

    if save_weights_only:
        model.save_weights("model.h5")
    else:
        model.save("model.h5")

    load_weights = mocker.spy(model, "load_weights")
    load_model = mocker.spy(dvclive.keras, "load_model")

    model.fit(
        x,
        y,
        epochs=1,
        batch_size=1,
        callbacks=[
            DvcLiveCallback(
                model_file="model.h5",
                save_weights_only=save_weights_only,
                resume=True,
            )
        ],
    )

    assert load_model.call_count != save_weights_only
    assert load_weights.call_count == save_weights_only

def test_keras_no_resume_skip_load(tmp_dir, xor_model, mocker, capture_wrap):
    model, x, y = xor_model()

    model.save_weights("model.h5")

    load_weights = mocker.spy(model, "load_weights")

    model.fit(
        x,
        y,
        epochs=1,
        batch_size=1,
        callbacks=[
            DvcLiveCallback(
                model_file="model.h5",
                save_weights_only=True,
                resume=False,
            )
        ],
    )

    assert load_weights.call_count == 0

def test_keras_no_existing_model_file_skip_load(
    tmp_dir, xor_model, mocker, capture_wrap
):
    model, x, y = xor_model()

    load_weights = mocker.spy(model, "load_weights")

    model.fit(
        x,
        y,
        epochs=1,
        batch_size=1,
        callbacks=[
            DvcLiveCallback(
                model_file="model.h5",
                save_weights_only=True,
                resume=True,
            )
        ],
    )

    assert load_weights.call_count == 0

def test_keras_None_model_file_skip_load(
    tmp_dir, xor_model, mocker, capture_wrap
):
    model, x, y = xor_model()

    model.save_weights("model.h5")

    load_weights = mocker.spy(model, "load_weights")

    model.fit(
        x,
        y,
        epochs=1,
        batch_size=1,
        callbacks=[
            DvcLiveCallback(
                save_weights_only=True,
                resume=True,
            )
        ],
    )

    assert load_weights.call_count == 0


import sys
sys.stdin = open('input.txt')

def cook(i, n, group1, group2):
    global selection, result
    # 조합 결성시 return
    if len(group1) == n//2 and len(group2) == n//2:
        ans1 = 0
        ans2 = 0
        for i in range(n//2):
            for j in range(i, n//2):
                ans1 += data[group1[i]][group1[j]] + data[group1[j]][group1[i]]
                ans2 += data[group2[i]][group2[j]]+ data[group2[j]][group2[i]]
        result = min(result, abs(ans1-ans2))
        return

    # 조합 만들기
    # 애초에 group1과 group2를 나눠서 두가지로 만든다.
    if len(group1) < n//2 and len(group2) < n//2:
        cook(i+1, n, group1+[i], group2)
        cook(i+1, n, group1, group2+[i])

    elif len(group1) < n//2:
        cook(i + 1, n, group1 + [i], group2)

    else:
        cook(i + 1, n, group1, group2 + [i])

T = int(input())

for tc in range(1, T+1):
    N = int(input())
    data = [list(map(int, input().split())) for _ in range(N)]
    selection = [False]*N
    result = 20000 * N**2
    cook(0, N, [], [])

    print(f'#{tc}', result)


from datetime import datetime

import six
from oslo_config import cfg
from oslo_log import log
from oslo_utils import uuidutils, importutils

from delfin import db
from delfin.common.constants import TelemetryCollection, TelemetryJobStatus
from delfin.exception import TaskNotFound
from delfin.i18n import _
from delfin.task_manager import rpcapi as task_rpcapi
from delfin.task_manager.scheduler import schedule_manager
from delfin.task_manager.tasks.telemetry import PerformanceCollectionTask

CONF = cfg.CONF
LOG = log.getLogger(__name__)

class JobHandler(object):
    def __init__(self, ctx, task_id, storage_id, args, interval):
        # create an object of periodic task scheduler
        self.ctx = ctx
        self.task_id = task_id
        self.storage_id = storage_id
        self.args = args
        self.interval = interval
        self.task_rpcapi = task_rpcapi.TaskAPI()
        self.scheduler = schedule_manager.SchedulerManager().get_scheduler()
        self.stopped = False
        self.job_ids = set()

    @staticmethod
    def get_instance(ctx, task_id):
        task = db.task_get(ctx, task_id)
        return JobHandler(ctx, task_id, task['storage_id'],
                          task['args'], task['interval'])

    def perform_history_collection(self, start_time, end_time, last_run_time):
        # Trigger one historic collection to make sure we do not
        # miss any Data points due to reschedule
        LOG.debug('Triggering one historic collection for task %s',
                  self.task_id)
        try:
            telemetry = PerformanceCollectionTask()
            ret = telemetry.collect(self.ctx, self.storage_id, self.args,
                                    start_time, end_time)
            LOG.debug('Historic collection performed for task %s with '
                      'result %s' % (self.task_id, ret))
            db.task_update(self.ctx, self.task_id,
                           {'last_run_time': last_run_time})
        except Exception as e:
            msg = _("Failed to collect performance metrics during history "
                    "collection for storage id:{0}, reason:{1}"
                    .format(self.storage_id, six.text_type(e)))
            LOG.error(msg)

    def schedule_job(self, task_id):

        if self.stopped:
            # If Job is stopped return immediately
            return

        LOG.info("JobHandler received A job %s to schedule" % task_id)
        job = db.task_get(self.ctx, task_id)
        # Check delete status of the task
        deleted = job['deleted']
        if deleted:
            return
        collection_class = importutils.import_class(
            job['method'])
        instance = collection_class.get_instance(self.ctx, self.task_id)
        current_time = int(datetime.now().timestamp())
        last_run_time = current_time
        next_collection_time = last_run_time + job['interval']
        job_id = uuidutils.generate_uuid()
        next_collection_time = datetime \
            .fromtimestamp(next_collection_time) \
            .strftime('%Y-%m-%d %H:%M:%S')

        existing_job_id = job['job_id']

        scheduler_job = self.scheduler.get_job(existing_job_id)

        if not (existing_job_id and scheduler_job):
            LOG.info('JobHandler scheduling a new job')
            self.scheduler.add_job(
                instance, 'interval', seconds=job['interval'],
                next_run_time=next_collection_time, id=job_id,
                misfire_grace_time=int(job['interval'] / 2))

            update_task_dict = {'job_id': job_id}
            db.task_update(self.ctx, self.task_id, update_task_dict)
            self.job_ids.add(job_id)
            LOG.info('Periodic collection tasks scheduled for for job id: '
                     '%s ' % self.task_id)

            # Check if historic collection is needed for this task.
            # If the last run time is already set, adjust start_time based on
            # last run time or history_on_reschedule which is smaller
            # If jod id is created but last run time is not yet set, then
            # adjust start_time based on interval or history_on_reschedule
            # whichever is smaller

            end_time = current_time * 1000
            # Maximum supported history duration on restart
            history_on_reschedule = CONF.telemetry. \
                performance_history_on_reschedule
            if job['last_run_time']:
                start_time = job['last_run_time'] * 1000 \
                    if current_time - job['last_run_time'] < \
                    history_on_reschedule \
                    else (end_time - history_on_reschedule * 1000)
                self.perform_history_collection(start_time, end_time,
                                                last_run_time)
            elif existing_job_id:
                interval_in_sec = job['interval']
                start_time = (end_time - interval_in_sec * 1000) \
                    if interval_in_sec < history_on_reschedule \
                    else (end_time - history_on_reschedule * 1000)
                self.perform_history_collection(start_time, end_time,
                                                last_run_time)
        else:
            LOG.info('Job already exists with this scheduler')

    def stop(self):
        self.stopped = True
        for job_id in self.job_ids.copy():
            self.remove_scheduled_job(job_id)
        LOG.info("Stopping telemetry jobs")

    def remove_scheduled_job(self, job_id):
        if job_id in self.job_ids:
            self.job_ids.remove(job_id)
        if job_id and self.scheduler.get_job(job_id):
            self.scheduler.remove_job(job_id)

    def remove_job(self, task_id):
        try:
            LOG.info("Received job %s to remove", task_id)
            job = db.task_get(self.ctx, task_id)
            job_id = job['job_id']
            self.remove_scheduled_job(job_id)
        except Exception as e:
            LOG.error("Failed to remove periodic scheduling job , reason: %s.",
                      six.text_type(e))

class FailedJobHandler(object):
    def __init__(self, ctx):
        # create an object of periodic failed task scheduler
        self.scheduler = schedule_manager.SchedulerManager().get_scheduler()
        self.ctx = ctx
        self.stopped = False
        self.job_ids = set()

    @staticmethod
    def get_instance(ctx, failed_task_id):
        return FailedJobHandler(ctx)

    def schedule_failed_job(self, failed_task_id):

        if self.stopped:
            return

        try:
            job = db.failed_task_get(self.ctx, failed_task_id)
            retry_count = job['retry_count']
            result = job['result']
            job_id = job['job_id']
            if retry_count >= \
                    TelemetryCollection.MAX_FAILED_JOB_RETRY_COUNT or \
                    result == TelemetryJobStatus.FAILED_JOB_STATUS_SUCCESS:
                LOG.info("Exiting Failure task processing for task [%d] "
                         "with result [%s] and retry count [%d] "
                         % (job['id'], result, retry_count))
                self._teardown_task(self.ctx, job['id'], job_id)
                return
            # If job already scheduled, skip
            if job_id and self.scheduler.get_job(job_id):
                return

            try:
                db.task_get(self.ctx, job['task_id'])
            except TaskNotFound as e:
                LOG.info("Removing failed telemetry job as parent job "
                         "do not exist: %s", six.text_type(e))
                # tear down if original task is not available
                self._teardown_task(self.ctx, job['id'],
                                    job_id)
                return

            if not (job_id and self.scheduler.get_job(job_id)):
                job_id = uuidutils.generate_uuid()
                db.failed_task_update(self.ctx, job['id'],
                                      {'job_id': job_id})

                collection_class = importutils.import_class(
                    job['method'])
                instance = \
                    collection_class.get_instance(self.ctx, job['id'])
                self.scheduler.add_job(
                    instance, 'interval',
                    seconds=job['interval'],
                    next_run_time=datetime.now(), id=job_id,
                    misfire_grace_time=int(job['interval'] / 2))
                self.job_ids.add(job_id)

        except Exception as e:
            LOG.error("Failed to schedule retry tasks for performance "
                      "collection, reason: %s", six.text_type(e))
        else:
            LOG.info("Schedule collection completed")

    def _teardown_task(self, ctx, failed_task_id, job_id):
        db.failed_task_delete(ctx, failed_task_id)
        self.remove_scheduled_job(job_id)

    def remove_scheduled_job(self, job_id):
        if job_id in self.job_ids:
            self.job_ids.remove(job_id)
        if job_id and self.scheduler.get_job(job_id):
            self.scheduler.remove_job(job_id)

    def stop(self):
        self.stopped = True
        for job_id in self.job_ids.copy():
            self.remove_scheduled_job(job_id)

    def remove_failed_job(self, failed_task_id):
        try:
            LOG.info("Received failed job %s to remove", failed_task_id)
            job = db.failed_task_get(self.ctx, failed_task_id)
            job_id = job['job_id']
            self.remove_scheduled_job(job_id)
            db.failed_task_delete(self.ctx, job['id'])
            LOG.info("Removed failed_task entry  %s ", job['id'])
        except Exception as e:
            LOG.error("Failed to remove periodic scheduling job , reason: %s.",
                      six.text_type(e))

    @classmethod
    def job_interval(cls):
        return TelemetryCollection.FAILED_JOB_SCHEDULE_INTERVAL


# link : https://school.programmers.co.kr/learn/courses/30/lessons/172928
# title : 공원 산책

def solution(park, routes):
    for r_idx, i in enumerate(park):
        for c_idx, j in enumerate(i):
            if(j == "S"):
                dog = Dog(park, c_idx, r_idx)
    for inst in routes :
        arg = inst.split(" ")
        if arg[0] == "E":
            dog.Right(int(arg[1]))
        elif arg[0] == "W":
            dog.Left(int(arg[1]))
        elif arg[0] == "N":
            dog.Up(int(arg[1]))
        else :
            dog.Down(int(arg[1]))
        print(dog.getPos())
    return dog.getPos()

class Dog :
    def __init__(self, park, xpos, ypos) :
        self.park = park
        self.xpos = xpos
        self.ypos = ypos
    def Right(self, step) :
        for i in range(self.xpos+1, self.xpos+step+1) :
            if (i >= len(self.park[0])) or (self.park[self.ypos][i] == "X") :
                return
        self.xpos += step
    def Left(self, step) :
        for i in range(self.xpos-1, self.xpos-step-1, -1) :
            if (i < 0) or (self.park[self.ypos][i] == "X") :
                return
        self.xpos -= step
    def Up(self, step) :
        for i in range(self.ypos-1, self.ypos-step-1, -1) :
            if (i < 0) or (self.park[i][self.xpos] == "X") :
                return
        self.ypos -= step
    def Down(self, step) :
        # x.pos : 2, y.pos:0 0+2+1
        for i in range(self.ypos+1, self.ypos+step+1) :
            if (i >= len(self.park)) or (self.park[i][self.xpos] == "X") :
                return
        self.ypos += step
    def getPos(self) :
        return [self.ypos, self.xpos]

park = ["SOO","OXX","OOO"]
routes = ["E 2","S 2","W 1"]
print(solution(park, routes))


class Solution:
    def levelOrder(self, root):
        # ans = []
        que = []
        if root is None:
            return
        que.append(root)
        while len(que) > 0:
            data = que.pop(0)
            if data.left:
                que.append(data.left)
            if data.right:
                que.append(data.right)
            print(data.data, end=' ')
            # Solution.ans.append(data.data)
class Node:
    def __init__(self, val):
        self.right = None
        self.data = val
        self.left = None

node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
node4 = Node(4)
node5 = Node(5)
node6 = Node(6)
node7 = Node(7)
node8 = Node(8)
node9 = Node(9)
node10 = Node(10)
node11 = Node(11)
node12 = Node(12)
node13 = Node(13)
node14 = Node(14)
node15 = Node(15)

node1.right = node2
node2.right = node3
node1.left = node4
node4.left = node5
node4.right = node6
node5.left = node7
node5.right = node8
node8.left = node9
node9.left = node10
node9.right = node11
node6.right = node12
node12.left = node13
node12.right = node14
node14.right= node15

sol = Solution()
sol.levelOrder(node1)
print(sol.ans)


while(True):
    m,n = map(int,input().split())
    if not m: break
    a = list(range(1,m+1))
    b = [input() for _ in range(n)]
    t = [str(i+1) for i in range(n)]
    t[2::3]   = ["Fizz"]*len(t[2::3])
    t[4::5]   = ["Buzz"]*len(t[4::5])
    t[14::15] = ["FizzBuzz"]*len(t[14::15])
    i=0
    for j in range(n):
        if len(a) <2: break
        if b[j] != t[j]: del a[i]; i = 0 if i >= len(a) else i; continue
        i += 1
        i = i%len(a)
    print(" ".join(str(e) for e in a))


import corexyLib
import motorLib
from time import sleep
import RPi.GPIO as GPIO

SQUARE_SIDE = 57.3
resolution = 'Half'
corexy = corexyLib.CoreXY(20, resolution, motorLib.Motor(20, 21, 1, (14, 15, 18), 400, resolution), motorLib.Motor(19, 26, 1, (14, 15, 18), 400, resolution), 0, 0)
corexy.motorA.initial_set_up()
corexy.motorB.initial_set_up()
GPIO.setup(5, GPIO.OUT)

# Assume origin at the up left corner of square(1,1)
def cal_xy_coor(row, col):
    x_coor = ((row-1)+ (1/2)) * SQUARE_SIDE
    y_coor = ((col-1) + (1/2)) *SQUARE_SIDE

    return x_coor, y_coor

GPIO.output(5, GPIO.HIGH)
while(True):

    corexy.move_up(2500)
    corexy.move_down(2500)
    corexy.move_left(2500)
    corexy.move_right(2500)
    corexy.move_down(2500)
    corexy.move_up(2500)
    corexy.move_right(2500)
    corexy.move_left(2500)

GPIO.output(5, GPIO.LOW)
corexy.move_up(2500)
corexy.move_down(2500)
# corexy.move_left(5424)
# corexy.move_down(6630)

# corexy.motorA.motor_steps(5000)
# corexy.motorA.set_counter_clockwise()
# corexy.motorA.motor_steps(5000)

# while True:

#     row = int(input("Enter row: "))
#     col = int(input("Enter col: "))

#     new_x_coor, new_y_coor = cal_xy_coor(row, col)

#     corexy.move_to(new_x_coor, new_y_coor)


import sys
from typing import List, Optional, Tuple, cast
import unittest

def how_construct(target_string: str, strings: List[str]) -> Optional[List[str]]:
    n = len(target_string) + 1
    table: List[Optional[List[str]]] = [
        [] if i == 0 else None for i in range(n)]
    for i in range(n):
        if table[i] is not None:
            for string in strings:
                j = i + len(string)
                if j < n and target_string[i: j] == string:
                    table[j] = [*cast(List[str], table[i]), string]
    return table[len(target_string)]

class SolutionTest(unittest.TestCase):
    def test_solution(self):
        sys.setrecursionlimit(10000)

        fixtures = [
            (
                ("abcdef", ["ab", "abc", "cd", "def", "abcd"]),
                ["abc", "def"],
            ),
            (
                ("skateboard", ["bo", "rd", "ate", "t", "ska", "sk", "boar"]),
                None,
            ),
            (
                ("", ["cat", "dog", "mouse"]),
                [],
            ),
        ]

        for inputs, output in fixtures:
            solution = how_construct(*inputs)
            if solution:
                self.assertEqual(sorted(output), sorted(solution))
            else:
                self.assertEqual(output, solution)


import os
import pandas as pd
from natsort import natsorted
from openpyxl import load_workbook

dirName = './pozyxAPI_dane_pomiarowe'

def parse_learn_data():
    data = pd.DataFrame()
    for filename in natsorted(os.listdir(dirName)):
        if filename.endswith(".xlsx"):
            df = pd.read_excel(f"{dirName}/{filename}")
            df = df[['0/timestamp', 't', 'no', 'measurement x', 'measurement y', 'reference x', 'reference y']]
            data = data.append(df, ignore_index=True)
    df = pd.read_excel("./pozyxAPI_only_localization_dane_testowe_i_dystrybuanta.xlsx")
    df = df[['0/timestamp', 't', 'no', 'measurement x', 'measurement y', 'reference x', 'reference y']]
    data = data.append(df, ignore_index=True)
    data.to_csv("./dataset.csv")

def add_results_to_main_excel(predict_test):
    df_to_export = pd.DataFrame(predict_test)
    with pd.ExcelWriter('./tmp.xlsx') as writer:
        df_to_export.to_excel(writer, sheet_name='Results', index=False)
    export_workbook = load_workbook(filename='./tmp.xlsx')
    export_sheet = export_workbook.active
    target_workbook = load_workbook(filename='./pozyxAPI_only_localization_dane_testowe_i_dystrybuanta.xlsx')
    target_sheet = target_workbook.active
    export_values = []
    for value in export_sheet.iter_rows(min_row=2, max_col=2, values_only=True):
        export_values.append(value)
    os.remove('tmp.xlsx')
    for it in range(1, export_values.__len__()+1):
        target_sheet[f'O{it + 1}'] = export_values[it-1][0]
        target_sheet[f'P{it + 1}'] = export_values[it-1][1]
    target_workbook.save('./Results.xlsx')


"""
Ex 7.

Program description: The objective of this program is to create a function named “print date” which will print in the format (from previously created list ).
The format is Month/Day/Year.

"""

days = ["Friday", "Saturday", "Sunday", "Monday", "Tuesday", "Wensday", "Thursday"]
year = 2021
month = 1
day = 23

def next():
  if(day<31):
    day+=1
  else:
    day = 0
    month+=1
  if(month == 12):
    month = 1
    year+=1

def find_day(day, month, year):
  total = (day-1) + (month-1)*30 + (360 * (year-2021))
  return days[total%7]

def print_date():
  return find_day(day,month,year) + ", " + str(month) + "/" + str(day) + "/" + str(year)

print(print_date())


class CityPlan:
    def __init__(self, city_plan):
        self.position = city_plan["position"]
        self.criteria = city_plan["criteria"]
        self.score1 = city_plan["score1"]
        self.score2 = city_plan["score2"]

    @property
    def criteria(self):
        return self._criteria

    @property
    def position(self):
        return self._position

    @property
    def score1(self):
        return self._score1

    @property
    def score2(self):
        return self._score2

    @criteria.setter
    def criteria(self, criteria: list):
        '''
        -> list[int]
        '''
        assert type(criteria) == list or type(criteria) == str
        if type(criteria) == list and all(type(i) == int for i in criteria):
            assert criteria == sorted(criteria)
        else:
            criteria_one = [["all houses", 0], ["all houses", 2], "end houses", "7 temps", "5 bis"]
            criteria_two = ["two streets all parks", "two streets all pools", ["all pools all parks", 1], ["all pools all parks", 2], "all pools all parks one roundabout"]

            if self.position == 1:
                assert criteria in criteria_one
            elif self.position == 2:
                assert criteria in criteria_two
            else:
                raise Exception("Invalid Position")

        self._criteria = criteria

    @position.setter
    def position(self, position: int):
        '''
        -> int
        '''
        assert 1 <= position <= 3 and type(position) == int

        self._position = position

    @score1.setter
    def score1(self, score1: int):
        '''
        -> int
        '''
        assert 0 <= score1 and type(score1) == int

        self._score1 = score1

    @score2.setter
    def score2(self, score2: int):
        '''
        -> int
        '''
        assert 0 <= score2 and type(score2) == int

        self._score2 = score2


#%% Imports
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from collections import defaultdict
from helpers import   pairwiseDistCorr,nn_reg,nn_arch,reconstructionError
from matplotlib import cm
from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.random_projection import SparseRandomProjection, GaussianRandomProjection
from itertools import product
from helpers import get_data_from_csv

out = './RP/'
cmap = cm.get_cmap('Spectral')

np.random.seed(42)

# import wine quality data
wineX, wineY = get_data_from_csv("./BASE/wine_trg.csv", n_features=11, sep=',', header=None)
digitX, digitY = get_data_from_csv("./BASE/digit_trg.csv", n_features=256, sep=',', header=None)

wineX = StandardScaler().fit_transform(wineX)
digitX = StandardScaler().fit_transform(digitX)

clusters = [2,5,10,15,20,25,30,35,40]
dims = [2,5,10,15,20,25,30,35,40,45,50,55,60]
dims_wine = [i for i in range(2,12)]

# data for 1

tmp = defaultdict(dict)
for i,dim in product(range(10),dims_wine):
    rp = SparseRandomProjection(random_state=i, n_components=dim)
    tmp[dim][i] = pairwiseDistCorr(rp.fit_transform(wineX), wineX)
tmp =pd.DataFrame(tmp).T
tmp.to_csv(out+'wine scree1.csv')

tmp = defaultdict(dict)
for i,dim in product(range(10),dims):
    rp = SparseRandomProjection(random_state=i, n_components=dim)
    tmp[dim][i] = pairwiseDistCorr(rp.fit_transform(digitX), digitX)
tmp =pd.DataFrame(tmp).T
tmp.to_csv(out+'digit scree1.csv')

tmp = defaultdict(dict)
for i,dim in product(range(10),dims_wine):
    rp = SparseRandomProjection(random_state=i, n_components=dim)
    rp.fit(wineX)
    tmp[dim][i] = reconstructionError(rp, wineX)
tmp =pd.DataFrame(tmp).T
tmp.to_csv(out+'wine scree2.csv')

tmp = defaultdict(dict)
for i,dim in product(range(10),dims):
    rp = SparseRandomProjection(random_state=i, n_components=dim)
    rp.fit(digitX)
    tmp[dim][i] = reconstructionError(rp, digitX)
tmp =pd.DataFrame(tmp).T
tmp.to_csv(out+'digit scree2.csv')

# Data for 2

grid ={'rp__n_components':dims_wine,'NN__alpha':nn_reg,'NN__hidden_layer_sizes':nn_arch}
rp = SparseRandomProjection(random_state=5)
mlp = MLPClassifier(activation='relu',max_iter=2000,early_stopping=True,random_state=5)
pipe = Pipeline([('rp',rp),('NN',mlp)])
gs = GridSearchCV(pipe,grid,verbose=10,cv=5)

gs.fit(wineX,wineY)
tmp = pd.DataFrame(gs.cv_results_)
tmp.to_csv(out+'wine dim red.csv')

grid ={'rp__n_components':dims,'NN__alpha':nn_reg,'NN__hidden_layer_sizes':nn_arch}
rp = SparseRandomProjection(random_state=5)
mlp = MLPClassifier(activation='relu',max_iter=2000,early_stopping=True,random_state=5)
pipe = Pipeline([('rp',rp),('NN',mlp)])
gs = GridSearchCV(pipe,grid,verbose=10,cv=5)

gs.fit(digitX,digitY)
tmp = pd.DataFrame(gs.cv_results_)
tmp.to_csv(out+'digit dim red.csv')

# data for 3
# Set this from chart 2 and dump, use clustering script to finish up
dim = 6
rp = SparseRandomProjection(n_components=dim,random_state=5)

wineX2 = rp.fit_transform(wineX)
wine2 = pd.DataFrame(np.hstack((wineX2,np.atleast_2d(wineY))))
cols = list(range(wine2.shape[1]))
cols[-1] = 'Class'
wine2.columns = cols
wine2.to_csv(out+'wine_datasets.csv',index=False,header=False)

dim = 60
rp = SparseRandomProjection(n_components=dim,random_state=5)
digitX2 = rp.fit_transform(digitX)
digit2 = pd.DataFrame(np.hstack((digitX2,np.atleast_2d(digitY))))
cols = list(range(digit2.shape[1]))
cols[-1] = 'Class'
digit2.columns = cols
digit2.to_csv(out+'digit_datasets.csv',index=False,header=False)


import sys

N = int(input())
Nums = list(map(int, sys.stdin.readline().split()))
M = int(input())
Mums = list(map(int, sys.stdin.readline().split()))
Nums.sort()

def binary_search(answer):
    start = 0
    end = N - 1

    while start <= end:
        mid = (start + end) // 2
        if Nums[mid] == answer:
            return True
        elif Nums[mid] < answer:
            start = mid + 1
        else:
            end = mid - 1
    return False

for i in range(0, M):
    if (binary_search(Mums[i]) == True):
        print("1")
    else:
        print(0)


# Parse Data from hex data helper class.
from common.types import *

class ParseHelper:
    @staticmethod
    def getData(rawdata, format_info):
        data_type = format_info[0]
        if(data_type==DataType.NUM):
            return ParseHelper.getNumber(rawdata, format_info[1], format_info[2])
        elif(data_type==DataType.HEX):
            return ParseHelper.getHEX(rawdata, format_info[1], format_info[2])
        elif(data_type==DataType.MAC):
            return ParseHelper.getMACFormat(rawdata, format_info[1], format_info[2])
        elif(data_type==DataType.IP):
            return ParseHelper.getIPFormat(rawdata, format_info[1], format_info[2])
        elif(data_type==DataType.IPv6):
            return ParseHelper.getIPv6Format(rawdata, format_info[1], format_info[2])

        return None # Type isn't specified.

    @staticmethod
    def getNumber(rawdata, start, length) -> int:
        start_padding = 0
        end_padding = 0
        if (start) % 4 != 0:
            start_padding = start % 4
        if (length) % 4 != 0:
            end_padding = 4 - length % 4
        temp_hex = rawdata[(start+start_padding)//4:(start+length+end_padding)//4]

        temp_int = bin(int(temp_hex, 16))
        #print("getNumber({},{},{}) ==> {} ==> {}".format(rawdata, (start+start_padding)//4, (start+length+end_padding)//4, temp_hex, temp_int))
        temp_int = temp_int[2:2+length]

        return int(temp_int, 2)

    @staticmethod
    def getHEX(rawdata, start, length) -> str:
        start_padding = 0
        end_padding = 0
        if (start) % 4 != 0:
            start_padding = start % 4
        if (length) % 4 != 0:
            end_padding = 4 - length % 4
        temp_hex = rawdata[(start+start_padding)//4:(start+length+end_padding)//4]

        temp_int = bin(int(temp_hex, 16))
        #print("getNumber({},{},{}) ==> {} ==> {}".format(rawdata, (start+start_padding)//4, (start+length+end_padding)//4, temp_hex, temp_int))
        temp_int = temp_int[2:2+length]

        return hex(int(temp_int, 2))
        #return rawdata[start:start+length]

    @staticmethod
    def getMACFormat(rawdata, start, length) -> str:
        temp_lst = []
        for i in range(start//4,(start+length)//4,2):
            temp_lst.append(rawdata[i: i+2])
        mac = ":".join(temp_lst)

        return mac.upper()

    @staticmethod
    def getIPFormat(rawdata, start, length) -> str:
        temp_lst = []
        for i in range(start//4,(start+length)//4,2):
            temp_lst.append(str(int(rawdata[i: i+2],16)))
        ip = ".".join(temp_lst)

        return ip

    @staticmethod
    def getIPv6Format(rawdata, start, length) -> str:
        temp_lst = []
        for i in range(start//4,(start+length)//4,2):
            temp_lst.append(rawdata[i: i+2])
        mac = ":".join(temp_lst)

        for i in range(16,1,-1):
            candidate = ("00:"*i)[:-1]
            if mac.find(candidate) > -1:
                mac = mac.replace(candidate,"",1)
                break

        mac = mac.replace("00","0")

        return mac.upper()


# coding=utf-8
import hashlib

from falcon.errors import HTTPBadRequest
from ultros_site.base_route import BaseRoute

__author__ = "Gareth Coles"

class ProfileRoute(BaseRoute):
    route = "/profile"

    def on_get(self, req, resp):
        user = req.context["user"]

        if not user:
            raise HTTPBadRequest()

        self.render_template(
            req, resp, "users/profile.html",
            user=user,
            avatar="https://www.gravatar.com/avatar/{}".format(self.gravatar_hash(user.email))
        )

    def gravatar_hash(self, email: str):
        email = email.strip()
        email = email.lower()
        email = email.encode("UTF-8")

        return hashlib.md5(email).hexdigest()


import unittest
from solution.batch4.problem47 import consecutive_distinct_primes, \
    first_4_distinct_primes

class DistinctPrimesFactors(unittest.TestCase):
    def test_HR_problem_k2(self):
        k = 2
        nums = [20, 100]
        expected = [
            [14, 20],
            [14, 20, 21, 33, 34, 35, 38, 39, 44, 45, 50, 51, 54, 55,
             56, 57, 62, 68, 74, 75, 76, 85, 86, 87, 91, 92, 93, 94, 95, 98, 99]
                    ]
        for i, n in enumerate(nums):
            self.assertEqual(expected[i], consecutive_distinct_primes(n, k))

    def test_HR_problem_k3(self):
        k = 3
        nums = [644, 1000]
        expected = [[644], [644, 740, 804, 986]]
        for i, n in enumerate(nums):
            self.assertEqual(expected[i], consecutive_distinct_primes(n, k))

    def test_HR_problem_k4(self):
        k = 4
        nums = [10_000, 100_000, 300_000]
        expected = [[], [], [134_043, 238_203, 253_894, 259_368]]
        for i, n in enumerate(nums):
            self.assertEqual(expected[i], consecutive_distinct_primes(n, k))

    def test_PE_problem(self):
        expected = 134_043
        self.assertEqual(expected, first_4_distinct_primes())

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


#!/usr/bin/env python

import rospy
import math
import sys
import tf
from el2425_bitcraze.srv import SetTargetPosition
from el2425_bitcraze.srv import SetPolygonTrajectory
from geometry_msgs.msg import PoseStamped
from geometry_msgs.msg import Point

rate = 5
deltaTheta = 20

class PolygonTrajectoryPlanner:
    def __init__(self):
        self.rate = rospy.Rate(rate) # 3hz

        self.goal = [0, 0, 0]

        rospy.Subscriber('goal', PoseStamped, self.cfGoalCallback)
        self.setTargetPosition = rospy.ServiceProxy('set_target_position', SetTargetPosition)

        rospy.Service('set_polygon_trajectory', SetPolygonTrajectory, self.polygonTrajectoryCallback)

        self.planTrajectory = False
        self.onCircle = False

    def polygonTrajectoryCallback(self, req):
        self.center = req.center
        self.r = req.r
        self.xrotation = req.xrotation
        self.onCircle = False
        self.theta = 0

        if not self.planTrajectory:
            self.planTrajectory = True

        return()

    def run(self):
        self.theta = 0
        while not rospy.is_shutdown():
            if self.planTrajectory:
                if self.isOnCircle():
                    self.onCircle = True
                    theta_rad = math.pi*self.theta/180
                    x_new = self.center[0] + self.r*math.cos(theta_rad)
                    y_new = self.center[1] + self.r*math.sin(theta_rad)*math.cos(self.xrotation*math.pi/180)
                    z_new = self.center[2] - self.r*math.sin(theta_rad)*math.sin(self.xrotation*math.pi/180)

                    # step/ increment of 5 degrees.
                    # this step decides the shape of the cirlce
                    # if we change it to 90 degrees the tarjectory will become square
                    distToTarget = math.sqrt(math.pow(self.goal[0]-x_new,2) + math.pow(self.goal[1]-y_new,2) + math.pow(self.goal[2]-z_new,2))
                    if distToTarget <= 0.1:
                        self.theta = self.theta + deltaTheta       #10
                    #print "Point: %f" %(self.point.x)

                    if self.theta >= 360:
                        self.theta = 0
                else:
                    x_new = self.center[0] + self.r
                    y_new = self.center[1]
                    z_new = self.center[2]

                self.setTargetPosition(x_new, y_new, z_new)
            self.rate.sleep()

    def isOnCircle(self):
        if self.onCircle:
            return True
        else:
            x = self.goal[0]
            y = self.goal[1]
            z = self.goal[2]
            x0 = self.center[0] + self.r
            y0 = self.center[1]
            z0 = self.center[2]
            dist = math.sqrt(math.pow(x-x0,2) + math.pow(y-y0,2) + math.pow(z-z0,2))
            return dist <= 0.1

    def cfGoalCallback(self, goal):
        self.goal = [goal.pose.position.x, goal.pose.position.y, goal.pose.position.z]

if __name__ == "__main__":
    rospy.init_node("trajectory_handler")

    trajHandler = PolygonTrajectoryPlanner()
    trajHandler.run()


import numpy as np
import tensorflow as tf
from pyTasks.task import Task, Parameter
from pyTasks.task import Optional, containerHash
from pyTasks.target import CachedTarget, LocalTarget
from pyTasks.target import JsonService, FileTarget
from .gram_tasks import PrepareKernelTask
import logging
import math
from time import time
import os
from tensorflow.contrib.tensorboard.plugins import projector
from scipy.spatial.distance import cdist
from .graph_tasks import EdgeType

class WVSkipgram(object):

    def __init__(self, num_words, learning_rate, embedding_size,
                 num_steps, neg_sampling, unigrams, log="./log/"):
        self.num_words = num_words
        self.learning_rate = learning_rate
        self.embedding_size = embedding_size
        self.num_steps = num_steps
        self.neg_sampling = neg_sampling
        self.unigrams = unigrams
        self.log_dir = log
        self.graph, self.batch_inputs, self.batch_labels,self.normalized_embeddings,\
        self.loss, self.optimizer = self.trainer_initial()

    def trainer_initial(self):
        graph = tf.Graph()
        with graph.as_default():

            # logging
            self.logger = tf.summary.FileWriter(self.log_dir)

            with tf.name_scope("embedding"):
                batch_inputs = tf.placeholder(tf.int64, shape=([None, ]))
                batch_labels = tf.placeholder(tf.int64, shape=([None, 1]))

                graph_embeddings = tf.Variable(
                        tf.random_uniform([self.num_words, self.embedding_size], -0.5 / self.embedding_size, 0.5/self.embedding_size),
                        name='word_embedding')

                batch_graph_embeddings = tf.nn.embedding_lookup(graph_embeddings, batch_inputs) #hiddeb layer

                weights = tf.Variable(tf.truncated_normal([self.num_words, self.embedding_size],
                                                              stddev=1.0 / math.sqrt(self.embedding_size))) #output layer wt
                biases = tf.Variable(tf.zeros(self.num_words)) #output layer biases

                #negative sampling part
                loss = tf.reduce_mean(
                    tf.nn.nce_loss(weights=weights,
                                   biases=biases,
                                   labels=batch_labels,
                                   inputs=batch_graph_embeddings,
                                   num_sampled=self.neg_sampling,
                                   num_classes=self.num_words,
                                   sampled_values=tf.nn.fixed_unigram_candidate_sampler(
                                       true_classes=batch_labels,
                                       num_true=1,
                                       num_sampled=self.neg_sampling,
                                       unique=True,
                                       range_max=self.num_words,
                                       distortion=0.75,
                                       unigrams=self.unigrams)#word_id_freq_map_as_list is the
                                   # frequency of each word in vocabulary
                                   ))
                norm = tf.sqrt(tf.reduce_mean(tf.square(graph_embeddings), 1, keep_dims=True))
                normalized_embeddings = graph_embeddings/norm

                # summary
                tf.summary.histogram("weights", weights)
                tf.summary.histogram("biases", biases)
                tf.summary.scalar("loss", loss)

                config = projector.ProjectorConfig()
                emb = config.embeddings.add()
                emb.tensor_name = normalized_embeddings.name
                emb.metadata_path = os.path.join(self.log_dir, 'vocab.tsv')
                projector.visualize_embeddings(self.logger, config)

            with tf.name_scope('descent'):
                global_step = tf.Variable(0, trainable=False)
                learning_rate = tf.train.exponential_decay(self.learning_rate,
                                                           global_step, 100000, 0.96, staircase=True) #linear decay over time

                learning_rate = tf.maximum(learning_rate,0.001) #cannot go below 0.001 to ensure at least a minimal learning

                optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,global_step=global_step)

                self.logger.add_graph(graph)
        return graph, batch_inputs, batch_labels, normalized_embeddings, loss, optimizer

    def train(self, dataset):
        with tf.Session(graph=self.graph,
                        config=tf.ConfigProto(log_device_placement=True,allow_soft_placement=False)) as sess:

            merged_summary = tf.summary.merge_all()
            saver = tf.train.Saver()

            init = tf.global_variables_initializer()
            sess.run(init)

            sess.run(tf.tables_initializer())

            step = 0

            for i in range(self.num_steps):
                t0 = time()

                feed_it = dataset.make_initializable_iterator()
                next_element = feed_it.get_next()

                sess.run(feed_it.initializer)
                while True:
                    try:
                        feed_dict = sess.run([next_element])
                        feed_dict = {self.batch_inputs: feed_dict[0][0],
                                     self.batch_labels:
                                     sess.run(
                                        tf.reshape(feed_dict[0][1], [-1, 1])
                                        )
                                     }
                        loss_val = 0
                        _,  loss_val = sess.run([self.optimizer, self.loss], feed_dict=feed_dict)

                        if step % 10 == 0:
                            s = sess.run(merged_summary, feed_dict=feed_dict)
                            self.logger.add_summary(s, step)

                        if step % 1000 == 0:
                            saver.save(sess, os.path.join(self.log_dir, "model.ckpt"), step)

                        step += 1
                    except tf.errors.OutOfRangeError:
                        break

                epoch_time = time() - t0
                loss = 0

            #done with training
            final_embeddings = self.normalized_embeddings.eval()
        return final_embeddings

def collect_ast(G, nodes):
    stack = []
    stack.extend(nodes)

    out = []

    while len(stack) > 0:
        act = stack.pop()
        out.append(act)

        for in_node, _, _, d in G.in_edges(act, keys=True, data='type'):
            if d is EdgeType.se:
                stack.append(in_node)

    return out

def is_ast_node(G, node):
    ast_node = True

    for out_node, _, _, d in G.out_edges(node, keys=True, data='type'):
        ast_node &= d is EdgeType.se

    for out_node, _, _, d in G.in_edges(node, keys=True, data='type'):
        ast_node &= d is EdgeType.se

    return ast_node

class WVGraphSentenceTask(Task):
    out_dir = Parameter('./w2v/sentences/')

    def __init__(self, name, h, D):
        self.name = name
        self.h = h
        self.D = D

    def require(self):
        return PrepareKernelTask(self.name, self.h, self.D)

    def output(self):
        path = self.out_dir.value + self.__taskid__() + '.txt'
        return FileTarget(path)

    def __taskid__(self):
        return 'W2VGraphSentence_%s_%d_%d' % (self.name, self.h, self.D)

    def run(self):
        with self.input()[0] as i:
            G = i.query()

        L = []

        with self.output() as output:
            for node in G:

                in_nodes = []
                ast_nodes = []

                for in_node, _, _, d in G.in_edges(node, keys=True, data='type'):
                    if d is EdgeType.se:
                        ast_nodes.append(in_node)
                    elif d is EdgeType.de:
                        in_nodes.append(in_node)

                in_nodes.extend(collect_ast(G, ast_nodes))

                if len(in_nodes) == 0:
                    continue

                in_nodes = [G.node[n]['label'] for n in in_nodes]

                output.write(
                    str(G.node[node]['label']) + ' ' + ' '.join(in_nodes)+'\n'
                )

class WVVocabulary(Task):
    out_dir = Parameter('./w2v/')

    def __init__(self, graph_list, length, h, D):
        self.graph_list = graph_list
        self.h = h
        self.D = D
        self.length = length

    def require(self):
        return [
            WVGraphSentenceTask(
                name,
                self.h,
                self.D
            )
            for name in self.graph_list
        ]

    def output(self):
        path = self.out_dir.value + self.__taskid__() + '.json'
        return CachedTarget(
            LocalTarget(path, service=JsonService)
        )

    def __taskid__(self):
        return 'W2VVocabulary_%d_%d_%d' % (self.h, self.D,
                                           containerHash(self.graph_list))

    def run(self):
        vocab = {}
        overall = 0
        for inp in self.input():
            with inp as i:
                for line in i.readlines():
                    for w in line.split():
                        if w not in vocab:
                            vocab[w] = 0
                        vocab[w] += 1
                    overall += 1
        vocab = [x for x in sorted(
                    list(vocab.items()), key=lambda x: x[1], reverse=True
                 )][:self.length]
        vocab = {k[0]: (v, k[1]) for v, k in enumerate(vocab)}

        print('### Parsed %s samples ###' % overall)

        with self.output() as o:
            o.emit(vocab)

class WVEmbeddingTask(Task):
    out_dir = Parameter('./w2v/')
    embedding_size = Parameter(10)
    learning_rate = Parameter(0.001)
    num_steps = Parameter(3)
    neg_sampling = Parameter(15)
    batch_size = Parameter(100)
    log_dir = Parameter('./log/embedded/')

    def __init__(self, graph_list, length, h, D):
        self.graph_list = graph_list
        self.h = h
        self.D = D
        self.length = length

    def require(self):
        out = [WVVocabulary(self.graph_list, self.length, self.h, self.D)]
        out.extend([
            WVGraphSentenceTask(
                name,
                self.h,
                self.D
            )
            for name in self.graph_list
        ])
        return out

    def output(self):
        path = self.out_dir.value + self.__taskid__() + '.json'
        return CachedTarget(
            LocalTarget(path, service=JsonService)
        )

    def __taskid__(self):
        return 'W2VEmbeddingTask_%d_%d_%d' % (self.h, self.D,
                                           containerHash(self.graph_list))

    def _get_vocab(self, vocab):
        vocab = [x[0] for x in
                 sorted(list(vocab.items()),
                        key=lambda v: v[1][0])]

        with open(os.path.join(self.log_dir.value, 'vocab.tsv'), 'w') as o:
            for v in vocab:
                o.write(v+'\n')

        return vocab

    def run(self):
        with self.input()[0] as i:
            vocab = i.query()
        inp = (self.input()[i] for i in range(1, len(self.input())))
        filenames = [f.sandBox + f.path for f in inp]

        unigrams = [x[1][1] for x in
                    sorted(list(vocab.items()),
                    key=lambda v: v[1][0])]

        model_skipgram = WVSkipgram(
            len(vocab),
            self.learning_rate.value,
            self.embedding_size.value,
            self.num_steps.value,
            self.neg_sampling.value,
            unigrams,
            self.log_dir.value
        )

        with tf.Session(graph=model_skipgram.graph,
                        config=tf.ConfigProto(log_device_placement=True,allow_soft_placement=False)) as sess:

            vocab_mapping = tf.constant(self._get_vocab(vocab))
            table = tf.contrib.lookup.index_table_from_tensor(
                                        mapping=vocab_mapping, num_oov_buckets=1,
                                        default_value=-1)

            def parse_mapping(line):
                line = tf.string_split([line], ' ').values
                line = table.lookup(line)
                label = line[0:1]
                features = line[1:]
                return features, tf.tile(label, [tf.shape(features)[0]])

            dataset = tf.data.TextLineDataset(filenames)
            dataset = dataset.map(parse_mapping)
            dataset = dataset.flat_map(lambda features, labels:
                                        tf.data.Dataset().zip((
                                          tf.data.Dataset().from_tensor_slices(features),
                                          tf.data.Dataset().from_tensor_slices(labels))
                                        ))
            dataset = dataset.shuffle(1000).batch(self.batch_size.value)

        embedding = model_skipgram.train(dataset)

        with self.output() as o:
            o.emit(embedding.tolist())

class WVSimilarWords(Task):
    out_dir = Parameter('./w2v/')

    def __init__(self, graph_list, length, h, D):
        self.graph_list = graph_list
        self.h = h
        self.D = D
        self.length = length

    def require(self):
        out = [WVVocabulary(self.graph_list, self.length, self.h, self.D),
               WVEmbeddingTask(self.graph_list, self.length,
                               self.h, self.D)]

        return out

    def output(self):
        path = self.out_dir.value + self.__taskid__() + '.json'
        return CachedTarget(
            LocalTarget(path, service=JsonService)
        )

    def __taskid__(self):
        return 'W2VSimilarWords_%d_%d_%d' % (self.h, self.D,
                                           containerHash(self.graph_list))

    def run(self):
        with self.input()[0] as i:
            vocab = i.query()
        with self.input()[1] as i:
            embedding = np.array(i.query())

        inv_vocab = [None]*len(vocab)
        for k, v in vocab.items():
            inv_vocab[v[0]] = k
        inv_vocab = inv_vocab

        dis = cdist(embedding, embedding, 'cosine')
        arg_sort = np.argsort(dis, axis=1)[:, 1:6]

        near = {}

        for i, k in enumerate(inv_vocab):
            row = arg_sort[i]
            near[k] = []
            for j in range(row.shape[0]):
                near[k].append([inv_vocab[row[j]], 1-dis[i, j]])

        with self.output() as o:
            o.emit(near)