import sys
import os
from pathlib import Path
import random
import json
import pandas as pd
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
from seaborn import heatmap
import matplotlib.pyplot as plt
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QRadioButton, QLabel, QVBoxLayout, QHBoxLayout, \
    QButtonGroup, QTableView, QHeaderView, QSizePolicy, QTableWidget, QTableWidgetItem
from PyQt5.QtGui import QPixmap, QFont
from PyQt5.QtCore import Qt
from PyQt5 import QtCore
from typing import List
from results_reader import ResultReader, MonteCarloPlotter

from pdb import set_trace

if os.path.exists("/media/barrachina/data"):
    root_drive = Path("/media/barrachina/data")
elif os.path.exists("D:/"):
    root_drive = Path("D:/")
else:
    raise FileNotFoundError("Results path not found")

BASE_PATHS = {
    "BRET": str(root_drive / "datasets/PolSar/Bretigny-ONERA/bret-2003.png"),
    "OBER": str(
        root_drive / "datasets/PolSar/Oberpfaffenhofen/ESAR_Oberpfaffenhofen_T6/Master_Track_Slave_Track/T6/PauliRGB_T1.bmp"),
    "SF-AIRSAR": str(root_drive / "datasets/PolSar/San Francisco/PolSF/SF-AIRSAR/SF-AIRSAR-Pauli.bmp"),
    "SF-RS2": str(root_drive / "datasets/PolSar/San Francisco/PolSF/SF-RS2/SF-RS2-Pauli.bmp"),
    "FLEVOLAND": str(root_drive / "datasets/PolSar/Flevoland/AIRSAR_Flevoland/T3/PauliRGB.bmp"),
    "GARON": str(root_drive / "/datasets/PolSar/garon/20141125-1_djit_rad.png")
}
GROUND_TRUTH_PATHS = {
    "BRET": str(root_drive / "datasets/PolSar/Bretigny-ONERA/labels_4roi.png"),
    "OBER": str(root_drive / "datasets/PolSar/Oberpfaffenhofen/ground_truth.png"),
    "SF-AIRSAR": str(root_drive / "datasets/PolSar/San Francisco/PolSF/SF-AIRSAR/SF-AIRSAR-label3d.png"),
    "SF-RS2": str(root_drive / "datasets/PolSar/San Francisco/PolSF/SF-RS2/SF-RS2-label3d.png"),
    "FLEVOLAND": str(root_drive / "datasets/PolSar/Flevoland/AIRSAR_Flevoland/ground_truth.png"),
    "GARON": str(root_drive / "/datasets/PolSar/garon/20141125-1_djit_rad-labels.png")
}
START_VALUES = {
    "dataset": 'SF-AIRSAR',
    "model": "cao",
    "dtype": 'complex',
    "library": "complex",
    "dataset_mode": 'k',
    "dataset_method": 'random',
    "balance": 'None',
}

DEFAULT_MATPLOTLIB_COLORS = plt.rcParams['axes.prop_cycle'].by_key()['color']

class DataFrameModel(QtCore.QAbstractTableModel):
    DtypeRole = QtCore.Qt.UserRole + 1000
    ValueRole = QtCore.Qt.UserRole + 1001

    def __init__(self, df=pd.DataFrame(), parent=None):
        super(DataFrameModel, self).__init__(parent)
        self._dataframe = df

    def setDataFrame(self, dataframe):
        self.beginResetModel()
        self._dataframe = dataframe.copy()
        self.endResetModel()

    def dataFrame(self):
        return self._dataframe

    dataFrame = QtCore.pyqtProperty(pd.DataFrame, fget=dataFrame, fset=setDataFrame)

    @QtCore.pyqtSlot(int, QtCore.Qt.Orientation, result=str)
    def headerData(self, section: int, orientation: QtCore.Qt.Orientation, role: int = QtCore.Qt.DisplayRole):
        if role == QtCore.Qt.DisplayRole:
            if orientation == QtCore.Qt.Horizontal:
                return self._dataframe.columns[section]
            else:
                return str(self._dataframe.index[section])
        return QtCore.QVariant()

    def rowCount(self, parent=QtCore.QModelIndex()):
        if parent.isValid():
            return 0
        return len(self._dataframe.index)

    def columnCount(self, parent=QtCore.QModelIndex()):
        if parent.isValid():
            return 0
        return self._dataframe.columns.size

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if not index.isValid() or not (0 <= index.row() < self.rowCount() and 0 <= index.column() < self.columnCount()):
            return QtCore.QVariant()
        row = self._dataframe.index[index.row()]
        col = self._dataframe.columns[index.column()]
        dt = self._dataframe[col].dtype

        val = self._dataframe.iloc[row][col]
        if role == QtCore.Qt.DisplayRole:
            return str(val)
        elif role == DataFrameModel.ValueRole:
            return val
        if role == DataFrameModel.DtypeRole:
            return dt
        return QtCore.QVariant()

    def roleNames(self):
        roles = {
            QtCore.Qt.DisplayRole: b'display',
            DataFrameModel.DtypeRole: b'dtype',
            DataFrameModel.ValueRole: b'value'
        }
        return roles

    def flags(self, index) -> Qt.ItemFlags:
        # QtCore.Qt.ItemIsEditable |
        # | QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsDragEnabled | QtCore.Qt.ItemIsDropEnabled
        # | QtCore.Qt.ItemIsTristate
        return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        # Variables
        self.simulation_results = ResultReader()
        self.params = START_VALUES  # start config to show
        self.plotter = MonteCarloPlotter()

        # Qt objects
        self.setWindowTitle("Results")
        self.label_image = QLabel()
        self.ground_truth_image = QLabel()
        self.params_label = QLabel(str(self.params))
        self.params_label.setAlignment(Qt.AlignCenter)
        self.btngroup = []

        widget = QWidget()

        outer_layout = QVBoxLayout()
        lower_layout = self._get_lower_layout()
        outer_layout.addLayout(self._get_upper_layout())
        outer_layout.addLayout(lower_layout)
        widget.setLayout(outer_layout)
        # widget.setLayout(hlayout)
        self.setCentralWidget(widget)
        self.show()
        self.update_information()

    # Layouts
    def _get_accuracy_layout(self):
        self.acc_values_title = QLabel("Accuracy")
        myFont = QFont()
        myFont.setBold(True)
        self.acc_values_title.setFont(myFont)
        key = []
        key.append("Train OA")
        key.append("Train AA")
        key.append("Validation OA")
        key.append("Validation AA")
        key.append("Test OA")
        key.append("Test AA")
        self.tableAccWidget = QTableWidget()
        self.tableAccWidget.setRowCount(4)
        self.tableAccWidget.setColumnCount(6)
        self.tableAccWidget.setHorizontalHeaderLabels(key)
        self.tableAccWidget.setVerticalHeaderLabels(['mean', 'median', 'IQR', 'range'])
        self.tableAccWidget.setMinimumHeight(150)
        vbox = QVBoxLayout()
        vbox.addWidget(self.acc_values_title)
        vbox.addWidget(self.tableAccWidget)
        return vbox

    def _get_upper_layout(self):
        hlayout = QHBoxLayout()  # Main layout. Horizontal 2 things, radio buttons + image
        vlayout = QVBoxLayout()
        vlayout.addLayout(self.radiobuttons())
        vlayout.addWidget(self._get_conf_figure_widget())
        hlayout.addLayout(vlayout)
        img_layout = QVBoxLayout()
        img_layout.addWidget(self.params_label)  # Current config
        img_layout.addWidget(self.label_image)  # Show image
        hlayout.addLayout(img_layout)
        return hlayout

    def _get_lower_layout(self):
        hlayout = QHBoxLayout()

        hlayout.addWidget(self._get_dataframe_table_layout())
        hlayout.addLayout(self._get_figure_layout())

        return hlayout

    def _get_dataframe_table_layout(self):
        # layout = QHBoxLayout()
        self.tableView = QTableView()
        # self.verticalLayout.addWidget(self.tableView)
        # set_trace()
        self.tableView.setModel(
            DataFrameModel(self.simulation_results.df
                           .drop_duplicates()
                           .sort_values(by=['dataset', 'model', 'dtype', 'library',
                                            'dataset_mode', 'dataset_method', 'balance'])
                           .reset_index(drop=True)
                           )
        )
        self.tableView.setAlternatingRowColors(True)
        self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        for i in range(len(self.simulation_results.df.keys())):
            self.tableView.horizontalHeader().setSectionResizeMode(i, QHeaderView.ResizeToContents)
        self.tableView.setMinimumWidth(600)
        sp = self.tableView.sizePolicy()
        sp.setHorizontalPolicy(QSizePolicy.Minimum)
        self.tableView.setSizePolicy(sp)
        # layout.addWidget(self.tableView)
        return self.tableView

    def _get_figure_layout(self):
        self.figure = plt.figure()
        self.figure.tight_layout()
        self.canvas = FigureCanvas(self.figure)
        self.toolbar = NavigationToolbar(self.canvas, self)
        vlay = QVBoxLayout()
        vlay.addWidget(self.toolbar)
        vlay.addWidget(self.canvas)
        return vlay

    def _get_conf_figure_widget(self):
        self.conf_figure = plt.figure()
        self.conf_figure.tight_layout()
        self.conf_canvas = FigureCanvas(self.conf_figure)
        return self.conf_canvas

    def radiobuttons(self):
        outer_vlay = QVBoxLayout()
        hl = QHBoxLayout()
        vlayout = QVBoxLayout()

        vlayout.addLayout(self.add_title(self.dataset_radiobutton(), name="Dataset"))
        vlayout.addLayout(self.add_title(self.model_radiobutton(), "Model"))
        vlayout.addLayout(self.add_title(self.dtype_radiobuttons(), "Dtype"))
        vlayout.addLayout(self.add_title(self.library_radiobutton(), "Library"))
        vlayout.addLayout(self.add_title(self.dataset_mode_radiobuttons(), "Dataset Mode"))
        vlayout.addLayout(self.add_title(self.model_method_radiobutton(), "Dataset Method"))
        vlayout.addLayout(self.add_title(self.balance_radiobuttons(), "Balance"))
        vlayout.addLayout(self.add_title(self.equiv_technique_radiobutton(), "Equivalent Technique"))

        hl.addLayout(vlayout)
        hl.addWidget(self.ground_truth_image)

        outer_vlay.addLayout(hl)
        outer_vlay.addStretch()
        outer_vlay.addLayout(self._get_accuracy_layout())
        return outer_vlay

    def dataset_mode_radiobuttons(self):
        vlayout = QHBoxLayout()
        self.coh_rb = QRadioButton("coh")
        self.coh_rb.toggled.connect(lambda: self.update_information("dataset_mode", self.coh_rb.text()))

        self.pauli_rb = QRadioButton("k", self)
        self.pauli_rb.toggled.connect(lambda: self.update_information("dataset_mode", self.pauli_rb.text()))

        self.btngroup.append(QButtonGroup())
        self.btngroup[-1].addButton(self.pauli_rb)
        self.btngroup[-1].addButton(self.coh_rb)

        self.coh_rb.setChecked(True)
        vlayout.addWidget(self.coh_rb)
        vlayout.addWidget(self.pauli_rb)
        vlayout.addStretch()

        return vlayout

    def dtype_radiobuttons(self):
        vlayout = QHBoxLayout()
        self.complex_dtype_rb = QRadioButton("complex")
        self.complex_dtype_rb.toggled.connect(
            lambda state: state and self.update_information("dtype", self.complex_dtype_rb.text()))

        self.real_dtype_rb = QRadioButton("real_imag", self)
        self.real_dtype_rb.toggled.connect(
            lambda state: state and self.update_information("dtype", self.real_dtype_rb.text()))

        rb2 = QRadioButton("amplitude_phase")
        rb2.toggled.connect(lambda state: state and self.update_information("dtype", rb2.text()))
        rb3 = QRadioButton("amplitude_only")
        rb3.toggled.connect(lambda state: state and self.update_information("dtype", rb3.text()))
        rb4 = QRadioButton("real_only")
        rb4.toggled.connect(lambda state: state and self.update_information("dtype", rb4.text()))

        self.btngroup.append(QButtonGroup())
        # self.btngroup[-1].addButton(self.real_dtype_rb)
        self.btngroup[-1].addButton(self.complex_dtype_rb)
        self.btngroup[-1].addButton(self.real_dtype_rb)
        self.btngroup[-1].addButton(rb2)
        self.btngroup[-1].addButton(rb3)
        self.btngroup[-1].addButton(rb4)

        self.complex_dtype_rb.setChecked(True)
        vlayout.addWidget(self.complex_dtype_rb)
        vlayout.addWidget(self.real_dtype_rb)
        vlayout.addWidget(rb2)
        vlayout.addWidget(rb3)
        vlayout.addWidget(rb4)
        vlayout.addStretch()

        return vlayout

    def balance_radiobuttons(self):
        vlayout = QHBoxLayout()
        rb1 = QRadioButton("none")
        rb1.toggled.connect(lambda: self.update_information("balance", rb1.text()))

        rb2 = QRadioButton("loss", self)
        rb2.toggled.connect(lambda: self.update_information("balance", rb2.text()))

        rb3 = QRadioButton("dataset")
        rb3.toggled.connect(lambda: self.update_information("balance", rb3.text()))

        self.btngroup.append(QButtonGroup())
        self.btngroup[-1].addButton(rb3)
        self.btngroup[-1].addButton(rb2)
        self.btngroup[-1].addButton(rb1)

        rb1.setChecked(True)
        vlayout.addWidget(rb1)
        vlayout.addWidget(rb2)
        vlayout.addWidget(rb3)
        vlayout.addStretch()

        return vlayout

    def equiv_technique_radiobutton(self):
        vlayout = QHBoxLayout()
        rb1 = QRadioButton("ratio_tp")
        rb1.toggled.connect(lambda: self.update_information("equiv_technique", rb1.text()))

        rb2 = QRadioButton("np", self)
        rb2.toggled.connect(lambda: self.update_information("equiv_technique", rb2.text()))

        rb3 = QRadioButton("alternate_tp")
        rb3.toggled.connect(lambda: self.update_information("equiv_technique", rb3.text()))

        rb4 = QRadioButton("none")
        rb4.toggled.connect(lambda: self.update_information("equiv_technique", rb4.text()))

        self.btngroup.append(QButtonGroup())
        self.btngroup[-1].addButton(rb4)
        self.btngroup[-1].addButton(rb3)
        self.btngroup[-1].addButton(rb2)
        self.btngroup[-1].addButton(rb1)

        rb1.setChecked(True)
        vlayout.addWidget(rb1)
        vlayout.addWidget(rb2)
        vlayout.addWidget(rb3)
        vlayout.addWidget(rb4)
        vlayout.addStretch()

        return vlayout

    def library_radiobutton(self):
        vlayout = QHBoxLayout()
        self.cvnn_library_rb = QRadioButton("cvnn", self)
        self.cvnn_library_rb.toggled.connect(
            lambda state: state and self.update_information("library", self.cvnn_library_rb.text()))

        rb2 = QRadioButton("tensorflow", self)
        rb2.toggled.connect(lambda state: state and self.update_information("library", rb2.text()))

        self.btngroup.append(QButtonGroup())
        self.btngroup[-1].addButton(rb2)
        self.btngroup[-1].addButton(self.cvnn_library_rb)

        self.cvnn_library_rb.setChecked(True)
        vlayout.addWidget(self.cvnn_library_rb)
        vlayout.addWidget(rb2)
        vlayout.addStretch()

        return vlayout

    def model_method_radiobutton(self):
        vlayout = QHBoxLayout()
        rb1 = QRadioButton("random")
        rb1.toggled.connect(lambda: self.update_information("dataset_method", rb1.text()))

        rb2 = QRadioButton("separate", self)
        rb2.toggled.connect(lambda: self.update_information("dataset_method", rb2.text()))

        rb3 = QRadioButton("single_separated_image")
        rb3.toggled.connect(lambda: self.update_information("dataset_method", rb3.text()))

        self.btngroup.append(QButtonGroup())
        self.btngroup[-1].addButton(rb3)
        self.btngroup[-1].addButton(rb2)
        self.btngroup[-1].addButton(rb1)

        rb1.setChecked(True)
        vlayout.addWidget(rb1)
        vlayout.addWidget(rb2)
        vlayout.addWidget(rb3)
        vlayout.addStretch()

        return vlayout

    def model_radiobutton(self):
        vlayout = QHBoxLayout()
        rb1 = QRadioButton("cao")
        rb1.toggled.connect(lambda: self.update_information("model", rb1.text()))

        rb2 = QRadioButton("own", self)
        rb2.toggled.connect(lambda: self.update_information("model", rb2.text()))

        # rb3 = QRadioButton("zhang")
        # rb3.toggled.connect(lambda: self.update_information("model", rb3.text()))
        #
        # rb4 = QRadioButton("haensch", self)
        # rb4.toggled.connect(lambda: self.update_information("model", rb4.text()))
        #
        # rb5 = QRadioButton("tan", self)
        # rb5.toggled.connect(lambda: self.update_information("model", rb5.text()))

        rb6 = QRadioButton("cnn", self)
        rb6.toggled.connect(lambda: self.update_information("model", rb6.text()))

        rb7 = QRadioButton("mlp", self)
        rb7.toggled.connect(lambda: self.update_information("model", rb7.text()))

        rb8 = QRadioButton("expanded-mlp", self)
        rb8.toggled.connect(lambda: self.update_information("model", rb8.text()))

        rb9 = QRadioButton("expanded-cnn", self)
        rb9.toggled.connect(lambda: self.update_information("model", rb9.text()))

        self.btngroup.append(QButtonGroup())
        self.btngroup[-1].addButton(rb9)
        self.btngroup[-1].addButton(rb8)
        self.btngroup[-1].addButton(rb7)
        self.btngroup[-1].addButton(rb6)
        # self.btngroup[-1].addButton(rb5)
        # self.btngroup[-1].addButton(rb4)
        # self.btngroup[-1].addButton(rb3)
        self.btngroup[-1].addButton(rb2)
        self.btngroup[-1].addButton(rb1)

        rb1.setChecked(True)
        vlayout.addWidget(rb1)
        vlayout.addWidget(rb2)
        # vlayout.addWidget(rb3)
        # vlayout.addWidget(rb4)
        # vlayout.addWidget(rb5)
        vlayout.addWidget(rb6)
        vlayout.addWidget(rb7)
        vlayout.addWidget(rb8)
        vlayout.addWidget(rb9)
        vlayout.addStretch()

        return vlayout

    def dataset_radiobutton(self):
        vlayout = QHBoxLayout()
        rb1 = QRadioButton("SF-AIRSAR")
        rb1.toggled.connect(lambda: self.update_information("dataset", rb1.text()))

        rb2 = QRadioButton("SF-RS2", self)
        rb2.toggled.connect(lambda: self.update_information("dataset", rb2.text()))

        rb3 = QRadioButton("OBER")
        rb3.toggled.connect(lambda: self.update_information("dataset", rb3.text()))

        rb4 = QRadioButton("BRET", self)
        rb4.toggled.connect(lambda: self.update_information("dataset", rb4.text()))

        rb5 = QRadioButton("FLEVOLAND", self)
        rb5.toggled.connect(lambda: self.update_information("dataset", rb5.text()))

        self.btngroup.append(QButtonGroup())
        self.btngroup[-1].addButton(rb5)
        self.btngroup[-1].addButton(rb4)
        self.btngroup[-1].addButton(rb3)
        self.btngroup[-1].addButton(rb2)
        self.btngroup[-1].addButton(rb1)

        rb1.setChecked(True)
        vlayout.addWidget(rb1)
        vlayout.addWidget(rb2)
        vlayout.addWidget(rb3)
        vlayout.addWidget(rb4)
        vlayout.addWidget(rb5)
        vlayout.addStretch()

        return vlayout

    def add_title(self, layout, name: str, up: bool = True):
        lay = QVBoxLayout()
        l1 = QLabel(name)
        myFont = QFont()
        myFont.setBold(True)
        l1.setFont(myFont)
        l1.setAlignment(Qt.AlignLeft)
        if up:
            lay.addWidget(l1)
        lay.addLayout(layout)
        # lay.addStretch()
        if not up:
            lay.addWidget(l1)
        return lay

    # Update information
    def get_image(self, image_path: List[str]):
        if not image_path:
            pixmap = QPixmap(BASE_PATHS[self.params["dataset"]])
        else:
            image_path = random.choice(image_path)
            pixmap = QPixmap(image_path)
        scaled_pixmap = pixmap.scaled(900, 700, QtCore.Qt.KeepAspectRatio)
        self.label_image.setPixmap(scaled_pixmap)
        self.label_image.resize(scaled_pixmap.width(), scaled_pixmap.height())

    def get_image_ground_truth(self):
        pixmap = QPixmap(GROUND_TRUTH_PATHS[self.params["dataset"]])
        scaled_pixmap = pixmap.scaled(400, 200, QtCore.Qt.KeepAspectRatio)
        self.ground_truth_image.setPixmap(scaled_pixmap)
        self.ground_truth_image.resize(scaled_pixmap.width(), scaled_pixmap.height())

    def clear_plot(self):
        self.figure.clear()
        self.canvas.draw()

    def plot(self, history_path):
        self.figure.clear()
        ax1 = self.figure.add_subplot(121)
        ax2 = self.figure.add_subplot(122)
        ax1.clear()
        ax2.clear()
        self.plotter.plot(data=history_path, ax=ax1, keys=["accuracy", "val_accuracy"])
        self.plotter.plot(data=history_path, ax=ax2, keys=["loss", "val_loss"])
        ax1.grid(True, axis='both')
        ax2.grid(True, axis='both')
        self.canvas.draw()

    def clear_conf_matrix(self):
        if hasattr(self, "conf_figure"):
            self.conf_figure.clear()
            self.conf_canvas.draw()

    def plot_conf_matrix(self, conf_list):
        if hasattr(self, "conf_figure"):
            self.conf_figure.clear()
            ax1 = self.conf_figure.add_subplot(131)
            ax2 = self.conf_figure.add_subplot(132)
            ax3 = self.conf_figure.add_subplot(133)
            ax1.clear()
            ax2.clear()
            ax3.clear()
            heatmap(conf_list[0].drop('Total', axis=1).drop('Total'), ax=ax1, annot=True, cmap="rocket_r")
            heatmap(conf_list[1].drop('Total', axis=1).drop('Total'), ax=ax2, annot=True, cmap="rocket_r")
            if len(conf_list) > 2:
                heatmap(conf_list[2].drop('Total', axis=1).drop('Total'), ax=ax3, annot=True, cmap="rocket_r")
            self.conf_canvas.draw()

    def print_values(self, json_key):
        if json_key is not None and hasattr(self, "tableAccWidget"):
            self.acc_values_title.setText(f"Accuracy (total count {int(self.simulation_results.get_total_count(json_key))})")
            for i, stat in enumerate(["mean", "median", "iqr", 'range']):
                for j, dat in enumerate(["train", "val", "test"]):
                    for k, variable in enumerate(["accuracy", "average_accuracy"]):
                        self.tableAccWidget.setItem(i, 2*j + k, QTableWidgetItem(
                            self.simulation_results.get_eval_stat_string(json_key=json_key, dataset=dat,
                                                                         stat=stat, variable=variable)))
            header = self.tableAccWidget.horizontalHeader()
            header.setSectionResizeMode(0, QHeaderView.ResizeToContents)
            header.setSectionResizeMode(1, QHeaderView.ResizeToContents)
            header.setSectionResizeMode(2, QHeaderView.ResizeToContents)
            header.setSectionResizeMode(3, QHeaderView.ResizeToContents)
            header.setSectionResizeMode(4, QHeaderView.ResizeToContents)
            header.setSectionResizeMode(5, QHeaderView.ResizeToContents)
            # header.setMinimumSectionSize(200)
        elif hasattr(self, "tableAccWidget"):
            self.acc_values_title.setText("Accuracy")
            for i in range(len(["mean", "median", "iqr", 'range'])):
                self.tableAccWidget.setItem(i, 0, QTableWidgetItem(f"00.00%"))
                self.tableAccWidget.setItem(i, 1, QTableWidgetItem(f"00.00%"))
                self.tableAccWidget.setItem(i, 2, QTableWidgetItem(f"00.00%"))
                self.tableAccWidget.setItem(i, 3, QTableWidgetItem(f"00.00%"))
                self.tableAccWidget.setItem(i, 4, QTableWidgetItem(f"00.00%"))
                self.tableAccWidget.setItem(i, 5, QTableWidgetItem(f"00.00%"))

    def _verify_combinations(self, key, value):
        if value == "complex":
            if hasattr(self, 'cvnn_library_rb'):  # It wont exists if I still didnt create the radiobutton.
                self.cvnn_library_rb.setChecked(True)  # Set library cvnn
        elif value == "tensorflow":
            if hasattr(self, 'real_dtype_rb'):
                if self.complex_dtype_rb.isChecked():
                    self.real_dtype_rb.setChecked(True)  # Set real dtype
        elif key == 'dataset':
            if value == "OBER":
                if hasattr(self, 'coh_rb'):
                    self.coh_rb.setChecked(True)  # Set real dtype
                    self.coh_rb.setEnabled(False)
                if hasattr(self, 'pauli_rb'):
                    self.pauli_rb.setEnabled(False)
            else:
                if hasattr(self, 'coh_rb'):
                    self.coh_rb.setEnabled(True)
                if hasattr(self, 'pauli_rb'):
                    self.pauli_rb.setEnabled(True)
        elif key == "equiv_technique" and value != "ratio_tp":
            if hasattr(self, 'real_dtype_rb'):
                self.real_dtype_rb.setChecked(True)  # Set real dtype

    def update_information(self, key=None, value=None):
        if key and value:
            self.params[key] = value
            self._verify_combinations(key, value)
        self.params_label.setText(str(self.params))
        # Not yet working.
        # Try https://stackoverflow.com/questions/49929668/disable-and-enable-radiobuttons-from-another-radiobutton-in-pyqt4-python
        json_key = json.dumps(self.params, sort_keys=True)
        self.get_image(self.simulation_results.get_image(json_key))
        self.get_image_ground_truth()
        if self.simulation_results.data_exists(json_key):
            stats = self.simulation_results.get_stats(json_key=json_key)
            conf_stats = self.simulation_results.get_conf_stats(json_key=json_key)
            self.plot(stats) if self.simulation_results.data_exists(json_key) else self.clear_plot()
            self.print_values(json_key)
            self.plot_conf_matrix(conf_stats) if conf_stats else self.clear_conf_matrix()
        else:
            self.print_values(None)
            self.clear_plot()
            self.clear_conf_matrix()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    app.exec()


import os, numpy
from scipy.interpolate import UnivariateSpline

datapath=os.path.join(os.path.dirname(os.path.abspath(__file__)),"transmission_data")

class Material():
    def __init__(self, name, energies, absorption_lengths_um, density=1.0):
        self.name=name
        self.energies=numpy.array(energies)
        self.absorption_lengths_um=absorption_lengths_um
        self.density=density

    def transmission(self, energies, length_um=1, density=None):
        if density is None: density = self.density
        length_um = length_um*density/float(self.density)
        return numpy.exp(-length_um/numpy.interp(energies, self.energies, self.absorption_lengths_um))

    def absorbtion(self, energies, length_um=1, density=None):
        return 1-self.transmission(energies, length_um, density)

class Optic():
    def __init__(self, name, energies, transmission_data, solid_angle=1):
        self.name=name
        self.energies=numpy.array(energies)
        self.transmission_data=transmission_data
        self.solid_angle=solid_angle

    def transmission(self, energies, solid_angle=None):
        if solid_angle is None: solid_angle=self.solid_angle
        transmission_data = self.transmission_data*solid_angle/self.solid_angle
        return numpy.interp(energies, self.energies, transmission_data)

class PlasmaSource():
    def __init__(self, name, e_pulse, N0, T):
        self.name=name
        self.e_pulse=e_pulse
        self.N0=N0
        self.T=T

    def spectrum(self, energies, e_pulse):
        N0 = numpy.interp(e_pulse, self.e_pulse, self.N0)
        T =  numpy.interp(e_pulse, self.e_pulse, self.T)
        return N0*numpy.exp(-numpy.array(energies)/T)

#    def spectrum(self, energies, e_pulse):
#        N0 = numpy.interp(e_pulse, self.e_pulse, self.N0)
#        T =  numpy.interp(e_pulse, self.e_pulse, self.T)
#        T2=T*0.5
#        return numpy.exp(6000/T-6000/T2)*N0*numpy.exp(-numpy.array(energies)/T)*(energies>6000)+N0*numpy.exp(-numpy.array(energies)/T2)*(energies<6000)

def read_material_files():
    datapath=os.path.join(os.path.dirname(os.path.abspath(__file__)),"transmission_data")
    dirList=os.listdir(datapath)
    material_dict={}
    for fname in dirList:
        if '.txt' not in fname:continue
        data = numpy.loadtxt(os.path.join(datapath,fname))
        name=fname[0:-4]
        material_dict[name]=Material(name, data[:,0], data[:,1])
    return material_dict

def read_optic_files():
    datapath=os.path.join(os.path.dirname(os.path.abspath(__file__)),"optic_data")
    dirList=os.listdir(datapath)
    optic_dict={}
    for fname in dirList:
        if '.txt' not in fname:continue
        data = numpy.loadtxt(os.path.join(datapath,fname))
        name=fname[0:-4]
        optic_dict[name]=Optic(name, data[:,0], data[:,1])
    return optic_dict

def read_source_files():
    datapath=os.path.join(os.path.dirname(os.path.abspath(__file__)),"source_data")
    dirList=os.listdir(datapath)
    source_dict={}
    for fname in dirList:
        if '.txt' not in fname:continue
        data = numpy.loadtxt(os.path.join(datapath,fname))
        name=fname[0:-4]
        source_dict[name]=PlasmaSource(name, data[:,0], data[:,1], data[:,2])
    return source_dict

def plasma_source_spectrum(energies, N0, T):
    """ energy, array of energies in eV
    N0 photons/(eV steradian shot),
    T characteristic energy/temperature (eV) """
    return N0*numpy.exp(-energies/T)

def materials_transmission(energies, materials_thickness):
    flux = numpy.ones_like(energies, dtype='float')
    for material,thickness in materials_thickness.iteritems():
        flux*=materials[material].transmission(energies, thickness)
    return flux

def source_optic_materials(e_pulse, optic_name, materials_thickness, solid_angle=None, energies = None, source_name = "water_jet_2013"):
    optic = optics[optic_name]
    if energies is None: energies = optic.energies
    return sources[source_name].spectrum(energies, e_pulse)*optic.transmission(energies, solid_angle)*materials_transmission(energies, materials_thickness)

def source_optic_materials_absorber(e_pulse, optic_name, materials_thickness, solid_angle=None, energies = None, absorber_material='Bi', absorber_length_um=2, source_name = "water_jet_2013"):
    return materials[absorber_material].absorbtion(energies, absorber_length_um)*source_optic_materials(e_pulse, optic_name, materials_thickness, solid_angle, energies, source_name)

materials=read_material_files()
optics=read_optic_files()
sources=read_source_files()


import time
#import logging

from vmcjp.utils import cmd_const
from vmcjp.slack.db import write_cred_db, read_event_db
from vmcjp.vmc.vmc_client import login, sddc_list, token_validation, get_sddcs, get_sddclimit, get_aws_region, get_connected_accounts, get_vpc_map, sddc_creation, sddc_deletion, sddc_name_and_id_list, get_sddc

#logger = logging.getLogger()
#logger.setLevel(logging.INFO)

def lambda_handler(event, context):
#    logging.info(event)

    expire_time = event.get("expire_time")
    command = event.get("vmc_command")

    if expire_time is None and command != "validate_token":
        data = login(event.get("token"))
        event.update(data)
        write_cred_db(
            event.get("db_url"),
            event.get("user_id"),
            data
        )
    elif expire_time is not None and _expired(expire_time):
        data = login(event.get("token"))
        event.update(data)
        write_cred_db(
            event.get("db_url"),
            event.get("user_id"),
            data
        )

    return eval(event.get("vmc_command"))(event)

def _expired(expire_time):
    now = time.time()
    return now > expire_time

def validate_token(event):
    return token_validation(
        event.get("token"),
        event.get("org_id")
    )

def list_sddcs(event):
#    list = sddc_list(
#        event.get("access_token"),
#        event.get("org_id")
#    )
    return sddc_list(
        event.get("access_token"),
        event.get("org_id")
    )
#    return list

def check_max_hosts(event):
    sddclimit = get_sddclimit(
        event.get("access_token"),
        event.get("org_id")
    )
    sddcs = get_sddcs(
        event.get("access_token"),
        event.get("org_id")
    )

    i = 0
    for sddc in sddcs:
        i += len(sddc.get("resource_config").get("esx_hosts"))

    max_hosts = (sddclimit - 1) - i
    if max_hosts < 1:
        return max_hosts
    else:
        return 1 if max_hosts < 3 else max_hosts

def list_region(event):
    regions = get_aws_region(
        event.get("access_token"),
        event.get("org_id")
    )

    region_ids = regions.keys()
    return [
        {
            "text": regions.get(region_id),
            "value": region_id
        } for region_id in region_ids
    ]

def list_aws_account(event):
    accounts = get_connected_accounts(
        event.get("access_token"),
        event.get("org_id")
    )

    if accounts is not None:
        return [
            {
                "text": account.get("account_number"),
                "value": "{}+{}".format(
                    account.get("account_number"),
                    account.get("id")
                )
            } for account in accounts
        ]

def list_vpc(event):
    data = get_vpc_map(
        event.get("access_token"),
        event.get("org_id"),
        event.get("linked_account_id"),
        event.get("region"),
    )
    vpc_map = data.get("vpc_map")
    vpcs = data.get("vpc_map").keys()

    return [
        {
            "text": "{}, {}, {}".format(
                vpc,
                vpc_map.get(vpc).get("description"),
                vpc_map.get(vpc).get("cidr_block")
            ),
            "value": vpc
        } for vpc in vpcs
    ]

def list_subnet(event):
    data = get_vpc_map(
        event.get("access_token"),
        event.get("org_id"),
        event.get("connected_account_id"),
        event.get("region"),
    )
    vpc_map = data.get("vpc_map")
    vpc = vpc_map.get(event.get("vpc_id"))
    subnets = vpc.get("subnets")

    return [
        {
            "text": "{}, {}, {}".format(
                subnet.get("subnet_id"),
                subnet.get("availability_zone"),
                subnet.get("subnet_cidr_block")
            ),
            "value": subnet.get("subnet_id")
        } for subnet in subnets if subnet.get("compatible")
    ]

def create_sddc(event):
    event_db = read_event_db(
        event.get("db_url"),
        event.get("user_id"),
    )

    if event_db.get("status") != "creating":
        data = sddc_creation(
            event.get("access_token"),
            event.get("org_id"),
            event.get("link_aws"),
            event.get("sddc_name"),
            event.get("num_hosts"),
            event.get("provider"),
            event.get("region"),
            event.get("size"),
            event.get("vpc_cidr"),
            event.get("connected_account_id"),
            event.get("customer_subnet_id"),
            event.get("deployment_type"),
            event.get("host_instance_type"),
            event.get("sddc_type"),
            event.get("storage_capacity")
        )
        return data.get("id")
    else:
        raise Exception("Can not create sddc concurrently!!")

def delete_sddc(event):
    data = sddc_deletion(
        event.get("access_token"),
        event.get("org_id"),
        event.get("sddc_id"),
    )
    return data.get("id")

def list_sddcs_name_id(event):
    return sddc_name_and_id_list(
        event.get("access_token"),
        event.get("org_id")
    )

def get_sddc_user(event):
    data = get_sddc(
        event.get("access_token"),
        event.get("org_id"),
        event.get("sddc_id")
    )
    return data.get("user_name")


import time
import torch
import psutil

def MegaBytes(bytes):
    return bytes / (1024.0 * 1024.0)

class _MeasureClass:
    def __init__(self):
        self.enabled = False
        self.last_measure = None

    def __call__(self, name=None):
        if not self.enabled:
            return

        current_time = time.time()
        current_gpu_memory = torch.cuda.memory_allocated(
        ) if torch.cuda.is_available() else 0

        current_memory_info = psutil.Process().memory_info()

        if self.last_measure is not None:
            print(
                '{} took {:.3f} seconds'.format(
                    self.last_measure['name'],
                    current_time - self.last_measure['start_time']
                )
            )
            if torch.cuda.is_available():
                print(
                    '{} consumed {:.2f} MB'.format(
                        self.last_measure['name'],
                        MegaBytes(
                            current_gpu_memory - self.last_measure['gpu_memory']
                        )
                    )
                )
                print(
                    'current gpu memory: {:.2f} MB'.format(
                        MegaBytes(current_gpu_memory)
                    )
                )
            else:
                print(
                    '{} consumed rss= {:.2f} MB vms= {:.2f} MB'.format(
                        self.last_measure['name'],
                        MegaBytes(
                            current_memory_info.rss -
                            self.last_measure['memory_info'].rss
                        ),
                        MegaBytes(
                            current_memory_info.vms -
                            self.last_measure['memory_info'].vms
                        )
                    )
                )
                print(
                    'current rss= {:.2f} MB vms= {:.2f} MB'.format(
                        MegaBytes(current_memory_info.rss),
                        MegaBytes(current_memory_info.vms)
                    )
                )

        if name is not None:
            self.last_measure = {
                'name': name,
                'start_time': time.time(),
                'gpu_memory': current_gpu_memory,
                'memory_info': current_memory_info
            }
        else:
            self.last_measure = None

measure = _MeasureClass()
"""
Use `measure` to measure the time and the memory cosumed between two moments in the execution of the code.

Example::

    measure('cooking')
    cook_food()
    measure('eating')
    eat_food()
    measure()

Output::

    cooking took 1.2 seconds
    cooking consumed 205000 bytes
    current gpu memory: 205000 bytes
    eating took 0.7 seconds
    eating consumed 103000 bytes
    current gpu memory: 308000 bytes

"""


import telebot

bot = telebot.TeleBot('1274495758:AAGCbMvfDqmvvHNRj-I60DEjZvfV4qLCoy0')

@bot.message_handler(commands=['start'])
def send_welcome(message):
	bot.reply_to(message, "О какой стране вы хотите узнать?😊 ")

@bot.message_handler(func=lambda m: True)
def echo_all(message):
    if message.text == 'Казахстан':
        bot.reply_to(message, 'Местоположения: Центр Евразий \n'
                     'Президент: К.Ж. Токаев \n'
                     'Столица: Нур-Султан \n'
                     'Насиление: 18 809 210 млн человек \n'
                     'Государственный язык: Казахский язык \n'
                     'Площадь страны: 2 724 900 км² \n'
                     'Валюта: Тенге \n'
                     'Подробнее: https://ru.wikipedia.org/wiki/Казахстан')
    if message.text == 'Корея':
        bot.reply_to(message, 'Местоположения: Восточная Азия \n'
                              'Президент: Мун Чжэ Ин \n'
                              'Столица: Сеул \n'
                              'Насиление: 51 млн человек \n'
                              'Государственный язык: Корейский язык \n'
                              'Площадь страны: 102 210 км² \n'
                              'Валюта: Вон \n'
                              'Подробнее: https://ru.wikipedia.org/wiki/Республика_Корея')
    if message.text == 'Россия':
        bot.reply_to(message, 'Местоположения: Восточная Европа и Северная Азия \n'
                              'Президент: В.С. Путин \n'
                              'Столица: Москва \n'
                              'Насиление: 146 748 590 млн человек \n'
                              'Государственный язык: Русский язык \n'
                              'Площадь страны: 17 125 191 км² \n'
                              'Валюта: Рубль \n'
                              'Подробнее: https://ru.wikipedia.org/wiki/Россия')
    if message.text == 'Китай':
        bot.reply_to(message, 'Местоположения: Восточная Азия \n'
                              'Президент: Чжунхуа Жэньминь Гунхэго \n'
                              'Столица: Пекин \n'
                              'Насиление: 1 404 328 611 млрд человек \n'
                              'Государственный язык: Китайский язык \n'
                              'Площадь страны: 9 598 962 км² \n'
                              'Валюта: Китайский Юань \n'
                              'Подробнее: https://ru.wikipedia.org/wiki/Китай')
    if message.text == 'Киргизия':
        bot.reply_to(message, 'Местоположения: Центральная Азия \n'
                              'Президент: Талант Мамытов \n'
                              'Столица: Бишкек \n'
                              'Насиление: 6 389 500 млн человек \n'
                              'Государственный язык: Киргизский язык \n'
                              'Площадь страны: 199 951 км² \n'
                              'Валюта: Сом \n'
                              'Подробнее: https://ru.wikipedia.org/wiki/Киргизия')
    if message.text == 'Франция':
        bot.reply_to(message, 'Местоположения: Заподная Европа \n'
                              'Президент: Эмманюэль Макрон \n'
                              'Столица: Париж \n'
                              'Насиление: 67 848 156 млн человек \n'
                              'Государственный язык: Французкий язык \n'
                              'Площадь страны: 643 801 км² \n'
                              'Валюта: Евро \n'
                              'Подробнее: https://ru.wikipedia.org/wiki/Франция')
    if message.text == 'Испания':
        bot.reply_to(message, 'Местоположения: Юга-Западная Европа и Африка \n'
                              'Президент: Король Филипп VI \n'
                              'Столица: Мадрид \n'
                              'Насиление: 46 714 997 млн человек \n'
                              'Государственный язык: Испанский язык \n'
                              'Площадь страны: 505 990 км² \n'
                              'Валюта: Евро \n'
                              'Подробнее: https://ru.wikipedia.org/wiki/Испания')
    if message.text == 'Италия':
        bot.reply_to(message, 'Местоположения: Южная Европа \n'
                              'Президент: Серджо Маттарелла \n'
                              'Столица: Рим \n'
                              'Насиление: 60 588 366 млн человек \n'
                              'Государственный язык: Итальянский язык \n'
                              'Площадь страны: 301 340 км² \n'
                              'Валюта: Евро \n'
                              'Подробнее: https://ru.wikipedia.org/wiki/Италия')
    if message.text == 'Узбекистан':
        bot.reply_to(message, 'Местоположения: центральная часть Средней Азий \n'
                              'Президент: Шавкат Мирзиёев \n'
                              'Столица: Ташкент \n'
                              'Насиление: 34 036 800 млн человек \n'
                              'Государственный язык: Узбекский язык \n'
                              'Площадь страны: 448 924 км² \n'
                              'Валюта: Сум \n'
                              'Подробнее: https://ru.wikipedia.org/wiki/Узбекистан')
    if message.text == 'Северная Корея':
        bot.reply_to(message, 'Местоположения: Восточная Азия \n'
                              'Президент: Ким Чен Ын \n'
                              'Столица: Пхеньян \n'
                              'Насиление: 25 713 726 млн человек \n'
                              'Государственный язык: Корейский язык \n'
                              'Площадь страны: 120 540 км² \n'
                              'Валюта: Северокорейский Вон \n'
                              'Подробнее: https://ru.wikipedia.org/wiki/Корейская_Народно-Демократическая_Республика')
    if message.text == 'США':
        bot.reply_to(message, 'Местоположения: Северная Америка \n'
                              'Президент: Джо Байден \n'
                              'Столица: Вашингтон \n'
                              'Насиление: 328 915 700 млн человек \n'
                              'Государственный язык: Узбекский язык \n'
                              'Площадь страны: 9 519 431 км² \n'
                              'Валюта: Доллар США \n'
                              'Подробнее: https://ru.wikipedia.org/wiki/Соединённые_Штаты_Америки')
    if message.text == 'Индия':
        bot.reply_to(message, 'Местоположения: Южная Азия \n'
                              'Президент: Рам Натх Ковинд \n'
                              'Столица: Нью-Дели \n'
                              'Насиление: 1 377 388 000 млрд человек \n'
                              'Государственный язык: Хинди, Англиский язык \n'
                              'Площадь страны: 3 287 263 км² \n'
                              'Валюта: Индийская Рупия \n'
                              'Подробнее: https://ru.wikipedia.org/wiki/Индия')
    if message.text == 'Япония':
        bot.reply_to(message, 'Местоположения: Восточная Азия \n'
                              'Президент: Рам Натх Ковинд \n'
                              'Столица: Токио \n'
                              'Насиление: 125 900 000 млн человек \n'
                              'Государственный язык: Японский язык \n'
                              'Площадь страны: 377 944 км² \n'
                              'Валюта: Японская Иена \n'
                              'Подробнее: https://ru.wikipedia.org/wiki/Япония')
    if message.text == 'ОАЭ':
        bot.reply_to(message, 'Местоположения: Ближный Восток \n'
                              'Президент: Халифа ибн Зайд аль-Нахайян \n'
                              'Столица: Абу-Даби \n'
                              'Насиление: 10 207 863 млн человек \n'
                              'Государственный язык: Арабский язык \n'
                              'Площадь страны: 83 600 км² \n'
                              'Валюта: Дирхам ОАЭ \n'
                              'Подробнее: https://ru.wikipedia.org/wiki/Объединённые_Арабские_Эмираты')
    if message.text == 'Германия':
        bot.reply_to(message, 'Местоположения: Центральная Европа \n'
                              'Президент: Франк-Вальтер Штайнмайер \n'
                              'Столица: Берлин \n'
                              'Насиление: 83 019 200 млн человек \n'
                              'Государственный язык: Немецкий язык \n'
                              'Площадь страны: 357 385 км² \n'
                              'Валюта: Евро \n'
                              'Подробнее: https://ru.wikipedia.org/wiki/Германия')
    if message.text == 'Турция':
        bot.reply_to(message, 'Местоположения: Передняя Азия и Южная Европа \n'
                              'Президент: Реджеп Тайип Эрдоган \n'
                              'Столица: Анкара \n'
                              'Насиление: 83 154 997 млн человек \n'
                              'Государственный язык: Турецкий язык \n'
                              'Площадь страны: 783 563 км² \n'
                              'Валюта: Турецкая Лира \n'
                              'Подробнее: https://ru.wikipedia.org/wiki/Турция')
    if message.text == 'Монголия':
        bot.reply_to(message, 'Местоположения: Восточная Азия \n'
                              'Президент: Халтмаагийн Баттулга \n'
                              'Столица: Улан-Батор \n'
                              'Насиление: 3 256 176 млн человек \n'
                              'Государственный язык: Монгольский язык \n'
                              'Площадь страны: 1 564 116 км² \n'
                              'Валюта: Монгольский Тугрик \n'
                              'Подробнее: https://ru.wikipedia.org/wiki/Монголия')
    if message.text == 'Украина':
        bot.reply_to(message, 'Местоположения: Восточная и Центральная Европа \n'
                              'Президент: Владимир Зеленский \n'
                              'Столица: Киев \n'
                              'Насиление: 41 723 998 млн человек \n'
                              'Государственный язык: Украинский язык \n'
                              'Площадь страны: 603 549 км² \n'
                              'Валюта: Гривна \n'
                              'Подробнее: https://ru.wikipedia.org/wiki/Украина')
    if message.text == 'Польша':
        bot.reply_to(message, 'Местоположения: Центральная Азия \n'
                              'Президент: Анджей Дуда \n'
                              'Столица: Варшава \n'
                              'Насиление: 38 313 035 млн человек \n'
                              'Государственный язык: Польский язык \n'
                              'Площадь страны: 312 679 км² \n'
                              'Валюта: Польский Злотый \n'
                              'Подробнее: https://ru.wikipedia.org/wiki/Польша')
    if message.text == 'Швейцария':
        bot.reply_to(message, 'Местоположения: стык Западной, Центральной и Южной Европы \n'
                              'Президент: Симонетта Соммаруга \n'
                              'Столица: отсутствует(Берн) \n'
                              'Насиление: 8 558 758 млн человек \n'
                              'Государственный язык: Немецкий, Итальянский, Французский и Романшский язык \n'
                              'Площадь страны: 41 284 км² \n'
                              'Валюта: Швейцарский Франк \n'
                              'Подробнее: https://ru.wikipedia.org/wiki/Швейцария')
    if message.text == 'Швеция':
        bot.reply_to(message, 'Местоположения: Северная Европа \n'
                              'Президент: Король Карл XVI Густав \n'
                              'Столица: Стокгольм \n'
                              'Насиление: 10 327 589 млн человек \n'
                              'Государственный язык: Шведский язык \n'
                              'Площадь страны: 447 435 км² \n'
                              'Валюта: Шведская Крона \n'
                              'Подробнее: https://ru.wikipedia.org/wiki/Швеция')
    if message.text == 'Чили':
        bot.reply_to(message, 'Местоположения: юго-запад Южной Америки \n'
                              'Президент: Себастьян Пиньера \n'
                              'Столица: Сантьяго \n'
                              'Насиление: 18 186 770 млн человек \n'
                              'Государственный язык: Испанский язык \n'
                              'Площадь страны: 756 102 км² \n'
                              'Валюта: Чилийское Песо \n'
                              'Подробнее: https://ru.wikipedia.org/wiki/Чили')

    #bot.reply_to(message, message.text)


import sublime, sublime_plugin, re, math

class GridMeCommand(sublime_plugin.TextCommand):
	def run(self, edit):
		sels = self.view.sel()
		reg = re.compile("[0-9]+ [0-9]+")
		for sel in sels:
			d1 = int(self.view.substr(sel).split(" ")[0])
			d2 = int(self.view.substr(sel).split(" ")[1])
			strbuilder = "[\r\n"
			for i in range(d1):
				st = "\t["
				for j in range(d2):
					st += "0, "
				strbuilder += st[:-2] + "],\r\n"
			self.view.replace(edit, sel, strbuilder[:-3] + "\r\n]\r\n")


'''
This file contains code to get the original dataset and clean with two procedures:
1) Reomove outliers
2) Balance the training and testing set

This file will create new directory and copy the images to it accordingly

Author: Boyang Wei & Xinyu Zhang
'''

base_tile_dir = 'histopathologic-cancer-detection/train/'
df = pd.DataFrame({'path': glob(os.path.join(base_tile_dir,'*.tif'))})
df['id'] = df.path.map(lambda x: x.split('/')[1].split('\\')[1].split('.')[0])
labels = pd.read_csv("histopathologic-cancer-detection/train_labels.csv")
df_whole = df.merge(labels, on = "id")

#Remove outliers
#All white
whiteList = ['f6f1d771d14f7129a6c3ac2c220d90992c30c10b',
             '9071b424ec2e84deeb59b54d2450a6d0172cf701',
             'c448cd6574108cf14514ad5bc27c0b2c97fc1a83',
             '54df3640d17119486e5c5f98019d2a92736feabc',
             '5f30d325d895d873d3e72a82ffc0101c45cba4a8',
             '5a268c0241b8510465cb002c4452d63fec71028a']
#Ex:
fig = plt.figure(figsize=(5,5))
fig.suptitle('ID: ' + whiteList[0])
img = cv2.imread(base_tile_dir + whiteList[0] + '.tif')
plt.imshow(img)

#All black
blackList = ['9369c7278ec8bcc6c880d99194de09fc2bd4efbe']
#Ex:
fig = plt.figure(figsize=(5,5))
fig.suptitle('ID: ' + blackList[0])
img = cv2.imread(base_tile_dir + blackList[0] + '.tif')
plt.imshow(img)

#Remove outliers from training set
for whiteId in whiteList:
    df_whole = df_whole[df_whole['id'] != whiteId]

for blackId in blackList:
    df_whole = df_whole[df_whole['id'] != blackId]

### Random Sampling of 10000 for both 0 and 1 cases
SAMPLE_SIZE = 10000

#Class 0
df_0 = df_whole[df_whole['label'] == 0].sample(SAMPLE_SIZE, random_state = 101)
#Class 1
df_1 = df_whole[df_whole['label'] == 1].sample(SAMPLE_SIZE, random_state = 101)

# Concat the dataframes
df_data = pd.concat([df_0, df_1], axis=0).reset_index(drop=True)
# Shuffle
df_data = df_data.sample(frac=1).reset_index(drop=True)
# View the numbers in each class
df_data['label'].value_counts()

###############################################################################
# Train and Test
# stratify=y creates a balanced validation set.
y = df_data['label'] #response variable

#Split by 9(df_train)/1(df_val)
df_train, df_val = train_test_split(df_data, test_size=0.10, random_state=101, stratify=y)

print(df_train.shape)
print(df_val.shape)

### Create directory separated from the entire training set
'''
Structure:

- base_dir
    - train_dir
        - no_tumor_tissue
        - has_tumor_tissue
    - val_dir
        - no_tumor_tissue
        - has_tumor_tissue
'''

base_dir = 'histopathologic-cancer-detection/base_dir'
os.mkdir(base_dir)

# train_dir
train_dir = os.path.join(base_dir, 'train_dir')
os.mkdir(train_dir)

# val_dir
val_dir = os.path.join(base_dir, 'val_dir')
os.mkdir(val_dir)

# create new folders inside train_dir
no_tumor_tissue = os.path.join(train_dir, 'a_no_tumor_tissue')
os.mkdir(no_tumor_tissue)
has_tumor_tissue = os.path.join(train_dir, 'b_has_tumor_tissue')
os.mkdir(has_tumor_tissue)

# create new folders inside val_dir
no_tumor_tissue = os.path.join(val_dir, 'a_no_tumor_tissue')
os.mkdir(no_tumor_tissue)
has_tumor_tissue = os.path.join(val_dir, 'b_has_tumor_tissue')
os.mkdir(has_tumor_tissue)

# Set the ID of each image to be the index of table
df_data.set_index('id', inplace=True)

### Transfer train/test images to created folder
# Get a list of train and val images
train_list = list(df_train['id'])
val_list = list(df_val['id'])

# Transfer the training images
for image in train_list:

    # the id in the csv file does not have the .tif extension therefore we add it here
    fname = image + '.tif'
    # get the label for a certain image
    target = df_data.loc[image,'label']

    # these must match the folder names
    if target == 0:
        label = 'a_no_tumor_tissue'
    if target == 1:
        label = 'b_has_tumor_tissue'

    # source path to image
    src = os.path.join('histopathologic-cancer-detection/train/', fname)
    # destination path to image
    dst = os.path.join(train_dir, label, fname)
    # copy the image from the source to the destination
    shutil.copyfile(src, dst)

# Transfer the validation images
for image in val_list:

    # the id in the csv file does not have the .tif extension therefore we add it here
    fname = image + '.tif'
    # get the label for a certain image
    target = df_data.loc[image,'label']

    # these must match the folder names
    if target == 0:
        label = 'a_no_tumor_tissue'
    if target == 1:
        label = 'b_has_tumor_tissue'

    # source path to image
    src = os.path.join('histopathologic-cancer-detection/train/', fname)
    # destination path to image
    dst = os.path.join(val_dir, label, fname)
    # copy the image from the source to the destination
    shutil.copyfile(src, dst)

#Check if the transfer is correct
print('Training image number with no tumor tissues: ' +
      str(len(os.listdir('histopathologic-cancer-detection/base_dir/train_dir/a_no_tumor_tissue'))))
print('Training image number with tumor tissues: ' +
      str(len(os.listdir('histopathologic-cancer-detection/base_dir/train_dir/b_has_tumor_tissue'))))
print('Test image number with tumor tissues: ' +
      str(len(os.listdir('histopathologic-cancer-detection/base_dir/val_dir/b_has_tumor_tissue'))))
print('Test image number with tumor tissues: ' +
      str(len(os.listdir('histopathologic-cancer-detection/base_dir/val_dir/b_has_tumor_tissue'))))


from string import ascii_uppercase,ascii_lowercase,digits,punctuation

# caesar_source.py
##################################################
def encode(plain):
  cipher=''
  for i in plain:
    index=letter.index(i)
    cipher=cipher+letter[(index+14)%len(letter)]
  return cipher

ascii_all=''
for i in range(len(ascii_uppercase)):
  ascii_all=ascii_all+ascii_uppercase[i]+ascii_lowercase[i]
letter=ascii_all+digits+punctuation
##################################################

cflag = open("caesar_output.txt").read()
flag = ""

for _ in range(len(cflag)):
    for i in letter:
        if cflag.startswith(encode(flag + i)):
            print(flag + i)
            flag += i


import datetime

from django.db.models import Avg, Q
from datetime import timedelta
from django.utils import timezone

from celery.task import PeriodicTask
from celery.schedules import crontab

from .models import (
    CarePlan,
    CarePlanResultOverTime
)

from apps.tasks.models import (
    TeamTask,
    AssessmentTask,
    PatientTask,
    MedicationTask,
    SymptomTask,
    VitalTask,
)

class CarePlanResultOverTimeTask(PeriodicTask):
    """
    This periodic task will set an result over time object into the
    model:`CarePlanResultOverTime`
    on a weekly basis.
    """

    # Runs every Monday
    run_every = crontab(minute='0', hour='0', day_of_week='mon')

    def get_outcome(self, plan):
        now = timezone.now()
        date = now.date() - timedelta(days=7)
        tasks = AssessmentTask.objects.filter(
            Q(assessment_template__custom_tracks_outcome=True) |
            (
                Q(assessment_template__custom_tracks_outcome__isnull=True) &
                Q(assessment_template__assessment_task_template__tracks_outcome=True)
            ),
            assessment_template__plan=plan,
            due_datetime__range=[date, now]
        ).aggregate(average=Avg('responses__rating'))
        average = tasks['average'] or 0
        return round((average / 5) * 100)

    def get_engagement(self, plan):
        now = timezone.now()
        date = now.date() - timedelta(days=7)
        patient_tasks = PatientTask.objects.filter(
            patient_template__plan=plan,
            due_datetime__range=[date, now])
        medication_tasks = MedicationTask.objects.filter(
            medication_task_template__plan=plan,
            due_datetime__range=[date, now])
        symptom_tasks = SymptomTask.objects.filter(
            symptom_template__plan=plan,
            due_datetime__range=[date, now])
        assessment_tasks = AssessmentTask.objects.filter(
            assessment_template__plan=plan,
            due_datetime__range=[date, now])
        vital_tasks = VitalTask.objects.filter(
            plan=plan,
            due_datetime__range=[date, now])

        total_patient_tasks = patient_tasks.count()
        total_medication_tasks = medication_tasks.count()
        total_symptom_tasks = symptom_tasks.count()
        total_assessment_tasks = assessment_tasks.count()
        total_vital_tasks = vital_tasks.count()

        completed_patient_tasks = patient_tasks.filter(
            status__in=['missed', 'done']).count()
        completed_medication_tasks = medication_tasks.filter(
            status__in=['missed', 'done']).count()
        completed_symptom_tasks = symptom_tasks.filter(
            is_complete=True).count()
        completed_assessment_tasks = assessment_tasks.filter(
            is_complete=True).count()
        completed_vital_tasks = vital_tasks.filter(
            is_complete=True).count()

        total_completed = (completed_patient_tasks +
                           completed_medication_tasks +
                           completed_symptom_tasks +
                           completed_assessment_tasks +
                           completed_vital_tasks)
        total_tasks = (total_patient_tasks +
                       total_medication_tasks +
                       total_symptom_tasks +
                       total_assessment_tasks +
                       total_vital_tasks)
        return round((total_completed / total_tasks) * 100) \
            if total_tasks > 0 else 0

    def run(self):
        for plan in CarePlan.objects.all():
            CarePlanResultOverTime.objects.create(
                plan=plan,
                outcome=self.get_outcome(plan),
                engagement=self.get_engagement(plan)
            )


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

"""
Fit the polynomial the full-duplex training set
"""

import os
from collections import OrderedDict

import numpy as np
import helpers.signal_processing as sp
import helpers.polynomial_cancellation as poly

from helpers.preprocess import basic_parser, load_data
from helpers.flop import flop_linear_polynomial, flop_convert

import pandas as pd

def fit(params):
    """Fit the polynomial model which includes the IQ mixer.
    """

    ##### Load and prepare data #####
    x, y, noise, measured_noise_power = load_data('data/fdTestbedData' + str(params.sampling_freq_MHz) + 'MHz10dBm', params)

    # Print total number of real parameters to be estimated
    # This number includes the linear as well
    n_poly = int(params.hsi_len * ((params.max_power + 1) / 2) * ((params.max_power + 1) / 2 + 1))
    print("Total number of real parameters to estimate for polynomial based canceller: {:d}".format(2 * n_poly))

    # Split into training and test sets
    training_samples = int(np.floor(x.size * params.training_ratio))

    x_train = x[0:training_samples]
    y_train = y[0:training_samples]
    x_test  = x[training_samples:]
    y_test  = y[training_samples:]

    # Remove samples when training with less samples
    training_samples = int(np.floor(training_samples * params.training_size))

    x_train = x[0: training_samples]
    y_train = y[0: training_samples]

    ##### Training #####
    # Estimate linear and non-linear cancellation parameters
    h_lin    = poly.si_estimation_linear(x_train, y_train, params)
    # This actually also estimates the linear! So we get both
    h_nonlin = poly.si_estimation_nonlinear(x_train, y_train, params)

    ##### Test #####
    # Do linear and non-linear cancellation
    y_canc        = poly.si_cancellation_linear(x_test, h_lin, params)
    # NB: This actually contains the linear cancellation AND the non-linear
    # cancellation.
    y_canc_nonlin = poly.si_cancellation_nonlinear(x_test, h_nonlin, params)

    ##### Evaluation #####
    # Scale signals according to known noise power
    y_test, y_canc, y_canc_nonlin, noise = sp.compute_scaling(noise, measured_noise_power, y_test, y_canc, y_canc_nonlin)

    if params.save:
        path = "results/results_wlmp"
    else:
        path = "results/tmp_wlmp"

    if not os.path.exists(path):
        os.makedirs(path)

    # Plot PSD and get signal powers
    noise_power, y_test_power, y_test_lin_canc_power, y_test_nonlin_canc_power = sp.plotPSD(
        params,
        y_test[params.hsi_len:],
        y_canc[params.hsi_len:],
        y_canc_nonlin[params.hsi_len:],
        noise,
        y_var=1,
        path=path
    )

    # We actually have that it performs the total cancellation!
    # model_canc then refers to the difference in performance between the linear
    # and non-linear canceller (where non-linear includes linear)
    model_canc = y_test_lin_canc_power - y_test_nonlin_canc_power
    # Total cancellation of model
    total_canc = y_test_power - y_test_nonlin_canc_power

    # Complexity (where we subtract the linear! and then we add the linear back later)
    n_cadd = n_poly - params.hsi_len - 1
    n_cmult = n_poly - params.hsi_len

    # Take result in terms of complex-valued additions, multiplications and convert
    # to total real-valued ops.
    model_add, model_mult = flop_convert(n_cadd, n_cmult, algo="reduced_cmult")
    model_act = 0

    model_flop = model_add + model_mult

    total_add  = model_add
    total_mult = model_mult
    total_act  = 0

    lin_add, lin_mult, lin_act = flop_linear_polynomial(params, algo="reduced_cmult")

    total_add  += lin_add + 2
    total_mult += lin_mult
    total_act  += lin_act

    total_flop = total_add + total_mult + total_act

    # Convert to real
    total_params = 2 * n_poly

    data = OrderedDict([
        ('total_flop', total_flop),
        ('total_add', total_add),
        ('total_mult', total_mult),
        ('total_canc_max', total_canc),
        ('total_params', total_params),
        ('model_flop', model_flop),
        ('model_add', model_add),
        ('model_mult', model_mult),
        ('model_act', model_act),
        ('model_canc', model_canc),
        ('training_size', params.training_size),
        ('min_power', params.min_power),
        ('max_power', params.max_power),
    ])

    file_path = path + os.sep + "wlmp.csv"

    df = pd.DataFrame(data, columns=data.keys(), index=[0])

    if os.path.exists(file_path):
        df_restored = pd.read_csv(file_path)

        df = df.append(df_restored)
        df = df.sort_values(by=['total_flop'])

    df.to_csv(file_path, index=False)

def main(params):

    np.random.seed(params.seed)

    if params.search_width:
        for max_power in range(params.min_width, params.max_width + 1, params.step_width):
            print("Max Power", max_power)
            params.max_power = max_power
            fit(params)
    else:
        fit(params)

if __name__ == '__main__':

    parser = basic_parser()
    parser.set_defaults(data_scaled=0)

    params, unknown = parser.parse_known_args()

    if unknown:
        raise ValueError("This argument {} in unknown".format(unknown))

    main(params)


import datetime
import logging
import os

import aiohttp
import naff
from dotenv import load_dotenv
from naff import (
    Extension,
    OptionTypes,
    Permissions,
    PrefixedContext,
    check,
    listen,
    prefixed_command,
    slash_command,
    slash_option,
)
from naff.api.events.discord import MemberAdd, MemberRemove, MessageCreate
from pymongo import MongoClient

from src.utilities import *

load_dotenv()

cluster = MongoClient(os.getenv("MONGODB_URL"))

levelling = cluster["dagelan"]["levelling"]

class levellings(Extension):
    @prefixed_command(name="rank")
    async def pref_rank(self, ctx: PrefixedContext, member: naff.Member = None):
        await rank(self, ctx, member)

    @slash_command("rank", description="Get your rank or another member's rank")
    @slash_option(
        "member",
        "Target @member",
        OptionTypes.USER,
        required=False,
    )
    async def slash_rank(self, ctx, member: naff.Member = None):
        # need to defer it, otherwise, it fails
        await ctx.defer()

        await rank(self, ctx, member)

    @prefixed_command(name="levels")
    async def pref_levels(self, ctx: PrefixedContext):
        await levels(self, ctx)

    @slash_command("levels", description="Get a link to the server's leaderboard")
    async def slash_levels(self, ctx):
        await levels(self, ctx)

    @prefixed_command(name="givexp")
    @check(member_permissions(Permissions.MANAGE_MESSAGES))
    async def pref_givexp(self, ctx, member: naff.Member, amount: int):
        await givexp(self, ctx, member, amount)

    @slash_command(
        name="give-xp",
        description="Give XP to a member",
    )
    @slash_option(
        "member",
        "Target @member",
        OptionTypes.USER,
        required=True,
    )
    @slash_option(
        "amount",
        "Amount of XP to give",
        OptionTypes.INTEGER,
        required=True,
    )
    @check(member_permissions(Permissions.MANAGE_MESSAGES))
    async def slash_givexp(self, ctx, member: naff.Member, amount: int):
        await givexp(self, ctx, member, amount)

    @prefixed_command(name="removexp")
    @check(member_permissions(Permissions.MANAGE_MESSAGES))
    async def pref_removexp(self, ctx, member: naff.Member, amount: int):
        await removexp(self, ctx, member, amount)

    @slash_command(
        name="remove-xp",
        description="Remove XP from a member",
    )
    @slash_option(
        "member",
        "Target @member",
        OptionTypes.USER,
        required=True,
    )
    @slash_option(
        "amount",
        "Amount of XP to remove",
        OptionTypes.INTEGER,
        required=True,
    )
    @check(member_permissions(Permissions.KICK_MEMBERS))
    async def slash_removexp(self, ctx, member: naff.Member, amount: int):
        await removexp(self, ctx, member, amount)

    @listen()
    async def on_member_join(self, event: MemberAdd):
        if event.guild_id == 922523614828433419:
            member = event.member

            if not member.bot:
                stats = levelling.find_one({"id": member.id})
                if stats is not None:
                    levelling.delete_one({"id": member.id})
                    logging.info(
                        f"{member.display_name} has joined the server and they are in database, resetting their stats..."
                    )

    @listen()
    async def on_member_leave(self, event: MemberRemove):
        if event.guild_id == 922523614828433419:
            member = event.member
            stats = levelling.find_one({"id": member.id})
            if stats is not None:
                levelling.delete_one({"id": member.id})
            else:
                logging.info(
                    f"{member.display_name} has left the server, but they were not in the database."
                )

    @listen()
    async def on_message_create(self, event: MessageCreate):
        message = event.message

        if message.guild.id == 922523614828433419:

            # ignore someone
            if message.author.id == 532264079641935883:
                return

            # ignore some message types
            if message.type == 8:
                return
            if message.type == 9:
                return
            if message.type == 10:
                return
            if message.type == 11:
                return
            if message.type == 7:
                return
            if message.type == 6:
                return

            # ignore bot channels
            if message.channel.id == [
                923044276831666177,  # bot-commands
            ]:
                return

            if not message.author.bot:
                await process_xp(self, message)


import datetime
import logging
import os
import subprocess
import typing
import urllib.parse

from dnas.config import config as cfg

class git:
    """
    A class for commiting and pushing files to GitHub.
    """

    @staticmethod
    def add(filename: str = None):
        """
        Add files to the git index, to be commited.
        """
        if not filename:
            raise ValueError(
                f"Missing required arguments: filename={filename}."
            )

        if type(filename) != str:
            raise TypeError(
                f"filename is not a string: {type(filename)}"
            )

        ret = subprocess.run(
            ["git", "add", filename],
            cwd=cfg.GIT_BASE,
            capture_output=True,
        )
        if ret.returncode != 0:
            raise ChildProcessError(
                f"Couldn't add file {filename} to git index:\n"
                f"args: {ret.args}\n"
                f"stdout: {ret.stdout.decode()}\n"
                f"stderr: {ret.stderr.decode()}"
            )
        logging.debug(f"Added {filename} to git index")

    @staticmethod
    def clean():
        """
        Remove any untracked files
        """
        ret = subprocess.run(
            ["git", "clean", "-f"],
            cwd=cfg.GIT_BASE,
            capture_output=True,
        )
        if ret.returncode != 0:
            raise ChildProcessError(
                f"Couldn't git clear -f:\n"
                f"args: {ret.args}\n"
                f"stdout: {ret.stdout.decode()}\n"
                f"stderr: {ret.stderr.decode()}"
            )
        logging.debug(f"Removed untracked fit files in {cfg.GIT_BASE}")

    @staticmethod
    def clear():
        """
        Remove all files currently in the git index for commit.
        """
        ret = subprocess.run(
            ["git", "restore", "--staged", "*"],
            cwd=cfg.GIT_BASE,
            capture_output=True,
        )
        if ret.returncode != 0:
            raise ChildProcessError(
                f"Couldn't clear git index of existing staged entries:\n"
                f"args: {ret.args}\n"
                f"stdout: {ret.stdout.decode()}\n"
                f"stderr: {ret.stderr.decode()}"
            )
        logging.debug(f"Cleared git index in {cfg.GIT_BASE}")

    @staticmethod
    def clone():
        """
        Clone the DNS Stats repo.
        """
        os.makedirs(cfg.GIT_BASE, exist_ok = True)

        ret = subprocess.run(
            ["git", "clone", cfg.GIT_STAT_CLONE_URL],
            cwd=cfg.BASE_DIR,
            capture_output=True,
        )
        if ret.returncode != 0:
            raise ChildProcessError(
                f"Couldn't clone git repo {cfg.GIT_STAT_CLONE_URL} to directory "
                f"{cfg.BASE_DIR}:\n"
                f"args: {ret.args}\n"
                f"stdout: {ret.stdout.decode()}\n"
                f"stderr: {ret.stderr.decode()}"
            )
        logging.debug(
            f"Cloned git repo {cfg.GIT_STAT_CLONE_URL} to {cfg.BASE_DIR}"
        )

    @staticmethod
    def commit(msg: str = None):
        """
        Commit staged changes to git with commit message "msg".
        """
        if not msg:
            raise ValueError(
                f"Missing required arguments: msg={msg}."
            )

        if type(msg) != str:
            raise TypeError(
                f"msg is not a string: {type(msg)}"
            )

        ret = subprocess.run(
            ["git", "commit", "-m", msg],
            cwd=cfg.GIT_BASE,
            capture_output=True,
        )
        if ret.returncode != 0:
            if "Your branch is up to date with" in ret.stdout.decode():
                raise ChildProcessError(
                    "Nothing committed, no changes with remote"
                )
            else:
                raise ChildProcessError(
                    f"Couldn't commit staged changes to git in {cfg.GIT_BASE}\n"
                    f"args: {ret.args}\n"
                    f"stdout: {ret.stdout.decode()}\n"
                    f"stderr: {ret.stderr.decode()}"
                )
        logging.debug(f"Committed to git in {cfg.GIT_BASE}: {msg}")

    @staticmethod
    def diff():
        """
        Return True if there are files in the git index, with uncommitted
        changes, else False.
        """
        ret = subprocess.run(
            ["git", "diff", "--cached"],
            cwd=cfg.GIT_BASE,
            capture_output=True,
        )
        if ret.returncode != 0:
            raise ChildProcessError(
                f"Couldn't check if git has staged changed:\n"
                f"args: {ret.args}\n"
                f"stdout: {ret.stdout.decode()}\n"
                f"stderr: {ret.stderr.decode()}"
            )
        if ret.stdout.decode() == "":
            logging.debug(f"No changes staged in git cache in {cfg.GIT_BASE}")
            return False
        else:
            logging.debug(
                f"Changes are staged git in cache in {cfg.GIT_BASE}")
            return True

    @staticmethod
    def git_exists():
        """
        Return True if DNAS Stats repo exists locally.
        """
        if not os.path.isdir(cfg.GIT_BASE):
            logging.debug(f"Local git directory doesn't exist: {cfg.GIT_BASE}")
            return False

        ret = subprocess.run(
            ["git", "status"],
            cwd=cfg.GIT_BASE,
            capture_output=True,
        )
        if ret.returncode != 0:
            logging.debug(f"No git repo detected in {cfg.GIT_BASE}")
            return False

        logging.debug(f"Git repo found in {cfg.GIT_BASE}")
        return True

    @staticmethod
    def gen_git_path_ymd(ymd: str = None) -> str:
        """
        Generate and return the path to the report files for a specific date.
        """
        if not ymd:
            raise ValueError(
                f"Missing required arguments: ymd={ymd}."
            )

        if type(ymd) != str:
            raise TypeError(
                f"ymd is not a string: {type(ymd)}"
            )

        day = datetime.datetime.strptime(ymd, cfg.DAY_FORMAT)

        git_dir = os.path.join(cfg.GIT_BASE, str(day.year))
        git_dir = os.path.join(git_dir, f"{day.month:02}")
        git_dir = os.path.join(git_dir, f"{day.day:02}")

        return git_dir

    @staticmethod
    def gen_git_url_ymd(ymd: str = None) -> str:
        """
        Generate and return the URL to the report files for a specific date.
        """
        if not ymd:
            raise ValueError(
                f"Missing required arguments: ymd={ymd}."
            )

        if type(ymd) != str:
            raise TypeError(
                f"ymd is not a string: {type(ymd)}"
            )

        day = datetime.datetime.strptime(ymd, cfg.DAY_FORMAT)

        git_url = os.path.join(str(day.year), f"{day.month:02}")
        git_url = os.path.join(git_url, f"{day.day:02}")
        git_url = urllib.parse.urljoin(cfg.GIT_STAT_BASE_URL, git_url)

        return git_url

    @staticmethod
    def pull():
        """
        Perform a git pull to make sure the local repo is up to date
        """
        ret = subprocess.run(
            ["git", "pull"],
            cwd=cfg.GIT_BASE,
            capture_output=True,
        )
        if ret.returncode != 0:
            raise ChildProcessError(
                f"Couldn't pull from remote branch "
                f"{cfg.GIT_REPORT_BRANCH}\n"
                f"args: {ret.args}\n"
                f"stdout: {ret.stdout.decode()}\n"
                f"stderr: {ret.stderr.decode()}"
            )
        logging.debug(
            f"Git pull succeeded"
        )

    @staticmethod
    def push():
        """
        Push commits to GitHub.
        """
        ret = subprocess.run(
            ["git", "push", "origin", cfg.GIT_REPORT_BRANCH],
            cwd=cfg.GIT_BASE,
            capture_output=True,
        )
        if ret.returncode != 0:
            raise ChildProcessError(
                f"Couldn't push commits to remote branch "
                f"{cfg.GIT_REPORT_BRANCH}\n"
                f"args: {ret.args}\n"
                f"stdout: {ret.stdout.decode()}\n"
                f"stderr: {ret.stderr.decode()}"
            )
        logging.debug(
            f"Pushed commit(s) to remote branch {cfg.GIT_REPORT_BRANCH}"
        )


from django.core.files.storage import default_storage
from time import time
import traceback
import sys
import cPickle as pickle
import zlib

'''pickle and compress obj'''
def pickle_zdumps(obj):
	return zlib.compress(pickle.dumps(obj,pickle.HIGHEST_PROTOCOL),9)

'''unpickle and decompress obj'''
def pickle_zloads(zstr):
	return pickle.loads(zlib.decompress(zstr))

def run():
	filenumber_start = 747
	filenumber_stop = 797

	path = "scripts/pubmed_matrices/pubmed_0%s_0%s_rawA.pkl" % (str(filenumber_start), str(filenumber_stop))
	file = open(path,'rb')
	rawA = pickle_zloads(file.read())
	file.close()
	path = "matrices/pubmed/pubmed_0%s_0%s_rawA.pkl" % (str(filenumber_start), str(filenumber_stop))
	file = default_storage.open(path,'wb')
	file.write(pickle_zdumps(rawA))
	file.close()

	path = "scripts/pubmed_matrices/pubmed_0%s_0%s_bigA.pkl" % (str(filenumber_start), str(filenumber_stop))
	file = open(path,'rb')
	bigA = pickle_zloads(file.read())
	file.close()
	path = "matrices/pubmed/pubmed_0%s_0%s_bigA.pkl" % (str(filenumber_start), str(filenumber_stop))
	file = default_storage.open(path,'wb')
	file.write(pickle_zdumps(bigA))
	file.close()


import tkinter as tk

window = tk.Tk()
window.title("Calculator")
canvas = tk.Canvas(height = 350 ,width = 400)
canvas.pack()
white_frame = tk.Frame(window, bg = "#4A525A")
white_frame.place(relheight = 5, relwidth = 7)

operation = None

def clear_func():
    current = e.get()
    e.delete(0,  len(current))

def button_click(number):
    global current
    current = e.get()
    e.delete(0,  len(current))
    e.insert(0, str(current) + str(number))

def button_add():
    global num1
    current = e.get()
    num1 = float(e.get())
    e.delete(0,  len(current) + 1)
    global operation
    operation = "add"

def button_sub():
    global num1
    current = e.get()
    if len(current)>=1:
        num1 = float(e.get())
        e.delete(0,  len(current) + 1)
        global operation
        operation = "subtract"
    if len(current) < 1:
        e.insert(0, "-")

def button_mult():
    global num1
    current = e.get()
    num1 = float(e.get())
    e.delete(0,  len(current) + 1)
    global operation
    operation = "multiply"

def button_div():
    global num1
    current = e.get()
    num1 = float(e.get())
    e.delete(0,  len(current) + 1)
    global operation
    operation = "div"

# def button_neg():
#    w e.insert(0, "-")
def equals_func():
    if e.get() != "" and operation != None:
        num2 = float(e.get())
        e.delete(0,  len(current) + 100)
        if operation == "add":
            e.insert(0, float(num1)+float(num2))
        elif operation == "subtract":
            e.insert(0, float(num1)-float(num2))
        elif operation == "multiply":
            e.insert(0, float(num1)*float(num2))
        else:
            e.insert(0, float(num1)/float(num2))

e = tk.Entry(white_frame, width = 46, bg = "#F4F4F9")
e.place(y = 50, x = 60, height = 30)

num_button_1 = tk.Button(white_frame, text = "1", command = lambda: button_click(1), bg = "#010400", fg = "white", font = "Algerian")
num_button_1.place(width = 70, x = 60, height = 60, y = 200)

num_button_2 = tk.Button(white_frame, text = "2", command = lambda: button_click(2), bg = "#010400", fg = "white", font = "Algerian")
num_button_2.place(y = 200,x = 130, width = 70, height = 60)

num_button_3 = tk.Button(white_frame, text = "3", command = lambda: button_click(3), bg = "#010400", fg = "white", font = "Algerian")
num_button_3.place(y = 200,x = 200, width = 70, height = 60)

num_button_4 = tk.Button(white_frame, text = "4", command = lambda: button_click(4), bg = "#010400", fg = "white", font = "Algerian")
num_button_4.place(width = 70, x = 60, height = 60, y = 140)

num_button_5 = tk.Button(white_frame, text = "5", command = lambda: button_click(5), bg = "#010400", fg = "white", font = "Algerian")
num_button_5.place(y = 140,x = 130, width = 70, height = 60)

num_button_6 = tk.Button(white_frame, text = "6", command = lambda: button_click(6), bg = "#010400", fg = "white", font = "Algerian")
num_button_6.place(y = 140,x = 200, width = 70, height = 60)

num_button_7 = tk.Button(white_frame, text = "7", command = lambda: button_click(7), bg = "#010400", fg = "white", font = "Algerian")
num_button_7.place(width = 70, x = 60, height = 60, y = 80)

num_button_8 = tk.Button(white_frame, text = "8", command = lambda: button_click(8), bg = "#010400", fg = "white", font = "Algerian")
num_button_8.place(y = 80,x = 130, width = 70, height = 60)

num_button_9 = tk.Button(white_frame, text = "9", command = lambda: button_click(9), bg = "#010400", fg = "white", font = "Algerian")
num_button_9.place(y = 80,x = 200, width = 70, height = 60)

num_button_0 = tk.Button(white_frame, text = "0", command = lambda: button_click(0), bg = "#010400", fg = "white", font = "Algerian")
num_button_0.place(y = 260,x = 130, width = 70, height = 60)

clear_button = tk.Button(white_frame, text = "Clear", command = clear_func, bg = "#24272B", font = "Pacifico")
clear_button.place(width = 70, x = 60, height = 60, y = 260)

equals_button = tk.Button(white_frame, text = "=", command = equals_func, bg = "#247BA0", font = "Algerian")
equals_button.place(y = 260,x = 200, width = 70, height = 60)

div_button = tk.Button(white_frame, text = "÷", command = button_div, font = "Pacifico")
div_button.place(y = 80,x = 270, width = 70, height = 60)

multiplication_button = tk.Button(white_frame, text = "x", command = button_mult, font = "Pacifico")
multiplication_button.place(y = 140,x = 270, width = 70, height = 60)

addition_button = tk.Button(white_frame, text = "+", command = button_add, font = "Pacifico")
addition_button.place(y = 200,x = 270, width = 70, height = 60)

minus_button = tk.Button(white_frame, text = "-", command = button_sub, font = "Pacifico")
minus_button.place(y = 260,x = 270, width = 70, height = 60)

# neg_num_button = tk.Button(white_frame, text = "Negative", command = button_neg, font = "Impact")
# neg_num_button.place(y = 5,x = 60, width = 280, height = 45)

window.mainloop()


import os
import shutil
import sys

from react_cli import ROOT_PATH
from react_cli import _build_html, build_app, _copy_python_assets, _resolve_imports

def test_build_app():
    build_app()
    _assert_is_not_template()

def test_build_html():
    _build_html()
    _assert_is_not_template()
    _assert_has_files_in_py_env()

def _assert_is_not_template():
    with open(os.path.join(ROOT_PATH, "build", "index.html"), "r") as f:
        content = f.read()
        assert "{{" not in content
        assert "}}" not in content
        assert "{%" not in content
        assert "%}" not in content

def _assert_has_files_in_py_env():
    src_path = os.path.join(ROOT_PATH, "src")
    with open(os.path.join(ROOT_PATH, "build", "index.html"), "r") as f:
        html_content = f.read()
        for root, dirs, files in os.walk(src_path):
            for file in files:
                if ".py" in file[-3:]:
                    src_relpath = os.path.join(os.path.relpath(root, start=src_path), file)
                    assert src_relpath in html_content

def test__copy_python_assets():
    _copy_python_assets()

    src_files = []
    for root, dirs, files in os.walk(os.path.join(ROOT_PATH, "src")):
        src_files += list(files)

    build_files = []
    for root, dirs, files in os.walk(os.path.join(ROOT_PATH, "build")):
        build_files += files

    for file in src_files:
        assert file in build_files

def test__resolve_imports():
    imports = _resolve_imports()
    assert len(imports) > 0
    assert all(".py" in path[-3:] for path in imports)
    assert all(os.path.exists(os.path.join(ROOT_PATH, "src", path)) for path in imports)
    pass


import sys
sys.stdin = open('문자열 비교.txt')

TC = int(input())
for tc in range(1, TC+1):
    base = list(input())
    text = list(input())

    res = 0
    for x in range(len(text)-len(base)+1):
        cnt = 0
        for y in range(len(base)):
            if text[x+y] == base[y]:
                cnt += 1
            else:
                cnt = 0
        if cnt == len(base):
            res = 1

    print('#{} {}'.format(tc, res))


import pandas

from django.db import migrations

from api.models import Tweet, Sentiment

def populate_tweets_with_sentiments(_, __):
    cols = ['sentiment', 'id', 'date', 'query_string', 'user', 'content']
    dataframe = pandas.read_csv('./data_processing/data/training_data.16000.csv',header=None, names=cols, encoding = "ISO-8859-1", low_memory=False)

    # removes unnecessary columns
    dataframe.drop(['date', 'query_string', 'user', 'content'],axis=1, inplace=True)

    for i in range(0, dataframe['id'].count()):
        tweet = Tweet.objects.get(pk=dataframe.loc[i, 'id'])
        tweet.sentiment_id = dataframe.loc[i, 'sentiment']
        tweet.save()

def undo_populate_tweets_with_sentiments(_, __):
    tweets = Tweet.objects.all()

    for tweet in tweets:
        tweet.sentiment_id = -1
        tweet.save()

class Migration(migrations.Migration):

    dependencies = [
        ("api", "0009_add_word_frequency")
    ]
    operations = [
        migrations.RunPython(
            populate_tweets_with_sentiments,
            undo_populate_tweets_with_sentiments
        ),
    ]


def leia_int(s):
    while True:
        n = input(f'{s}: ')
        if not n.isdigit():
            print('\n\033[1;31mERRO! Não é um número! Tente novamente!\033[m\n')
        else:
            print(f'Voce digitou o número {n}.')
            break

def main():
    leia_int('Digite un número')

if __name__ == '__main__':
    main()


from cs50 import get_float

while True:
    try:
        change = get_float("Change: ")
        if change > 0:
            break
        else:
            print("Invalid input")
    except ValueError:
        print("Invalid input")

change = round(change * 100)

coins = 0

while change > 0:
    if change >= 25:
        change = change - 25
        coins = coins + 1
    elif change >= 10:
        change = change - 10
        coins = coins + 1
    elif change >= 5:
        change = change - 5
        coins = coins + 1
    elif change >= 1:
        change = change - 1
        coins = coins + 1

print(coins)


# import colorgram
# colors = colorgram.extract('image.jpeg', 10)
# colors_list = []
# for color in colors:
#     colors_list.append(color)
#
# print(colors_list)
# color_rgb = []
#
# for each in colors_list:
#     r = each.rgb.r
#     g = each.rgb.g
#     b = each.rgb.b
#     new_color = r,g,b
#     color_rgb.append(new_color)
#
# print(color_rgb)

import turtle as t
from turtle import Turtle, Screen
import random

timmy = t.Turtle()
t.colormode(255)

color_list = [(192, 163, 119), (126, 185, 156), (213, 213, 132),
              (187, 222, 201), (155, 212, 186), (137, 168, 182),
              (220, 217, 177), (181, 141, 159), (91, 155, 110),
              (145, 149, 76)]

a = 1
b = 500

# changing speed of turtle
timmy.speed("fastest")

# making patten
while b:
    # makes the turtle to move forward
    timmy.forward(a)

    # makes the turtle to move left
    timmy.left(121)
    timmy.left(1)
    a += 1
    b -= 1

# a = 20
# timmy.speed("fastest")
# for each in range(1, 100):
#     timmy.left(5)
#     timmy.circle(each, 360, 3)
#
# timmy.left(120)
# for each in range(1, 100):
#     timmy.left(5)
#     timmy.circle(each, 360, 3)

# for each in range(1, 100):
#     timmy.left(5)
#     for _ in range(1, 4):
#         timmy.forward(a)
#         timmy.left(120)
#         a = a + 1

# Different graphics
# timmy.width(1)
# timmy.speed("fastest")
# for each in range(20, 70):
#     timmy.pencolor("black")
#     timmy.circle(each, 360, 3)
#     timmy.left(5)
#
# timmy.setx(0)
# timmy.sety(0)
# timmy.left(60)
# for each in range(20, 70):
#     timmy.pencolor("black")
#     timmy.circle(each, 360, 3)
#     timmy.left(5)
#
# timmy.setx(0)
# timmy.sety(0)
# timmy.left(60)
# for each in range(20, 70):
#     timmy.pencolor("black")
#     timmy.circle(each, 360, 3)
#     timmy.left(5)

# Hirst Painting code

# timmy.penup()
# timmy.hideturtle()
# timmy.sety(300)
#
# for _ in range(1, 11):
#     timmy.setx(-300)
#     y = timmy.ycor()
#     timmy.sety(y - 50)
#     for _ in range(1, 11):
#         timmy.forward(50)
#         timmy.dot(20, random.choice(color_list))

screen = Screen()
screen.exitonclick()


import sys
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
from MaquinaTuring import turing_machine

def check_input():
    input_string = input_entry.get()
    if turing_machine(input_string):
        messagebox.showinfo("Resultado", "La cadena es válida según las reglas de la máquina de Turing.")
    else:
        messagebox.showerror("Resultado", "La cadena no es válida según las reglas de la máquina de Turing.")

def close_window():
    sys.exit()

def clear_text():
    input_entry.delete(0, 'end')

# Crear la ventana principal
root = tk.Tk()
root.iconbitmap('D:/PIA Teoria de automatas/icono/pochita.ico')
root.title("Máquina de Turing")
root.geometry("600x300")

# Cambiar el color de fondo y el contorno de la ventana
root.configure(bg="#F0F0F0", bd=5, relief="solid")

# Estilos
label_style = {"font": ("Arial", 12), "bg": "#F0F0F0"}

# Crear los widgets
text_label1 = tk.Label(root, text="Producto Integrado de Aprendizaje Teoria de Automatas", **label_style)
text_label2 = tk.Label(root, text="Pablo Tadeo Capistran Fernandez Matricula 1971973", **label_style)
input_label = tk.Label(root, text="Ingresa una cadena para verificar:", **label_style)
input_entry = ttk.Entry(root, width=40)
check_button = ttk.Button(root, text="Verificar", command=check_input)
clear_button = ttk.Button(root, text="Limpiar", command=clear_text)
close_button = ttk.Button(root, text="Cerrar", command=close_window)

# Aumentar el tamaño de los botones
check_button.configure(width=20)
clear_button.configure(width=20)
close_button.configure(width=20)

# Posicionar los widgets en la ventana usando grid
text_label1.grid(row=0, column=0, columnspan=2, pady=10)
text_label2.grid(row=1, column=0, columnspan=2)
input_label.grid(row=2, column=0, pady=10, sticky=tk.E)
input_entry.grid(row=2, column=1, pady=10, sticky=tk.W)
check_button.grid(row=3, column=0, pady=10)
clear_button.grid(row=3, column=1, pady=10)
close_button.grid(row=4, column=0, columnspan=2, pady=5)

# Ajustar el tamaño de las columnas
root.columnconfigure(0, weight=1)
root.columnconfigure(1, weight=1)

# Iniciar el bucle de eventos
root.mainloop()