import numpy as np
from Ui_Files.Dialogs.line_dialog import Ui_Dialog as vhline_ui
from Ui_Files.Dialogs.axis_setup_dialog import Ui_Dialog as axis_setup_ui
from Ui_Files.Dialogs.Save_To_CSV import Ui_Dialog as STC_ui
from Ui_Files.Dialogs.app_settings import Ui_Dialog as app_settings
from Ui_Files.Dialogs.annotation_dialog import Ui_Dialog as annotation_ui
from Ui_Files.Dialogs.new_project_dialog import Ui_Dialog as new_project_dialog
from Ui_Files.Dialogs.simple_treeWidget_dialog import Ui_Dialog as simple_tw
from Ui_Files.Dialogs.bargraph_dialog import Ui_Dialog as bar_dialog
from Ui_Files.Dialogs.spine_color_dialog import Ui_Dialog as spine_color_dialog
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.pyplot import figure
import matplotlib
from matplotlib.widgets import SpanSelector
import pickle
from matplotlib.text import Text
import pandas as pd
from PySide2 import QtCore,QtWidgets
from shutil import copytree, copy2
import os
import seaborn as sns
from gui_elements.settings import ApplicationSettings
from scipy import sparse
from scipy.sparse.linalg import spsolve

def spine_color_fun(self):
    def finish():
        self.ax.spines['bottom'].set_color(ui.bspine_cb.currentText())
        self.ax.spines['top'].set_color(ui.tspine_cb.currentText())
        self.ax.spines['right'].set_color(ui.rspine_cb.currentText())
        self.ax.spines['left'].set_color(ui.lspine_cb.currentText())
        self.ax.xaxis.label.set_color(ui.bspine_cb.currentText())
        self.ax.yaxis.label.set_color(ui.lspine_cb.currentText())
        self.ax.tick_params(axis='x', colors=ui.bspine_cb.currentText())
        self.ax.tick_params(axis='y', colors=ui.lspine_cb.currentText())
        self.settings.setValue('top_spine_color',ui.tspine_cb.currentText())
        self.settings.setValue('bottom_spine_color', ui.bspine_cb.currentText())
        self.settings.setValue('left_spine_color', ui.lspine_cb.currentText())
        self.settings.setValue('right_spine_color', ui.rspine_cb.currentText())
        if self.ax_2 is not None:
            self.ax_2.tick_params(axis='y', colors=ui.rspine_cb.currentText())
            self.ax_2.yaxis.label.set_color(ui.rspine_cb.currentText())
        self.canvas.draw()
    dialog = QtWidgets.QDialog()
    ui = spine_color_dialog()
    ui.setupUi(dialog)
    colors = ['black','red','blue','green','purple','orange','yellow','white']
    ui.bspine_cb.addItems(colors)
    ui.bspine_cb.setCurrentText(self.settings.value('bottom_spine_color'))
    ui.tspine_cb.addItems(colors)
    ui.tspine_cb.setCurrentText(self.settings.value('top_spine_color'))
    ui.lspine_cb.addItems(colors)
    ui.lspine_cb.setCurrentText(self.settings.value('left_spine_color'))
    ui.rspine_cb.addItems(colors)
    ui.rspine_cb.setCurrentText(self.settings.value('right_spine_color'))

    ui.buttonBox.accepted.connect(lambda: finish())
    dialog.exec_()

def graph_test_fun(self):
    self.ax.set_xlim(0,200)
    print(self.ax_2.get_xlim())
    print(self.ax.get_ylim())
    self.ax.autoscale()
    self.n

def tight_figure(self):
    self.fig.tight_layout()
    self.canvas.draw()

def clearimage(self):
    from PIL import Image
    img = Image.open(r'C:\Users\austi\Desktop\image2.png')
    img = img.convert("RGBA")
    datas = img.getdata()

    newData = []
    for item in datas:
        if item[0] == 255 and item[1] == 255 and item[2] == 255:
            newData.append((255, 255, 255, 0))
        else:
            newData.append(item)

    img.putdata(newData)
    img.save(r"C:\Users\austi\Desktop\img2.png", "PNG")

def save_fig(self):
    if self.pickle_opened.text() == 'None':
        filename = QtWidgets.QFileDialog.getSaveFileName(
            None, 'Save Figure', self.settings.value('FIG_PATH'), "pickle (*.pkl);;All Files (*)")
        if filename[0] == '':
            print('passed')
        else:
            with open(filename[0], 'wb') as fid:
                try:
                    pickle.dump(self.fig, fid)
                except TypeError:
                    msg = QtWidgets.QMessageBox()
                    msg.setText("Can't save FigureCanvasQtAgg object")
            msg = QtWidgets.QMessageBox()
            msg.setText('Saved as: ' + filename[0])
            msg.exec_()
    else:
        filename = QtWidgets.QFileDialog.getSaveFileName(
            None, 'Save Figure', self.pickle_opened.text(), "pickle (*.pkl);;All Files (*)")
        if filename[0] == '':
            print('passed')
        else:
            with open(filename[0], 'wb') as fid:
                try:
                    pickle.dump(self.fig, fid)
                    self.pickle_opened.setText(filename[0])
                except TypeError:
                    msg = QtWidgets.QMessageBox()
                    msg.setText("Can't save FigureCanvasQtAgg object")
            msg = QtWidgets.QMessageBox()
            msg.setText('Saved as: ' + filename[0])
            msg.exec_()

def show_pickled_fig(self):
    self.cleargraph()
    if self.pickle_opened.text() == 'None':
        path,ext = QtWidgets.QFileDialog.getOpenFileName(self, 'Pickeled Figure', self.settings.value('FIG_PATH'))
        self.pickle_opened.setText(path)
    else:
        # print(self.pickle_opened.text())
        path, ext = QtWidgets.QFileDialog.getOpenFileName(self, 'Pickeled Figure', self.pickle_opened.text())
        self.pickle_opened.setText(path)
    if path == '':
        self.pickle_opened.setText('None')
    else:
        with open(path, 'rb') as fid:
            try:
                figx = pickle.load(fid)
            except EOFError:
                msg = QtWidgets.QMessageBox()
                msg.setText('There was a problem saving this so there is nothing to load')
                msg.exec_()
        try:
            ApplicationSettings.ALL_DATA_PLOTTED = {}
            self.canvas.draw()
            self.ui.verticalLayout.removeWidget(self.toolbar)
            self.toolbar.close()
            self.ui.verticalLayout.removeWidget(self.canvas)
            self.canvas.close()
            del self.fig
            del self.canvas
            del self.toolbar
            sns.set(context=self.context, style=self.style, palette=self.c_palette,
                    font=self.font, font_scale=self.fs, color_codes=True)
            self.fig = figx
            print(self.fig.axes)
            for num, ax in enumerate(self.fig.axes):
                if num == 0:
                    self.ax_1 = ax
                    self.ax = self.ax_1
                elif num == 1:
                    self.ax_2 = ax
                elif num == 2:
                    self.ax_3 = ax
                elif num == 3:
                    self.ax_4 = ax
                elif num == 4:
                    self.ax_5 = ax
                elif num == 5:
                    self.ax_6 = ax
                elif num == 6:
                    self.ax_7 = ax
                elif num == 7:
                    self.ax_8 = ax
                elif num == 8:
                    self.ax_9 = ax
                elif num == 9:
                    self.ax_10 = ax
                for i in ax.lines:
                    ApplicationSettings.ALL_DATA_PLOTTED[str(i)] = i
                for i in ax.texts:
                    ApplicationSettings.ALL_DATA_PLOTTED[str(i)] = i
                for i in ax.collections:
                    ApplicationSettings.ALL_DATA_PLOTTED[str(i)] = i
                # print(ax)
                # if ax is not self.ax_1 and ax is not self.ax_2:
                #     print('axes2')
                #     print(ax)
                #     self.ax_2 = ax
                #     for i in self.ax_2.lines:
                #         ApplicationSettings.ALL_DATA_PLOTTED[str(i)] = i
                #     for i in self.ax_2.texts:
                #         ApplicationSettings.ALL_DATA_PLOTTED[str(i)] = i
                #     for i in self.ax_2.collections:
                #         ApplicationSettings.ALL_DATA_PLOTTED[str(i)] = i
                # elif ax is not self.ax_1 and ax is not self.ax_2 and ax is not self.ax_3:
                #     print('axes3')
                #     print(ax)
                #     self.ax_3 = ax
                #     for i in self.ax_3.lines:
                #         ApplicationSettings.ALL_DATA_PLOTTED[str(i)] = i
                #     for i in self.ax_3.texts:
                #         ApplicationSettings.ALL_DATA_PLOTTED[str(i)] = i
                #     for i in self.ax_3.collections:
                #         ApplicationSettings.ALL_DATA_PLOTTED[str(i)] = i
                # elif ax is not self.ax_1 and ax is not self.ax_2 and ax is not self.ax_3:
                #     print('axes4')
                #     print(ax)
                #     self.ax_4 = ax
                #     for i in self.ax_4.lines:
                #         ApplicationSettings.ALL_DATA_PLOTTED[str(i)] = i
                #     for i in self.ax_4.texts:
                #         ApplicationSettings.ALL_DATA_PLOTTED[str(i)] = i
                #     for i in self.ax_4.collections:
                #         ApplicationSettings.ALL_DATA_PLOTTED[str(i)] = i
                # else:
                #     print('no home')
                #     print(ax)
            self.canvas = FigureCanvas(self.fig)
            self.toolbar = NavigationToolbar(self.canvas, self.canvas, coordinates=True)
            self.ui.verticalLayout.addWidget(self.toolbar)
            self.ui.verticalLayout.addWidget(self.canvas)
            self.canvas.installEventFilter(self)
            self.ax.callbacks.connect('xlim_changed', self.lims_change)
            self.ax.callbacks.connect('ylim_changed', self.lims_change)
            self.dragh = DragHandler(self, figure=self.fig)
            self.canvas.draw()

        except UnboundLocalError:
            msg = QtWidgets.QMessageBox()
            msg.setText('Press "Ctrl+1" for a new axes')
            msg.exec_()
# def Project_view_fun(self):
#     self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.dw_ProjectView)
#     self.restoreDockWidget(self.dw_ProjectView)
#     self.dw_ProjectView.show()
#
#
# def DataBrowser_view_fun(self):
#     self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.dw_Data_Broswer)
#     self.restoreDockWidget(self.dw_Data_Broswer)
#     self.dw_Data_Broswer.show()

def XPS_view_fun(self):
    self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.dw_XPS)
    self.restoreDockWidget(self.dw_XPS)
    self.dw_XPS.show()

def FTIR_view_fun(self):
    self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.dw_FTIR)
    self.restoreDockWidget(self.dw_FTIR)
    self.dw_FTIR.show()

def QCM_view_fun(self):
    self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.dw_QCM)
    self.restoreDockWidget(self.dw_QCM)
    self.dw_QCM.show()

def XRD_view_fun(self):
    self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.dw_XRD)
    self.restoreDockWidget(self.dw_XRD)
    self.dw_XRD.show()

def SE_view_fun(self):
    self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.dw_SE)
    self.restoreDockWidget(self.dw_SE)
    self.dw_SE.show()

def CF_view_fun(self):
    self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.dw_CF)
    self.restoreDockWidget(self.dw_CF)
    self.dw_CF.show()

def Console_view_fun(self):
    pass
    # import sys
    #
    # from qtpy.QtWidgets import QApplication
    # from pyqtconsole.console import PythonConsole
    #
    # def greet():
    #     print("hello world")
    #
    # if __name__ == '__main__':
    #     appl = QApplication([])
    #
    #     console = PythonConsole()
    #     console.push_local_ns('greet', greet)
    #     console.show()
    #     console.eval_in_thread()
    #     sys.exit(appl.exec_())
    # self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.dw_Console)
    # self.restoreDockWidget(self.dw_Console)
    # self.dw_Console.show()

def Calc_view_fun(self):
    self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.dw_calc)
    self.restoreDockWidget(self.dw_calc)
    self.dw_calc.show()

def toggle_legend(self):
    if self.ax.get_legend() is None:
        items = ('medium','xx-small','x-small','small','large','x-large','xx-large')
        size, ok = QtWidgets.QInputDialog.getItem(self, "Legend",
                                        "size", items, 0, False)
        if ok:
            items_2 = ('best', 'upper right', 'upper left', 'lower left', 'lower right', 'right', 'center left',
                       'center right', 'lower center', 'upper center', 'center')
            pos, ok_1 = QtWidgets.QInputDialog.getItem(self, "Legend",
                                                       "position", items_2, 0, False)
            if ok_1:
                all, ok_2 = QtWidgets.QInputDialog.getItem(self, "Legend",
                                                           "Combine all Axis Legends? ", ('No','Yes'), 0, False)
                if ok_2:
                    if all == 'Yes':
                        try:
                            lines_1, labels_1 = self.ax.get_legend_handles_labels()
                            lines_2, labels_2 = self.ax_2.get_legend_handles_labels()
                            print(labels_2)
                            lines = lines_1 + lines_2
                            labels = labels_1 + labels_2
                            self.ax.legend(lines, labels, loc=pos, fontsize = size)
                        except AttributeError:
                            self.ax.legend(loc=pos, fontsize=size)
                    else:
                        self.ax.legend(loc=pos, fontsize=size)
    else:
        self.ax.get_legend().remove()
    self.canvas.draw()

def Save_All_Plotted(self):

    def temp():
        temp = []
        for ix in ui.treeWidget.selectedIndexes():
            text = ix.data()
            temp.append(text)
            name = os.path.join(self.settings.value('SAVED_DATA_PATH'),ix.data())
            try:
                np.savetxt(str(name)+ui.save_as_LE.text()+ui.comboBox.currentText(),
                           ApplicationSettings.ALL_DATA_PLOTTED[ix.data()][0]._xy,delimiter=',')
            except TypeError:
                np.savetxt(str(name) + ui.save_as_LE.text() + ui.comboBox.currentText(),
                           ApplicationSettings.ALL_DATA_PLOTTED[ix.data()]._xy, delimiter=',')
    dialog = QtWidgets.QDialog()
    ui = STC_ui()
    ui.setupUi(dialog)
    dict = ApplicationSettings.ALL_DATA_PLOTTED
    Key_List = []
    for i in dict.keys():
        Key_List.append(QtWidgets.QTreeWidgetItem([i]))
    ui.treeWidget.addTopLevelItems(Key_List)
    ui.buttonBox.accepted.connect(lambda: temp())
    ui.treeWidget.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
    dialog.exec_()

def recoup_data(self):
    dict = ApplicationSettings.ALL_DATA_PLOTTED
    data = []
    x_label = self.ax.get_xlabel()
    y_label = self.ax.get_ylabel()
    for i in dict.keys():
        if type(dict[i]) == list:
            try:
                data.append(dict[i][0]._xy.T)
            except IndexError:
                pass
        else:
            try:
                data.append(dict[i]._xy.T)
            except IndexError:
                pass
    self.cleargraph()

def remove_line(self):
    def finish():
        for j in ui.treeWidget.selectedIndexes():
            line = ApplicationSettings.ALL_DATA_PLOTTED[j.data()]
            print(type(line))
            if isinstance(line, list):
                try:
                    self.ax.lines.remove(line[0])
                    ApplicationSettings.ALL_DATA_PLOTTED.pop(j.data())
                    del line
                    self.canvas.draw()
                except ValueError:
                    msg = QtWidgets.QMessageBox()
                    msg.setText('Removing Line From Wrong Axes!')
                    msg.exec_()
                except AttributeError:
                    pass
            elif isinstance(line,matplotlib.lines.Line2D):
                try:
                    self.ax.lines.remove(line)
                    ApplicationSettings.ALL_DATA_PLOTTED.pop(j.data())
                    del line
                except ValueError:
                    msg = QtWidgets.QMessageBox()
                    msg.setText('Removing Line From Wrong Axes!')
                    msg.exec_()
            elif isinstance(line, matplotlib.offsetbox.DraggableAnnotation):
                msg = QtWidgets.QMessageBox()
                msg.text("Can't Remove Annotation :(")
                msg.exec_()
            elif isinstance(line, matplotlib.collections.PolyCollection):
                line.remove()
                ApplicationSettings.ALL_DATA_PLOTTED.pop(j.data())
                del line
            elif isinstance(line, matplotlib.text.Text):
                line.remove()
                ApplicationSettings.ALL_DATA_PLOTTED.pop(j.data())
                del line
            elif isinstance(line, matplotlib.collections.LineCollection):
                line.remove()
                ApplicationSettings.ALL_DATA_PLOTTED.pop(j.data())
                del line
            else:
                print(line)
                print(type(line))
                line_0 = line.lines[0]
                self.ax.lines.remove(line_0)
                ApplicationSettings.ALL_DATA_PLOTTED.pop(j.data())
                del line_0

    all_lines = ApplicationSettings.ALL_DATA_PLOTTED
    dialog = QtWidgets.QDialog()
    ui = simple_tw()
    ui.setupUi(dialog)
    ui.treeWidget.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
    Key_List = []
    for i in all_lines.keys():
        Key_List.append(QtWidgets.QTreeWidgetItem([i]))
    ui.treeWidget.addTopLevelItems(Key_List)
    ui.buttonBox.accepted.connect(lambda:finish())
    dialog.exec_()
    self.canvas.draw()

def send_to_cf(self):
    fit_list = self.dw_SE.fitted_slopes
    self.dw_CF.ui.tableWidget.setRowCount(len(fit_list))
    for row in range(len(fit_list)):
        self.dw_CF.ui.tableWidget.setItem(row, 1, QtWidgets.QTableWidgetItem(str(fit_list[row])))

def random_c_plot(self):
    Z = np.random.rand(6, 10)
    c = self.ax.pcolor(Z)
    self.canvas.draw()
    self.fig.colorbar(c, ax=self.ax)

def app_settings_fun(self):
    def function():
        self.settings.setValue('app_style',ui.comboBox.currentText())
        # os.execl(sys.executable, sys.executable, *sys.argv)
    def change_path(settings_type):
        path = QtWidgets.QFileDialog.getExistingDirectory()
        self.settings.setValue(settings_type, path)
        if settings_type == 'FTIR_PATH':
            self.dw_FTIR.tree_view.setRootIndex(self.dw_FTIR.model.index(path))
        elif settings_type == 'QCM_PATH':
            self.dw_QCM.tree_view.setRootIndex(self.dw_QCM.model.index(path))
        elif settings_type == 'SE_PATH':
            self.dw_SE.tree_view.setRootIndex(self.dw_SE.model.index(path))
        elif settings_type == 'XPS_PATH':
            self.dw_XPS.tree_view.setRootIndex(self.dw_XPS.model.index(path))
        elif settings_type == 'XRD_PATH':
            self.dw_XRD.tree_view.setRootIndex(self.dw_XRD.model.index(path))
        update()
    def update():
        ui.datapath_le.setText(str(self.settings.value('DATA_PATH')))
        ui.projectpath_le.setText(str(self.settings.value('PROJECT_PATH')))
        ui.savepath_le.setText(str(self.settings.value('SAVED_DATA_PATH')))
        ui.fig_path_label.setText(str(self.settings.value('FIG_PATH')))
        ui.ftir_path_label.setText(str(self.settings.value('FTIR_PATH')))
        ui.se_path_label.setText(str(self.settings.value('SE_PATH')))
        ui.qcm_path_label.setText(str(self.settings.value('QCM_PATH')))
        ui.cf_path_label.setText(str(self.settings.value('CF_PATH')))
        ui.xps_path_label.setText(str(self.settings.value('XPS_PATH')))
        ui.xrd_path_label.setText(str(self.settings.value('XRD_PATH')))
        ui.comboBox.setCurrentText(self.settings.value('app_style'))

    d = QtWidgets.QDialog()
    ui = app_settings()
    ui.setupUi(d)
    ui.comboBox.addItems(QtWidgets.QStyleFactory.keys())
    ui.comboBox.addItems(['DarkStyle'])
    ui.comboBox.addItems(['DarkFusion'])
    ui.comboBox.addItems(['GrayFusion'])
    update()
    ui.buttonBox.accepted.connect(lambda: function())
    ui.comboBox.currentTextChanged.connect(lambda: function())
    ui.changedatapath_pb.clicked.connect(lambda: change_path('DATA_PATH'))
    ui.changesavepath_pb.clicked.connect(lambda: change_path('SAVED_DATA_PATH'))
    ui.changeprojectpath_pb.clicked.connect(lambda: change_path('PROJECT_PATH'))
    ui.change_figpath_pb.clicked.connect(lambda: change_path('FIG_PATH'))
    ui.change_ir_pb.clicked.connect(lambda: change_path('FTIR_PATH'))
    ui.change_qcm_pb.clicked.connect(lambda: change_path('QCM_PATH'))
    ui.change_se_pb.clicked.connect(lambda: change_path('SE_PATH'))
    ui.change_cf_pb.clicked.connect(lambda: change_path('CF_PATH'))
    ui.change_xps_pb.clicked.connect(lambda: change_path('XPS_PATH'))
    ui.changexrdpath_pb.clicked.connect(lambda: change_path('XRD_PATH'))
    d.exec_()

def send_to_custom_data(self):
    pass
    def temp():
        for ix in ui.treeWidget.selectedIndexes():
            text = ix.data()  # or ix.data()
            np.savetxt(ui.save_as_LE.text() + '.csv',
                       ApplicationSettings.ALL_DATA_PLOTTED[text][0]._xy, delimiter=',')
    dialog = QtWidgets.QDialog()
    ui = STC_ui()
    ui.setupUi(dialog)
    dict = ApplicationSettings.ALL_DATA_PLOTTED
    Key_List = []
    for i in dict.keys():
        Key_List.append(QtWidgets.QTreeWidgetItem([i]))
    ui.treeWidget.addTopLevelItems(Key_List)
    ui.buttonBox.accepted.connect(lambda: temp())
    dialog.exec_()

def new_project(self):
    def new_pro(project_name):
        os.makedirs(os.path.join(project_name,ui.project_le.text()))
        os.makedirs(os.path.join(project_name,ui.project_le.text(),'Data'))
        os.makedirs(os.path.join(project_name, ui.project_le.text(), 'Saved'))
        os.makedirs(os.path.join(project_name, ui.project_le.text(), 'Graphs'))
        project_path = os.path.join(project_name, ui.project_le.text())

        self.settings.setValue('PROJECT_PATH',project_path)
        self.settings.setValue('SAVED_DATA_PATH', os.path.join(project_path,'Saved'))
        self.settings.setValue('DATA_PATH', os.path.join(project_path, 'Data'))
        self.settings.setValue('FIG_PATH', os.path.join(project_path, 'Graphs'))
    dialog_path = QtWidgets.QFileDialog.getExistingDirectory()
    d = QtWidgets.QDialog()
    ui = new_project_dialog()
    ui.setupUi(d)
    ui.buttonBox.accepted.connect(lambda: new_pro(dialog_path))
    d.exec_()

def open_project(self):
    dialog = QtWidgets.QFileDialog.getExistingDirectory()
    self.settings.setValue('PROJECT_PATH', dialog)

def load_data(self):
    temp = self.settings.value()
    key_list = [i for i in temp.keys()]
    for i in key_list:
        data = temp[i][0]._xy.T
        self.ax.plot(data[0],data[1])
    self.canvas.draw()

def import_file(self):
    filepath = QtWidgets.QFileDialog.getOpenFileName()[0]
    try:
        filename = os.path.basename(filepath)
        datapath = self.settings.value('DATA_PATH')
        copy2(filepath, os.path.join(datapath,filename))
    except FileNotFoundError:
        pass

def import_directiory_function(self):
    src_directory = QtWidgets.QFileDialog.getExistingDirectory()
    dirname = src_directory.split('/')[-1]
    print(os.path.join(self.settings.value('DATA_PATH'),dirname))
    copytree(src_directory,os.path.join(self.settings.value('DATA_PATH'),dirname))

def plot_annotation(self):
    def finish():
        try:
            a_list = [ui.text.text(), ui.text_2.text(), ui.text_3.text()]
            while ("" in a_list):
                a_list.remove("")
            print(a_list)
            joined_string = "\n".join(a_list)
            print(joined_string)
            if ui.frame.currentText() == 'none':
                bbox = None
            else:
                bbox = dict(dict(boxstyle=ui.frame.currentText(), fc=ui.bgcolor.currentText(), ec="k", alpha=ui.alpha.value()))
            ApplicationSettings.ALL_DATA_PLOTTED[ui.text.text()] = \
                self.ax.text(np.average(self.ax.get_xlim()), np.average(self.ax.get_ylim()), joined_string,
                             color=ui.color.currentText(), fontsize=ui.size.value(), picker=True,
                             fontstyle=ui.fontstyle.currentText(), rotation=ui.rotation.value(), bbox=bbox,
                             ha=ui.ha_cb.currentText(), va='center')
            self.anno_alpha = ui.alpha.value()
            self.anno_text = ui.text.text()
            self.anno_text_2 = ui.text_2.text()
            self.anno_text_3 = ui.text_3.text()
            self.anno_bgcolor = ui.bgcolor.currentText()
            self.anno_fecolor = ui.framecolor.currentText()
            self.anno_rotation = ui.rotation.value()
            self.anno_color = ui.color.currentText()
            self.anno_frame_width = ui.framewidth_sb.value()
            self.anno_frame = ui.frame.currentText()
            self.anno_style = ui.fontstyle.currentText()
            self.anno_size = ui.size.value()
        except ValueError:
            msg = QtWidgets.QMessageBox()
            msg.setText('Annotation Syntax Error')
            msg.exec_()

        self.canvas.draw()
    d = QtWidgets.QDialog()
    ui = annotation_ui()
    ui.setupUi(d)
    ui.bgcolor.addItems(self.color_list)
    ui.framecolor.addItems(self.color_list)
    ui.color.addItems(self.color_list)

    ui.size.setValue(self.anno_size)
    ui.bgcolor.setCurrentText(self.anno_bgcolor)
    ui.color.setCurrentText(self.anno_color)
    ui.framecolor.setCurrentText(self.anno_fecolor)
    ui.frame.setCurrentText(self.anno_frame)
    ui.alpha.setValue(self.anno_alpha)
    ui.text.setText(self.anno_text)
    ui.text_2.setText(self.anno_text_2)
    ui.text_3.setText(self.anno_text_3)
    ui.rotation.setValue(self.anno_rotation)
    ui.framewidth_sb.setValue(self.anno_frame_width)
    ui.fontstyle.setCurrentText(self.anno_style)

    ui.buttonBox.accepted.connect(lambda: finish())
    d.exec_()

def bar_graph(self):
    d = QtWidgets.QDialog()
    ui = bar_dialog()
    ui.setupUi(d)
    l1 = [ui.x_list, ui.y1_list, ui.y2_list, ui.y3_list, ui.label1_le, ui.label2_le, ui.label3_le, ui.width_le, ui.num_sb]
    l2 = ['xlist', 'y1list', 'y2list', 'y3list', 'label1', 'label2', 'label3', 'width', 'num']
    def plot_bar():
        N = ui.num_sb.value()
        width = float(ui.width_le.text())
        labels = ui.x_list.text().split(' ')
        x = np.arange(len(labels))  # the label locations

        if N == 1:
            y1 = [float(i) for i in ui.y1_list.text().split(' ')]
            self.ax.bar(x, y1, width, label=ui.label1_le.text())
        elif N == 2:
            y1 = [float(i) for i in ui.y1_list.text().split(' ')]
            self.ax.bar(x - width / 2, y1, width, label=ui.label1_le.text())
            y2 = [float(i) for i in ui.y2_list.text().split(' ')]
            self.ax.bar(x + width / 2, y2, width, label=ui.label2_le.text())
        elif N == 3:
            y1 = [float(i) for i in ui.y1_list.text().split(' ')]
            self.ax.bar(x - 3*width / 3, y1, width, label=ui.label1_le.text())
            y2 = [float(i) for i in ui.y2_list.text().split(' ')]
            self.ax.bar(x + 3*width / 3, y2, width, label=ui.label2_le.text())
            y3 = [float(i) for i in ui.y3_list.text().split(' ')]
            self.ax.bar(x , y3, width, label=ui.label3_le.text())

        # Add some text for labels, title and custom x-axis tick labels, etc.
        self.ax.set_xticks(x)
        self.ax.set_xticklabels(labels)
        self.ax.legend()

        # self.fig.bar_label(rects1, padding=3)
        # self.fig.bar_label(rects2, padding=3)
        for i in range(len(l1)):
            self.bar[l2[i]] = l1[i].text()
        self.canvas.draw()
    for i in range(len(l1)):
        try:
            l1[i].setText(self.bar[l2[i]])
        except AttributeError:
            l1[i].setValue(int(self.bar[l2[i]]))
    ui.buttonBox.accepted.connect(lambda: plot_bar())
    d.exec_()

def baseline_als(y, lam, p, niter=10):
    L = len(y)
    D = sparse.diags([1,-2,1],[0,-1,-2], shape=(L,L-2))
    w = np.ones(L)
    for i in range(niter):
        W = sparse.spdiags(w, 0, L, L)
        Z = W + lam * D.dot(D.transpose())
        z = spsolve(Z, w*y)
        w = p * (y > z) + (1-p) * (y < z)
    return z

def fill_cols_fun(self):
    self.ui.tw_x.clear()
    self.ui.tw_y.clear()
    path = self.model.filePath(self.tree_view.currentIndex())
    filename, extension = os.path.splitext(self.model.filePath(self.tree_view.currentIndex()))
    try:
        skip_rows = self.ui.skip_rows_sb.value()
    except AttributeError:
        print('No Skipped Rows')
        skip_rows = 0
    if extension == '.CSV' or extension == '.csv':
        self.data = pd.read_csv(path, delimiter=',', skiprows=skip_rows)
    elif extension == '.xls' or extension == '.xlsx':
        excelfile = pd.ExcelFile(path)
        self.data = pd.read_excel(excelfile, "Sheet1", skiprows=skip_rows)
    elif extension == '.X01':
        self.data = pd.read_csv(path, delimiter='   ', skiprows=48, engine='python')
    elif extension =='.txt':
        self.data = pd.read_csv(path, sep='\t', skiprows=skip_rows)
    elif extension == '.dat':
        self.data = pd.read_csv(path, sep=' ', skiprows=skip_rows)
    else:
        print(extension)
        self.data = pd.read_csv(path, sep='\t')

    strings = [col for col in self.data.columns]
    column_list_x = []
    column_list_y = []
    for i in strings:
        column_list_x.append(QtWidgets.QTreeWidgetItem([i]))
        column_list_y.append(QtWidgets.QTreeWidgetItem([i]))
        self.ui.tw_x.addTopLevelItems(column_list_x)
        self.ui.tw_y.addTopLevelItems(column_list_y)

def move_line(self):
    def finish():
        for j in ui.treeWidget.selectedIndexes():
            line = ApplicationSettings.ALL_DATA_PLOTTED[j.data()]
            print(line)
            print(type(line))
            if isinstance(line, list):
                new_line = line[0]._xy.T[1] + float(ui.lineEdit.text())
                print(new_line)
                ApplicationSettings.ALL_DATA_PLOTTED[j.data() + '_' + str(ui.lineEdit.text())] = self.ax.plot(
                    line[0]._xy.T[0], new_line)
                self.ax.lines.remove(line[0])
                ApplicationSettings.ALL_DATA_PLOTTED.pop(j.data())
                del line
            elif isinstance(line, matplotlib.lines.Line2D):
                new_line = line._xy.T[1] + float(ui.lineEdit.text())
                print(new_line)
                print()
                ApplicationSettings.ALL_DATA_PLOTTED[j.data()+'_'+str(ui.lineEdit.text())] = self.ax.plot(
                    line._xy.T[0],new_line)
                self.ax.lines.remove(line)
                ApplicationSettings.ALL_DATA_PLOTTED.pop(j.data())
                del line
            else:
                msg = QtWidgets.QMessageBox()
                msg.setText('Make sure its a line')
                msg.exec_()

    all_lines = ApplicationSettings.ALL_DATA_PLOTTED
    dialog = QtWidgets.QDialog()
    ui = simple_tw()
    ui.setupUi(dialog)
    ui.treeWidget.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
    Key_List = []
    for i in all_lines.keys():
        Key_List.append(QtWidgets.QTreeWidgetItem([i]))
    ui.treeWidget.addTopLevelItems(Key_List)
    ui.buttonBox.accepted.connect(lambda:finish())
    dialog.exec_()
    self.canvas.draw()

def change_axis(self,axis):
    if axis ==1:
        self.ax = self.ax_1
    elif axis ==2:
        self.ax = self.ax_2
    elif axis ==3:
        self.ax = self.ax_3
    elif axis ==4:
        self.ax = self.ax_4
    elif axis ==5:
        self.ax = self.ax_5
    elif axis ==6:
        self.ax = self.ax_6
    elif axis ==7:
        self.ax = self.ax_7
    elif axis ==8:
        self.ax = self.ax_8
    elif axis ==9:
        self.ax = self.ax_9
    try:
        self.ax.callbacks.connect('xlim_changed', self.lims_change)
        self.dragh = DragHandler(self, figure=self.fig)
    except AttributeError:
        print('No Axis made yet')

def axis_setup_fun(self):
    possible_axes = [self.ax_1, self.ax_2, self.ax_3, self.ax_4, self.ax_5,
                     self.ax_6, self.ax_7, self.ax_8, self.ax_9, self.ax_10]
    print(possible_axes)
    self.ax.clear()
    self.fig.clf()
    self.ui.verticalLayout.removeWidget(self.toolbar)
    self.ui.verticalLayout.removeWidget(self.canvas)
    self.toolbar.close()
    self.canvas.close()
    self.fig = figure(num=None, figsize=(8, 6), dpi=80)
    self.canvas = FigureCanvas(self.fig)
    self.toolbar = NavigationToolbar(self.canvas, self.canvas, coordinates=True)
    self.ui.verticalLayout.addWidget(self.toolbar)
    self.ui.verticalLayout.addWidget(self.canvas)
    self.canvas.installEventFilter(self)
    self.ax.callbacks.connect('xlim_changed', self.lims_change)
    vertical_axes = QtWidgets.QInputDialog.getInt(self, 'Axes Setup','Vertical?',1)
    horizontal_axes = QtWidgets.QInputDialog.getInt(self, 'Axes Setup', 'Horizontal?',1)
    axesstr = str(vertical_axes[0]) + str(horizontal_axes[0])
    axesint = [horizontal_axes[0], vertical_axes[0]]
    times = axesint[0]*axesint[1]

    pos_axes = [int(axesstr + str(i)) for i in range(1, times+1)]
    for i,num in enumerate(pos_axes):
        print(i)
        print(num)
        possible_axes[i] = self.fig.add_subplot(num)
        print(possible_axes)
    self.ax = self.ax_1
    self.fig.tight_layout()
    self.canvas.draw()

def add_line_to_graph(self):
    def finish():
        if ui.comboBox.currentText() == 'Verticle Line':
            ApplicationSettings.ALL_DATA_PLOTTED['vline'+str(ui.line_pos_sb.value())] = self.ax.axvline(x=ui.line_pos_sb.value(), linestyle="--", lw=ui.line_width_sb.value(),
                            color=ui.color_cb.currentText(), alpha=ui.alpha_sb.value())
        elif ui.comboBox.currentText() == 'Horizontal Line':
            ApplicationSettings.ALL_DATA_PLOTTED['hline'+str(ui.line_pos_sb.value())] = self.ax.axhline(y=ui.line_pos_sb.value(), linestyle="--", lw=ui.line_width_sb.value(),
                            color=ui.color_cb.currentText(), alpha=ui.alpha_sb.value())
        self.canvas.draw()
    d = QtWidgets.QDialog()
    ui = vhline_ui()
    ui.setupUi(d)
    ui.buttonBox.accepted.connect(lambda: finish())
    d.exec_()

def keycheck(dict, key):
    if key in dict.keys():
        return True
    else:
        return False

def addmpl(self,fig):
    self.main_window.canvas = FigureCanvas(fig)
    self.ui.verticalLayout.addWidget(self.main_window.canvas)
    self.main_window.canvas.draw()
    self.toolbar = NavigationToolbar(self.main_window.canvas,
                                     self, coordinates=True)
    self.ui.verticalLayout.addWidget(self.main_window.toolbar)

def rmmpl(self):
    self.ui.verticalLayout.removeWidget(self.main_window.canvas)
    self.main_window.canvas.close()
    self.ui.verticalLayout.removeWidget(self.main_window.toolbar)

def qcm_hc_mass(data, start_time=float, end_time=float, purge_time_a=float, purge_time_b=float, num_cycles=int):
    time = data[0]
    mass = data[2]
    exposure = []
    exposure_idx = []
    mass_hc_a = []
    mass_hc_b = []
    exp_length_idx = []
    # time_in_idx = find_nearest(time, end_time) - find_nearest(time, start_time)
    mass_process = mass[find_nearest(time, start_time): find_nearest(time, end_time)]
    time_process = time[find_nearest(time, start_time):find_nearest(time, end_time)]
    print(time_process)
    print(mass_process)
    for i in range(num_cycles):
        if i % 2 == 0:
            exposure.append(start_time + (purge_time_a * i))
            exposure_idx.append(find_nearest(time_process, start_time + (purge_time_a * i)))
        elif i % 2 == 1:
            exposure.append(start_time + (purge_time_b * i))
            exposure_idx.append(find_nearest(time_process, start_time + (purge_time_b * i)))
    for k in range(len(exposure_idx) - 1):
        exp_length_idx.append(exposure_idx[k + 1] - exposure_idx[k])
    for j in range(num_cycles - 1):
        if j % 2 == 0:
            mass_hc_a.append(
                mass_process[int((exposure_idx[j + 1] - exposure_idx[j]) * .9 + exposure_idx[j])] - mass_process[
                    exposure_idx[j]])
        elif j % 2 == 1:
            mass_hc_b.append(
                mass_process[int((exposure_idx[j + 1] - exposure_idx[j]) * .9 + exposure_idx[j])] - mass_process[
                    exposure_idx[j]])
    fc = np.zeros(len(mass_hc_b))
    for i in range(len(mass_hc_b)):
        fc[i] = mass_hc_a[i]+mass_hc_b[i]
    return mass_hc_a,mass_hc_b, fc

def plot_QCM(self, time,pressure,mass,a_exp=int,b_exp=int,ttp=float,threshold=float,from_time=int,to_time=int,
             wait_time=float, density = float):
    #  Few more assignments Exposures is the time of each Exposure, the Index is just what index it
    #  shows up as. M_Diff and P_Diff are the mass and pressure difference at different exposures
    #  Purge Time Index is the number of data points between one exposure and the next, does not
    #  differentiate for the exposure time.
    Exposures = []
    A_Exposures = a_exp
    Exposure_index = []
    QCM_M_Diff = []
    QCM_P_Diff = []
    MC_A = []
    MC_B = []
    MC_P = []
    MC_N = []
    MC_Cycle = []

    t = 0
    #  Time through purge is the time to "wait" after there is an exposure to not overcount exposures
    #  Time is just a temp variable that gives the time of the last exposure

    # This for loop is just for appending the exposures to Exposures and Exposure_index nee
    for num in range(len(pressure) - 10):
        QCM_M_Diff.append(mass[num + 3] - mass[num])
        QCM_P_Diff.append(pressure[num + 3] - pressure[num])
        if QCM_P_Diff[num] >= threshold and time[num] - t > wait_time and time[num] > from_time and time[num] < to_time:
            Exposures.append(time[num])
            Exposure_index.append(num)
            t = time[num]

            # self.main_window.ax.axvline(time[num], color='gray', lw=1, alpha=0.5)
            # above line will add a line for each exposure if someone is uncertain about if its right

    # This for loop is knowing how long each purge time is (or time from one exposure to next)
    Purge_Time_Index = np.zeros(len(Exposure_index))

    for num in range(len(Exposure_index) - 1):
        if (Exposure_index[num + 1] - Exposure_index[num]) < 2000:
            Purge_Time_Index[num] = Exposure_index[num + 1] - Exposure_index[num]

    Purge_Time_Index[-1] = Purge_Time_Index[0]

    # print(Purge_Time_Index)

    #  for loop finds the mass at the: Exposure time + Purge_time*(time_through_purge) which takes the time
    #  of the last exposure and then adds something like 0.8*Time of purge... Insert is to do the last one
    #  if else says if Mass_Middle was bigger or smaller than the last one and sorts it into one of two lists
    #  Last if else sorts based on if num is odd or even... For A-B experiemtns.. Nothing for A BBB or some
    #  Thing like that
    mass_middle = np.zeros(len(Exposure_index)+2)
    mass_middle[0] = mass[Exposure_index[0] - int(Purge_Time_Index[0] * ttp)]
    # mass_middle.insert(0, mass[Exposure_index[0] - int(Purge_Time_Index[0] * ttp)])

    for num in range(len(Exposure_index)):
        # mass_middle.append(mass[int(Exposure_index[num] + int(Purge_Time_Index[num] * ttp))])
        mass_middle[num+1] = mass[int(Exposure_index[num] + int(Purge_Time_Index[num] * ttp))]
        # self.main_window.ax.axvline(time[num], color='gray', lw=1, alpha=0.5)
        # above line will add a line for each time if someone is uncertain about if its right

    # mass_middle.append(mass[Exposure_index[-1] + int(Purge_Time_Index[0] * ttp)])
    mass_middle[-1] = mass[Exposure_index[-1] + int(Purge_Time_Index[0] * ttp)]

    # print('There was ' + str(len(Exposures)) + '  Precursor Exposures')
    self.main_window.dw_QCM.ui.num_doses.setText(str(len(Exposures)))

    for num in range(len(Exposure_index)):
        if mass_middle[num + 1] - mass_middle[num] > 0:
            MC_P.append(mass_middle[num + 1] - mass_middle[num])
        elif mass_middle[num + 1] - mass_middle[num] < 0:
            MC_N.append(mass_middle[num + 1] - mass_middle[num])
        if num % (b_exp + A_Exposures) == 0:
            MC_Cycle.append(mass_middle[num + b_exp + A_Exposures] - mass_middle[num])
        if num == a_exp - 1:
            MC_A.append(mass_middle[num + 1] - mass_middle[num + 1 - A_Exposures])
        elif num == b_exp + a_exp - 1:
            MC_B.append(mass_middle[num + 1] - mass_middle[num + 1 - b_exp])
        elif num == a_exp + b_exp:
            a_exp = a_exp + A_Exposures + b_exp
            if num == a_exp - 1:
                MC_A.append(mass_middle[num + 1] - mass_middle[
                    num + 1 - A_Exposures])

            # elif num == B_Doses + A_Doses:
            #     self.QCM_Dict['MC_B'].QCM_B.append(Mass_Middle[num] - Mass_Middle[num + 1 - int(B_Exposures.text())])
    half_cycle_density_A = np.zeros(len(MC_A))
    half_cycle_density_B = np.zeros(len(MC_B))
    full_cycle_density = np.zeros(len(MC_Cycle))
    for i in range(len(MC_A)):
        half_cycle_density_A[i] = MC_A[i] / (10.0 * density)
    for i in range(len(MC_B)):
        half_cycle_density_B[i] = MC_B[i] / (10.0 * density)
    for i in range(len(MC_Cycle)):
        full_cycle_density[i] = MC_Cycle[i] / (10 * density)

    return MC_A, MC_B, MC_Cycle, half_cycle_density_A, half_cycle_density_B, full_cycle_density

def find_nearest(array: object, value: object) -> object:
    array = np.asarray(array)
    idx = (np.abs(array - value)).argmin()
    return idx

def select_delete_range(self, enabled):
    if enabled:
        self.span = SpanSelector(self.main_window.ax, remove_data_0, 'horizontal', useblit=False,
                                 rectprops=dict(alpha=0.2, facecolor='blue'))
    else:
        del self.span

def remove_data_0(self, minimum, maximum):
    def finish():
        data = []
        for j in ui.treeWidget.selectedIndexes():
            line = ApplicationSettings.ALL_DATA_PLOTTED[j.data()]
            data.append(line._xy.T)
            temp = line._xy.T[0]
            print(find_nearest(temp,minimum))
            print(find_nearest(temp, maximum))
        print(data)
            # if isinstance(line, list):
            #     try:
            #         self.ax.lines.remove(line[0])
            #         ApplicationSettings.ALL_DATA_PLOTTED.pop(j.data())
            #         del line
            #         self.canvas.draw()
            #     except ValueError:
            #         msg = QtWidgets.QMessageBox()
            #         msg.setText('Removing Line From Wrong Axes!')
            #         msg.exec_()
            #     except AttributeError:
            #         pass
            # elif isinstance(line, matplotlib.lines.Line2D):
            #     try:
            #         self.ax.lines.remove(line)
            #         ApplicationSettings.ALL_DATA_PLOTTED.pop(j.data())
            #         del line
            #     except ValueError:
            #         msg = QtWidgets.QMessageBox()
            #         msg.setText('Removing Line From Wrong Axes!')
            #         msg.exec_()
    all_lines = ApplicationSettings.ALL_DATA_PLOTTED
    dialog = QtWidgets.QDialog()
    ui = simple_tw()
    ui.setupUi(dialog)
    ui.treeWidget.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
    Key_List = []
    for i in all_lines.keys():
        Key_List.append(QtWidgets.QTreeWidgetItem([i]))
    ui.treeWidget.addTopLevelItems(Key_List)
    ui.buttonBox.accepted.connect(lambda: finish())
    dialog.exec_()
    self.canvas.draw()

def color_test(button):
    color = QtWidgets.QColorDialog()
    color.exec_()
    try:
        button.setStyleSheet("background-color: {}".format(color.currentColor().name()))
        button.setText(color.currentColor().name())
    except ValueError:
        print('err')

def gridspec(self):
    # self.ax.clear()
    # self.fig.clf()
    # self.ui.verticalLayout.removeWidget(self.toolbar)
    # self.ui.verticalLayout.removeWidget(self.canvas)
    # self.toolbar.close()
    # self.canvas.close()
    # self.fig = figure(num=None, figsize=(8, 6), dpi=80)
    # spec4 = self.fig.add_gridspec(ncols=1, nrows=2, height_ratios=[1, 3])
    # self.canvas = FigureCanvas(self.fig)
    # self.toolbar = NavigationToolbar(self.canvas, self.canvas, coordinates=True)
    # self.ui.verticalLayout.addWidget(self.toolbar)
    # self.ui.verticalLayout.addWidget(self.canvas)
    # self.canvas.installEventFilter(self)
    # self.ax1 = self.fig.add_subplot(spec4[0, 0])
    # self.ax2 = self.fig.add_subplot(spec4[1, 0])
    # self.canvas.draw
    rw, rh = 2, 5
    box1 = self.ax_1.get_position()
    box2 = self.ax_2.get_position()
    # current dimensions
    w1,h1 = box1.x1-box1.x0, box1.y1-box1.y0
    w2,h2 = box2.x1-box2.x0, box2.y1-box2.y0
    top1 = box1.y0+h1
    #top2 = box2.y0+h2
    full_h = h1+h2   #total height

    # compute new heights for each axes
    new_h1 = full_h*rw/(rw + rh)
    new_h2 = full_h*rh/(rw + rh)+.03

    #btm1,btm2 = box1.y0, box2.y0
    new_bottom1 = top1-new_h1

    # finally, set new location/dimensions of the axes
    self.ax_1.set_position([box1.x0, new_bottom1, w1, new_h1])
    self.ax_2.set_position([box2.x0, box2.y0, w2, new_h2])

    self.canvas.draw()

def label_size(self):
    size, ok = QtWidgets.QInputDialog.getDouble(None, 'Axis Label Size', 'Size: ')
    if ok:
        # sns.set(font_scale=size)
        ax_xlabel = self.ax_1.get_xlabel()
        self.ax_1.set_xlabel(ax_xlabel, fontsize=size)
        ax_ylabel = self.ax_1.get_ylabel()
        self.ax_1.set_ylabel(ax_ylabel, fontsize=size)
    #     self.ax.set_ylabel(self.ax.get_ylabel(), fontsize=size)
    #     self.ax.set_xticklabels(self.ax.get_xticklabels(), fontsize=size)
    #     self.ax.set_yticklabels(self.ax.get_yticklabels(), fontsize=size)
        try:
            ax2_xlabel = self.ax_2.get_xlabel()
            self.ax_2.set_xlabel(ax2_xlabel, fontsize=size)
            # self.ax_2.set_xticklabels(self.ax_2.get_xticklabels(), fontsize=size)
        except AttributeError:
            print('AttError')
        try:
            ax2_ylabel = self.ax_2.get_ylabel()
            self.ax_2.set_ylabel(ax2_ylabel, fontsize=size)
            # self.ax_2.set_ylabel(self.ax_2.get_ylabel(), fontsize=size)
            # self.ax_2.set_yticklabels(self.ax_2.get_yticklabels(), fontsize=size)
        except AttributeError:
            print('AttError')
        self.canvas.draw()

def print_something():
    print('something')

class DragHandler(object):
    """ A simple class to handle Drag n Drop.

    This is a simple example, which works for Text objects only
    """
    def __init__(self, main_window, figure=None):
        """ Create a new drag handler and connect it to the figure's event system.
        If the figure handler is not given, the current figure is used instead
        """
        if figure is None : figure = matplotlib.pyplot.gcf()
        # simple attibute to store the dragged text object
        self.dragged = None
        self.main_window = main_window
        # Connect events and callbacks
        figure.canvas.mpl_connect("pick_event", self.on_pick_event)
        figure.canvas.mpl_connect("button_release_event", self.on_release_event)
        # figure.canvas.mpl_connect("button_release_event", self.on_release)

    def on_pick_event(self, event):
        " Store which text object was picked and were the pick event occurs."
        if isinstance(event.artist, Text):
            self.dragged = event.artist
            self.pick_pos = (event.mouseevent.xdata, event.mouseevent.ydata)
        return True

    def on_release_event(self, event):
        " Update text position and redraw"
        if self.dragged is not None:
            old_pos = self.dragged.get_position()
            new_pos = (old_pos[0] + event.xdata - self.pick_pos[0],
                       old_pos[1] + event.ydata - self.pick_pos[1])
            self.dragged.set_position(new_pos)
            self.dragged = None
            self.main_window.canvas.draw()
        return True


from __future__ import print_function
import numpy as np
import h5py
import hdf5plugin
import Daisy

class SaveHDF5(Daisy.Base.DaisyAlg):

    def __init__(self, name):
        super().__init__(name)
        self.cfg        = {}

    def initialize(self, outputfile_name = None, default_init = None):
        self.data   = self.get("DataStore").data()
        self.LogInfo("initialized")

    def config(self, cfgdata=None):
        if cfgdata is None:
            self.LogError('Please provide configuration file!')
        Daisy.CfgParser(self, cfgdata, self.cfg)
        self.foname = self.cfg['outputfile_name']
        return True

    def execute(self, input_dataobj, output_path=''):
        idata  = self.data[input_dataobj]
        dtype  = type(idata)
        #print('type of ouput data: '+str(dtype))
        with h5py.File(self.foname, 'w') as hfile:
            hfile.create_dataset(output_path, data=idata)
            self.LogInfo('Save data '+input_dataobj+' as '+output_path+' to '+self.foname)
       # if type(output_path) is str:
       #     items = output_path.split('/')
       #     for item in items:
       #         if len(item) == 0:
       #             continue
       #         if item in handle.keys():
       #             handle = handle[item]
       #         else:
       #             handle = handle.create_group(item)
       #         print('enter path: '+ item)
       #
       # if dtype is dict:
       #     for key in idata.keys():
       #         if type(key) is str:
       #             self.LogInfo(key+" is stored in file "+self.foname)
       #             self.LogInfo(str(idata[key]))
       #             handle.create_dataset(key, data=idata[key])
       #         else:
       #             self.LogError("The keys of input data should be class <'str'> ")
       #             return True
       # else:
       #     print('================='+output_path)
       #     handle.create_dataset(output_path, data=idata)
       #

        return True

    def finalize(self):
        #self.hdf5.close()
        self.LogInfo("finalized, close HDF5 File: "+self.foname)
        return True


from django.urls import path
from .views import index, detail, result

app_name = "boss"

urlpatterns = [
    path('', index, name="index"),
    path('<int:pk>/', detail, name='detail'),
    path('<int:pk>/result/', result, name='result'),

]

# urlpatterns = [
#     path('index/', index, name="index"),
#     path('<int:pk>/', detail, name='detail'),
#     path('<int:pk>/result/', result, name='result'),

# ]


# Streamlit
import streamlit as st

from PIL import Image

st.set_page_config(layout='wide', initial_sidebar_state='collapsed', page_title='Support', page_icon='☕')

# Title
st.markdown('# Support')

# Coffee
st.markdown('## Hey, give me your [money](https://www.buymeacoffee.com/juanmolera)')
image = Image.open('images/fry-shut-up-and-take-my-money.png')
st.image(image, use_column_width=True)


from django.views.generic import View
from django.http import JsonResponse, HttpResponse
from django.core import serializers
from WIMPsite.models import *
import datetime

import json

class TestAPI(View):
    def get(self, request, action):
        get = request.GET

        if action == "scheduled_tests":
            j = json.loads(serializers.serialize("json", ScheduledTest.objects.filter(current_test=True).all()))
        elif action == "test_strip":
            if "pk" in get:
                strip = TestStrip.objects.get(pk=get["pk"])

                j = json.loads(serializers.serialize("json", strip.tests.all()))
            else:
                j = json.loads(serializers.serialize("json", TestStrip.objects.all()))
        elif action == "get_colors":
            strip = TestStrip.objects.get(pk=get["pk"])

            j = {"tests": []}
            for test in strip.tests.all():
                test_json = {}
                test_json["name"] = test.name
                test_json["colors"] = json.loads(serializers.serialize("json", test.colors.all()))

                j["tests"].append(test_json)
        elif action == "result":
            latest_test = ScheduledTest.objects.filter(current_test=True).latest('last_run')

            results = []

            for test in latest_test.test_strip.tests.all():
                result = test.results.latest('time_run')

                results.append({"color": result.rgb, "text": result.get_color_match[0][0].text})

            j = results

        else:
            j = {"error": "{} not found".format(action)}

        return JsonResponse(j, safe=False)

    def post(self, request, action):
        body = request.body.decode('utf8')
        body = json.loads(body)

        if action == "report_test":
            if "scheduled_test_pk" in body:
                test_run = ScheduledTest.objects.get(pk=body["scheduled_test_pk"])
                date = datetime.datetime.now()
                test_run.last_run = date
                test_run.save()

                for result in body["results"]:
                    chemical_test_pk = result["pk"]
                    r = result["r"]
                    g = result["g"]
                    b = result["b"]

                    TestResult.objects.create(chemical_test_id=chemical_test_pk, r=r, g=g, b=b,
                                              time_run=test_run.last_run)

                return HttpResponse("Success")
        elif action == "report_temp":
            if "temp" in body:
                TempResult.objects.create(temp=body["temp"])

                return HttpResponse("Success")
        elif action == "add_test":
            if "strip_id" in body:
                strip = TestStrip.objects.get(pk=body["strip_id"])

                chemical_test = ChemicalTest.objects.create(unit=body["unit"], name=body["strip_name"], test=strip,
                                                            region_y2=0, region_y1=0, region_x2=0, region_x1=0)

                for color in body["colors"]:
                    Color.objects.create(unit_value=color["unit_value"], text=color["text"], r=color["r"], g=color["g"],
                                         b=color["b"], test=chemical_test)

                return HttpResponse("Success")
        elif action == "add_strip":
            if "strip_name" in body:
                strip = TestStrip.objects.create(name=body["strip_name"])

                return JsonResponse({"id": strip.id})

        return HttpResponse("Fail")

class SettingsAPI(View):
    def get(self, request, action):
        get = request.GET


""" Search's indexes. """
from haystack import indexes

from .models import Solution

class SolutionIndex(indexes.SearchIndex, indexes.Indexable):

    """ Index by solutions. """

    text = indexes.CharField(document=True, use_template=True, null=True)
    title = indexes.CharField(model_attr='title', null=True)
    time_updated = indexes.DateTimeField(model_attr='time_updated')
    project = indexes.CharField(model_attr='project__title')

    def get_model(self):
        """ Point to model.

        :return Task:

        """
        return Solution

    def get_updated_field(self):
        """ Point to updated field.

        :return str:

        """
        return 'time_updated'


from aiohttp import web
import socketio
from faceRecog import FacRecog
import time
import redis
sio = socketio.AsyncServer()
app = web.Application()
sio.attach(app)
r = redis.Redis(host='localhost', port=6379, db=0)

async def index(request):
    with open('index.html') as f:
        return web.Response(text=f.read(), content_type='text/html')

@sio.on('renderFrame')
async def print_message(sid, message):
    index = 0
    imageSX4 = ""
    print(message)
    while(True):
        imageSX4 = (r.get(index)).decode('utf-8')
        print("Connected via Socket ID: ", sid)
        if(r.get(str(index))) == None:
            time.sleep(2)
            continue
        await sio.emit('response', imageSX4)
        print(message)
        r.delete(str(index))
        index+=1
        time.sleep(1.5)

app.router.add_get('/', index)
if __name__ == '__main__':
    web.run_app(app)


from pathlib import Path
from typing import List

from pil_utils import BuildImage

from meme_generator import add_meme
from meme_generator.exception import TextOverLength

img_dir = Path(__file__).parent / "images"

def wakeup(images, texts: List[str], args):
    text = texts[0]
    frame = BuildImage.open(img_dir / "0.jpg")
    try:
        frame.draw_text((310, 270, 460, 380), text, max_fontsize=90, min_fontsize=50)
    except ValueError:
        raise TextOverLength(text)
    frame.draw_text(
        (50, 610, 670, 720), f"{text}起来了", max_fontsize=110, min_fontsize=70
    )
    return frame.save_jpg()

add_meme(
    "wakeup",
    wakeup,
    min_texts=1,
    max_texts=1,
    default_texts=["好"],
    keywords=["xx起来了"],
    patterns=[r"(.+?)\s+起来了"],
)


import clr
from collections import OrderedDict
from datetime import datetime
import os
import re
import sys
from typing import Dict, Optional, Tuple

from connect import *
from connect.connect_cpython import PyScriptObject  # For type hints

clr.AddReference('System.Windows.Forms')
from System.Windows.Forms import MessageBox

# Directory to save the TXT file in
# This directory does not have to exist
OUTPUT_DIR = os.path.join('T:', os.sep, 'Physics', 'Scripts', 'Output Files', 'Generate Shifts Comments')

def fmt_num(num: float, nearest_x: float) -> str:
    """Gets a nicely formatted string version of the number

    Rounds the number to the nearest `nearest_x`
    Removes any trailing zeroes. If nothing remians after the decimal point, removes it also

    Arguments
    ---------
    num: The number to format
    nearest_x: The interval to round to

    Returns
    -------
    The string that is the formatted number

    Example
    -------
    fmt_num(1.61, 0.5) -> '1.5'
    """
    num = round(num / nearest_x) * nearest_x
    # Don't count the "0." at the beginning
    num_places = len(str(nearest_x)) - 2
    num = format(num, '.{}f'.format(num_places))
    # Remove trailing zeroes. If there was nothing but zeroes after the decinal point, remove it, too
    num = num.rstrip('0').rstrip('.')
    return num

def setup_beam_ssd(setup_beam: PyScriptObject, regex: str) -> Optional[float]:
    """Gets the SSD of the setup beam if any of the following are true:
    - Its name or description contains the given regular expression (case insensitive)
    - The regular expression is "AP" (case insensitive) and the beam's gantry angle is zero
    - The regular expression is "PA" (case insensitive) and the beam's gantry angle is 180

    The matched substring must not be surrounded by alphabetic characters

    Arguments
    ---------
    setup_beam: The setup beam whose SSD to return
    regex: The regular expression to match a substring in the setup beam's name or description

    Returns
    -------
    The setup beam's SSD, if the setup beam matches, or None otherwise or if the SSD is infinite
    """
    full_regex = r'(^|[^a-zA-Z])' + regex + r'($|[^a-zA-Z])'  # Matching substring must not be immediately preceded or followed by an alphabetic character
    if (re.search(full_regex, setup_beam.Name, re.IGNORECASE) is not None or re.search(full_regex, setup_beam.Description, re.IGNORECASE) is not None) or (regex == 'AP' and setup_beam.GantryAngle == 0) or (regex == 'PA' and setup_beam.GantryAngle == 180):
        setup_beam_ssd = setup_beam.GetSSD()
        if abs(setup_beam_ssd) != float('inf'):  # Infinite SSD
             return setup_beam_ssd

def cb_setup_beams(beam_set: PyScriptObject, pos: str) -> Tuple[Dict[PyScriptObject, float], Dict[PyScriptObject, float]]:
    """Gets the cone-beam (CB) setup beams for a beam set

    A setup beam is considered CB if its name or description contains "CB" or "CBCT", or "AP" (for supine patients) or "PA" (for prone patients)
    Only CB setup beams with SSD are returned

    Arguments
    ---------
    beam_set: The beam set whose CB setup beams to return

    Returns
    -------
    A 2-tuple of dictionaries with setup beams as the keys and SSDs as the values.
    The first element is "CB" setup beams, the second "AP"/"PA" setup beams.
    """
    cbs, aps = OrderedDict(), OrderedDict()

    # Check each setup beam to see if it is CB
    for setup_beam in beam_set.PatientSetup.SetupBeams:
        # Is it "CB"?
        ssd = setup_beam_ssd(setup_beam, r'CB(CT)?')
        if ssd is None:
            # Not "CB", so is it "AP"/"PA"?
            ssd = setup_beam_ssd(setup_beam, pos)
            if ssd is not None:
                aps[setup_beam] = ssd
        else:
            cbs[setup_beam] = ssd
    return cbs, aps

def output_filepath(beam_set: PyScriptObject) -> str:
    """Creates an output filename for the shifts TXT file for the beam set

    TXT file is in `OUTPUT_DIR`
    Filename is in the format "<beam set ID> Shifts Comments YYYY-MM-DD HH:MM:SS.txt"
    The colon in the beam set ID is replaced with a hyphen for Windows filename compatibility

    Arguments
    ---------
    beam_set: The beam set to return an output filepath for

    Returns
    -------
    The absolute filepath of the TXT file to create

    Example
    -------
    output_filepath(some_beam_set) -> 'My\Output\Dir\plan name-beam set name 2022-05-04 16_15_30.txt'
    """
    dt = datetime.now().strftime('%Y-%m-%d %H_%M_%S')
    bs_id = '-'.join(beam_set.BeamSetIdentifier().split(':'))
    filename = bs_id + ' Shifts Comments ' + dt + '.txt'
    filename = re.sub(r'[<>:"/\\\|\?\*]', '_', filename)
    return os.path.join(OUTPUT_DIR, filename)

def generate_shifts_comments(include_msq_shifts: Optional[bool] = False) -> None:
    """Creates and opens a TXT file listing patient shifts (couch shifts, MOSAIQ Site Setup shifts) and CB/AP/PA setup SSD if applicable.
    The MOSAIQ Setup Shifts are the same as the couch setup shifts but using the opposite directional term (e.g., "Posterior" if the couch shift is "Anterior").

    If there is no shift, writes "No setup shifts" instead of the couch shift.
    If there is a single CB setup beam, uses it. Otherwise, if there is a single AP (for supine) / PA (for prone) setup beam, uses it. Otherwise, alerts the user and exits the script.

    Assumes that CB setup beam name or description contains "CB" or "CBCT" (case insensitive) and that other AP/PA setup beam names or descriptions contain "AP" or "PA" (case insensitive).

    Arguments
    include_msq_shifts: True to include the MOSAIQ Setup Shifts, False otherwise.
                        Defaults to False.
    """
    # Get current beam set
    try:
        beam_set = get_current('BeamSet')
    except:
        MessageBox.Show('There is no beam set loaded. Click OK to abort the script.', 'No Beam Set Loaded')
        sys.exit()

    # Ensure beam set has beam(s)
    if beam_set.Beams.Count == 0:
        MessageBox('There are no beams in the current beam set.\nClick OK to abort the script.', 'No Beams')
        sys.exit()

    # Localization geometry
    loc_geom = beam_set.GetStructureSet().LocalizationPoiGeometry
    if loc_geom.Point is None or loc_geom.Point.x == float('inf'):
        MessageBox.Show('There is no localization geometry on the planning exam.\nClick OK to abort the script.', 'No Localization Geometry')
        sys.exit()
    loc_geom = loc_geom.Point

    # Beam set isocenter
    isos = [beam.Isocenter.Position for beam in beam_set.Beams]
    # Ensure all beam isos have same coordinates
    if len(set((iso.x, iso.y, iso.z) for iso in isos)) > 1:
        MessageBox.Show('Beams in beam set have different isocenter coordinates.\nClick OK to abort the script.', 'Beam Isos Differ')
        sys.exit()
    iso = isos[0]  # All isos have same position, so doesn't matter which one we use

    # Calculate shifts = localization geometry minus isocenter
    x, y, z = (loc_geom[dim] - iso[dim]
               for dim in 'xyz')

    # ----------------------------- Shift directions ----------------------------- #

    # "Left" or "Right"
    if x < 0:
        couch_r_l = 'Right'
        msq_r_l = 'Left'
    else:
        couch_r_l = 'Left'
        msq_r_l = 'Right'

    # "Superior" or "Inferior"
    if z < 0:
        couch_i_s = 'Inferior'
        msq_i_s = 'Superior'
    else:
        couch_i_s = 'Superior'
        msq_i_s = 'Inferior'

    # "Posterior" or "Anterior"
    if y < 0:
        couch_p_a = 'Anterior'
        msq_p_a = 'Posterior'
    else:
        couch_p_a = 'Posterior'
        msq_p_a = 'Anterior'

    # Round and format shifts
    x, y, z = (fmt_num(abs(shift), 0.1) for shift in (x, y, z))

    # Add couch shifts to comments
    comments = '1. Align to initial CT marks\n'
    if x == y == z == '0':
        comments += 'No setup shifts'
    else:
        comments += f'2. Shift couch so PATIENT is moved: {couch_r_l} {x} cm (patient\'s right/left), {couch_i_s} {z} cm, {couch_p_a} {y} cm'

    # CB setup SSD
    pos = 'AP' if 'Supine' in beam_set.PatientPosition else 'PA'
    cbs, aps = cb_setup_beams(beam_set, pos)  # All CB or AP/PA (depending on pt position) setup beams
    ssd = None
    if len(cbs) > 1:  # Multiple CB setup beams
        if len(aps) > 1:  # Multiple AP/PA setup beams
            MessageBox.Show('There are multiple CB and multiple ' + pos + ' setup beams, and the script doesn\'t know which one to use. Click OK to abort the script.', 'Multiple CB/' + pos + ' Setup Beams')
            sys.exit()
        elif not aps:  # No AP/PA setup beams
            MessageBox.Show('There are multiple CB setup beams and no other ' + pos + ' setup beams, and the script doesn\'t know which one to use. Click OK to abort the script.', 'Multiple CB Setup Beams')
            sys.exit()
        else:  # Exactly 1 AP/PA setup beam
            MessageBox.Show('There are multiple CB and one other ' + pos + ' setup beam, and the script doesn\'t know which one to use. Click OK to abort the script.', 'Multiple CB/' + pos + ' Setup Beams')
            sys.exit()
    elif cbs:  # Exactly 1 CB setup beam, so use it
        ssd = list(cbs.values())[0]
    elif aps:  # At least one AP/PA setup beam
        if len(aps) > 1:  # Multiple AP/PA setup beams
            MessageBox.Show('There are multiple ' + pos + ' setup beams and no other CB setup beams, and the script doesn\'t know which one to use. Click OK to abort the script.', 'Multiple ' + pos + ' Setup Beams')
            sys.exit()
        else:  # Exactly 1 AP/PA setup beam, so use it
            ssd = list(aps.values())[0]
    else:  # No CB or other AP/PA setup beams
        MessageBox.Show('There are no CB or other ' + pos + ' setup beams. Click OK to abort the script.', 'No CB/' + pos + ' Setup Beams')
        sys.exit()
    comments += '\n' + pos + ' setup SSD: ' + fmt_num(ssd, 0.25)

    # Add MOSAIQ site setup shifts to comments
    if include_msq_shifts:
        comments += '\n\nMOSAIQ Site Setup shifts:\n' \
                 + f'{msq_r_l} {x} cm, {msq_i_s} {z} cm, {msq_p_a} {y} cm'

    # Write comments to file
    if not os.path.isdir(OUTPUT_DIR):
        os.makedirs(OUTPUT_DIR)
    filepath = output_filepath(beam_set)
    with open(filepath, 'w') as f:
        f.write(comments)

    # Open comments file
    os.system('START /B notepad.exe "' + filepath + '"')


from typing import List

class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:
        if not grid:
            return 0
        m, n = len(grid), len(grid[0])
        answer = 0

        def dfs(i, j):
            grid[i][j] = '2'
            for di, dj in (0, 1), (0, -1), (1, 0), (-1, 0):
                ii, jj = i + di, j + dj
                if 0 <= ii < m and 0 <= jj < n and grid[ii][jj] == '1':
                    dfs(ii, jj)
        for i in range(m):
            for j in range(n):
                if grid[i][j] == '1':
                    dfs(i, j)
                    answer += 1
        return answer

if __name__ == '__main__':

    # Inputs and Expected Outputs
    grid_1 = [
        ["1", "1", "1", "1", "0"],
        ["1", "1", "0", "1", "0"],
        ["1", "1", "0", "0", "0"],
        ["0", "0", "0", "0", "0"]
    ]
    expected_output_1 = 1

    grid_2 = [
        ["1", "1", "0", "0", "0"],
        ["1", "1", "0", "0", "0"],
        ["0", "0", "1", "0", "0"],
        ["0", "0", "0", "1", "1"]
    ]
    expected_output_2 = 3

    # Run Tests
    solution_1 = Solution()
    solution_2 = Solution()
    test_1 = solution_1.numIslands(grid_1)
    test_2 = solution_2.numIslands(grid_2)

    # Print Results
    print(f"\nTest 1 Result: {test_1} \nExpected Result: {expected_output_1}")
    print(f"\nTest 2 Result: {test_2} \nExpected Result: {expected_output_2}")


import os
import os.path
import time
from data.dataset import *
import torch.nn as nn
import torch.nn.functional as F

class WaveNetModel(nn.Module):

    def __init__(self, hparams, device):

        super(WaveNetModel, self).__init__()

        self.layers = hparams.layers
        self.blocks = hparams.blocks
        self.dilation_channels = hparams.dilation_channels
        self.residual_channels = hparams.residual_channels
        self.skip_channels = hparams.skip_channels
        self.input_channel = hparams.input_channel
        self.initial_kernel = hparams.initial_kernel
        self.kernel_size = hparams.kernel_size
        self.output_channel = hparams.output_channel
        self.bias = hparams.bias

        self.device = device
        # build model
        receptive_field = 1
        init_dilation = 1

        self.dilated_convs = nn.ModuleList()

        self.residual_convs = nn.ModuleList()
        self.skip_convs = nn.ModuleList()

        # 1x1 convolution to create channels
        self.start_conv = nn.Conv1d(in_channels=self.input_channel,
                                    out_channels=self.residual_channels,
                                    kernel_size=self.initial_kernel,
                                    bias=self.bias)

        for b in range(self.blocks):
            additional_scope = self.kernel_size - 1
            new_dilation = 1
            actual_layer = self.layers
            if b == self.blocks-1:
                actual_layer = self.layers - 1
            for i in range(actual_layer):

                # dilated convolutions
                self.dilated_convs.append(nn.Conv1d(in_channels=self.residual_channels,
                                                    out_channels=self.dilation_channels*2,
                                                    kernel_size=self.kernel_size,
                                                    bias=self.bias,
                                                    dilation=new_dilation))

                # 1x1 convolution for residual connection
                self.residual_convs.append(nn.Conv1d(in_channels=self.dilation_channels,
                                                     out_channels=self.residual_channels,
                                                     kernel_size=1,
                                                     bias=self.bias))

                # 1x1 convolution for skip connection
                self.skip_convs.append(nn.Conv1d(in_channels=self.dilation_channels,
                                                 out_channels=self.skip_channels,
                                                 kernel_size=1,
                                                 bias=self.bias))

                receptive_field += additional_scope
                additional_scope *= 2
                init_dilation = new_dilation
                new_dilation *= 2

        self.end_conv = nn.Conv1d(in_channels=self.skip_channels,
                                  out_channels=self.output_channel,
                                  kernel_size=1,
                                  bias=self.bias)

        self.receptive_field = receptive_field + self.initial_kernel - 1

    def forward(self, input):

        x = self.start_conv(input)
        skip = 0

        # WaveNet layers
        for i in range(self.blocks * self.layers - 1):

            # |----------------------------------------------------|     *residual*
            # |                                                    |
            # |                |---- tanh --------|                |
            # -> dilate_conv ->|                  * ----|-- 1x1 -- + -->	*input*
            #                  |---- sigm --------|     |
            #                                          1x1
            #                                           |
            # ----------------------------------------> + ------------->	*skip*

            residual = x

            dilated = self.dilated_convs[i](x)

            filter, gate = torch.chunk(dilated, 2, dim=1)

            # dilated convolution
            filter = torch.tanh(filter)
            gate = torch.sigmoid(gate)
            x = filter * gate

            # parametrized skip connection
            s = x
            s = self.skip_convs[i](s)
            try:
                skip = skip[:, :, -s.size(2):]
            except:
                skip = 0
            skip = s + skip

            x = self.residual_convs[i](x)
            x = x + residual[:, :, -x.size(2):]

        x = torch.relu_(skip)
        x = self.end_conv(x)

        return x

    def parameter_count(self):
        par = list(self.parameters())
        s = sum([np.prod(list(d.size())) for d in par])
        return s

    def get_phonetic(self, input):

        real_length = input.shape[1]
        to_pad = int(self.receptive_field / 2)
        data = np.pad(input, ((0, 0), (to_pad, to_pad)), 'constant', constant_values=0)

        preds = []
        raw_out = []
        for i in range(real_length):
            model_input = data[:, i:i+self.receptive_field]
            model_input = torch.FloatTensor(model_input).unsqueeze(0).to(self.device)
            out = self.forward(model_input)
            raw_out.append(out.detach().squeeze())
            pred = out.max(1)[1]
            preds.append(pred.squeeze())

        return preds, raw_out


import argparse
import os
from collections import namedtuple

def cli_parser(prog="convert_hb_to_dance.py"):
    parser = argparse.ArgumentParser(prog = prog, description="convert hb list to dance file")
    parser.add_argument("top", type=str, nargs=1, help="Topology file")
    parser.add_argument("hb_design", type=str, nargs=1, help="The hb design")
    parser.add_argument("hb_list", type=str, nargs=1, help="The hb list from the trajectory")
    parser.add_argument("output_file", type=str, nargs=1, help="Name of the dance file to output")

    return parser

NT = namedtuple("NT", "strand_id base_type end3 end5 id_on_strand")
Strand = namedtuple("Strand", "length sequence")

def get_nt_dict(top_file: str) -> dict:
    nt_dict = {}

    with open(top_file, 'rt') as top:
        top.readline()

        nt_id = 0
        line = top.readline()
        while line:
            tokens = line.split()

            # put the NT to dict
            strand_id = int(tokens[0])
            base_type = tokens[1]
            end3 = int(tokens[2])
            end5 = int(tokens[3])

            # id_on_strand default to -2
            # because -1 is used in end3 and end5 as end indication
            nt_dict[nt_id] = NT(strand_id, base_type, end3, end5, -2)

            nt_id += 1
            line = top.readline()

    return nt_dict

def change_nt_id_on_strand(nt: NT, id_on_strand: int) -> NT:
    nt = NT(nt.strand_id, nt.base_type, nt.end3, nt.end5, id_on_strand)
    return nt

def get_strand_dict(nt_dict: dict) -> dict:
    visited_nt = set()
    strand_dict = {}

    for nt in nt_dict:
        if nt not in visited_nt:
            # Find end3
            # This requires non-circular topology
            strand_head_id = nt
            end3 = nt_dict[strand_head_id].end3

            # If the current nt's end3 is not -1,
            # Make the nt's end3 the strand_head_id and check again
            while end3 != -1:
                strand_head_id = end3
                end3 = nt_dict[strand_head_id].end3

            # Now we have the strand_head_id
            # We trace end5 to get the whole sequence

            strand_dict[nt_dict[strand_head_id].strand_id] = Strand(1, nt_dict[strand_head_id].base_type)
            nt_dict[strand_head_id] = change_nt_id_on_strand(nt_dict[strand_head_id], 0)
            visited_nt.add(strand_head_id)
            end5 = nt_dict[strand_head_id].end5
            while end5 != -1:
                strand_head_id = end5
                new_len = strand_dict[nt_dict[strand_head_id].strand_id].length + 1
                new_seq = strand_dict[nt_dict[strand_head_id].strand_id].sequence + nt_dict[strand_head_id].base_type
                nt_dict[strand_head_id] = change_nt_id_on_strand(nt_dict[strand_head_id], new_len - 1)  # -1 is because this index is 0-based
                strand_dict[nt_dict[strand_head_id].strand_id] = Strand(new_len, new_seq)
                visited_nt.add(strand_head_id)
                end5 = nt_dict[strand_head_id].end5

    return strand_dict

def parse_hb_design(hb_design: str, nt_dict: dict) -> list:
    hb_design_str_list = ["## Target_bonding_configuration\n"]

    with open(hb_design, 'rt') as hb_handle:
        line = hb_handle.readline()
        line = hb_handle.readline()
        while line:
            nt_1, nt_2 = [int(i) for i in line.split()]
            nt_1_str = str(nt_dict[nt_1].strand_id) + ".1." + str(nt_dict[nt_1].id_on_strand)
            nt_2_str = str(nt_dict[nt_2].strand_id) + ".1." + str(nt_dict[nt_2].id_on_strand)
            hb_design_str_list.append(nt_1_str + "\t" + nt_2_str + "\n")
            line = hb_handle.readline()

    hb_design_str_list.append("\n")

    return hb_design_str_list

def parse_hb_list(hb_list: str, nt_dict: dict, strand_dict: dict) -> [list, list]:
    header_str_list = []
    hb_dance_str_list = ["## Bonding_info\n\n"]

    current_step = 0
    print_conf_interval = 0

    with open(hb_list, 'rt') as hb_handle:
        line = hb_handle.readline()
        while line:
            if line.startswith("#"):
                hb_dance_str_list.append(line)

                # get print_conf_interval
                # sanity check: all print_conf_interval should be the same
                if print_conf_interval == 0 and current_step > 0:
                    print_conf_interval = int(line.split()[2]) - current_step
                elif print_conf_interval > 0:
                    if not int(line.split()[2]) - current_step == print_conf_interval:
                        raise Exception("print_conf_interval inconsistent at:", line.split()[2])

                current_step = int(line.split()[2])
                line = hb_handle.readline()
            elif line.startswith("\n"):
                hb_dance_str_list.append("\n")
                line = hb_handle.readline()
            elif line[0].isdigit():
                nt_1, nt_2 = [int(i) for i in line.split()]
                nt_1_str = str(nt_dict[nt_1].strand_id) + ".1." + str(nt_dict[nt_1].id_on_strand)
                nt_2_str = str(nt_dict[nt_2].strand_id) + ".1." + str(nt_dict[nt_2].id_on_strand)
                hb_dance_str_list.append(nt_1_str + "\t" + nt_2_str + "\n")
                line = hb_handle.readline()
            else:
                raise Exception("Unexpected line:", line)

    # add template
    header_str_list.append("## Header_for_metadata\n")
    header_str_list.append("# one_step_in_physical_time = 3.03 ps\n")
    header_str_list.append("# steps = " + str(current_step) + "\n")
    header_str_list.append("# print_conf_interval = " + str(print_conf_interval) + "\n")
    header_str_list.append("## strand_sequence_start\n")

    # add sequence
    for i in range(1, len(strand_dict) + 1):
        header_str_list.append("# " + str(i) + ":1:" + str(strand_dict[i].length) + ":" + strand_dict[i].sequence + "\n")

    header_str_list.append("## strand_sequence_stop\n")
    header_str_list.append("\n")

    return header_str_list, hb_dance_str_list

def main():
    parser = cli_parser(os.path.basename(__file__))
    args = parser.parse_args()
    top_file = args.top[0]
    hb_design = args.hb_design[0]
    hb_list = args.hb_list[0]
    output_file = args.output_file[0]

    nt_dict = get_nt_dict(top_file)
    strand_dict = get_strand_dict(nt_dict)

    # parse hb_list
    header_str_list, hb_dance_str_list = parse_hb_list(hb_list, nt_dict, strand_dict)

    hb_design_str_list = parse_hb_design(hb_design, nt_dict)

    with open(output_file, 'wt') as out_handle:
        out_handle.write("".join(header_str_list))
        out_handle.write("".join(hb_design_str_list))
        out_handle.write("".join(hb_dance_str_list))
    print("Done!\n===\n")

if __name__ == '__main__':
    main()


import re
from datetime import datetime, timedelta
import logging

import statsapi

from .build_game import GameBuilder
from .draw_scorecard import DrawScorecard

if __name__ == '__main__':
    logging.basicConfig(  # filename='parsing.log',
                        format='%(levelname)s:%(message)s',
                        level=logging.INFO)

    game_builder = GameBuilder()
    draw_scorecard = DrawScorecard()

    start_date = datetime(2018, 10, 5)
    for date in [start_date + timedelta(days=x) for x in range(0, 200)]:
        games = statsapi.schedule(
            start_date='%d/%d/%d' % (date.month, date.day, date.year))

        for game_dict in games:
            logging.info('Processing %d %s %s vs. %s', game_dict['game_id'],
                         game_dict['game_date'], game_dict['away_name'],
                         game_dict['home_name'])
            game = game_builder.build(game_dict['game_id'])
            drawing = draw_scorecard.draw(game)
            drawing.saveas('test.svg')

            #for inning in game:
            #    print(inning)
            #    for half in inning:
            #        print(half)
            #        for atbat in half:
            #            print(atbat)
            #            for runner in atbat.mid_pa_runners:
            #                print(runner, 'mid-pa')
            #            for runner in atbat.runners:
            #                print(runner)
            #input('Done')


import os,sys,string,traceback,random,glob,json,datetime
from flask import Flask, render_template, request, send_from_directory, redirect, jsonify

os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = './private/twitter-261302-f4efec35fd83.json'
from google.cloud import bigquery
import twitter
from tool import strdt, strd, strpt
import Manager

app = Flask(__name__)
m = Manager.Manager('./private/production.json')

@app.route('/')
def get_index():
    tweets = m.get_timeline()

    context = { 'title':"Current tweets.", 'tweets': tweets }
    return render_template('index.html', **context)

@app.route('/status', methods=['POST'])
def post_status():
    if request.method == 'POST':
        text = request.form['content']
        m.post_status(text)
    return redirect('/')

@app.route('/info', methods=['GET'])
def get_info():
    bq = json.load(open('./private/production.json', 'r'))
    days3 = datetime.datetime.now() - datetime.timedelta(days=3)
    client = bigquery.Client()

    sql = "SELECT FORMAT_DATETIME('%H', `at_created`) as hours, COUNT(*) as cnt FROM `{}` WHERE `at_created` > '{}' AND `by_year_month` >= {} GROUP BY hours ORDER BY hours".format(bq["table"], strd(days3), strpt(days3))
    print("sql=", sql)
    rates = []
    for row in client.query(sql).result():
        rates.append(row)

    sql = "SELECT `name`, MAX(`volume`) as _sum FROM `{}` WHERE `at_created` > '{}' GROUP BY name ORDER BY _sum DESC LIMIT 10".format(bq["trend_table"], strd(days3))
    print("sql=", sql)
    trends = []
    for row in client.query(sql).result():
        trends.append(row)

    context = { 'title':"info", 'rates_of_tweets':rates, 'trends':trends }
    return render_template('info.html', **context)

@app.route('/update.json')
def get_update():
    rows = m.get_timeline(max_id=m.get_max_id())
    m.insert_rows_origin(m.filter_for_bq_timeline(rows))

    return jsonify({'result':'ok', 'rows':len(rows)})

@app.route('/trends.json')
def get_trends():
    trends = m.get_trends()
    m.insert_rows_trend(trends)

    m.insert_rows_samples(m.get_search(['#VRChat', '#VRC']))
    m.insert_rows_samples(m.get_search('#Cluster'))
    m.insert_rows_samples(m.get_search('#VRC撮影の集い'))

    return jsonify({'result':'ok', 'trends':len(trends)})

if __name__ == "__main__":
    app.run(debug=True,host='0.0.0.0',port=8080)


import pygame
import random
import os
import time
import os

def resource_path(relative_path):
    try:
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.abspath(".")

    return os.path.join(base_path, relative_path)

pygame.init()

# screen settings
screen_width = 870
screen_height = 970
screen = pygame.display.set_mode((screen_width, screen_height))

# imgaes setting
current_path = os.path.dirname(__file__)
image_path = os.path.join(current_path, "images")

background = pygame.image.load(os.path.join(image_path, "background.png"))

# character
character = pygame.image.load(os.path.join(image_path, "character.png"))
character_mask = pygame.mask.from_surface(character)
character_x_pos = 20
character_y_pos = 220
to_x = 0
to_y = 0

# Tiles and colors
tile_images =[
    pygame.image.load(os.path.join(image_path, "tile1.png")),
    pygame.image.load(os.path.join(image_path, "tile2.png")),
    pygame.image.load(os.path.join(image_path, "tile3.png")),
    pygame.image.load(os.path.join(image_path, "tile4.png")),
    pygame.image.load(os.path.join(image_path, "tile5.png")),
    pygame.image.load(os.path.join(image_path, "tile6.png")),
    pygame.image.load(os.path.join(image_path, "tile7.png"))
]

colors = ["Red", "Orange", "Yellow", "Green", "Blue", "Indigo", "Purple"]

hidetile = pygame.image.load(os.path.join(image_path, "hidetile.png"))

tiles = []

pygame.display.set_caption("Mark Game")

# Font
game_font = pygame.font.Font(None, 40)

# Tracking variables
memorize = True
find = False
answer = False
correct = False
level = 1
memorize_time = 15
find_time = 10
check_time = 5
start_ticks = pygame.time.get_ticks()
elapsed_time = 0
action = ""
timer = ""
target_color = -1
difficulty = 0
color_number = 3
difficulty_changed = False
win = False

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        if (not answer) and event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                character_x_pos -= 110
            elif event.key == pygame.K_RIGHT:
                character_x_pos += 110
            elif event.key == pygame.K_UP:
                character_y_pos -= 110
            elif event.key == pygame.K_DOWN:
                character_y_pos += 110

        if (not answer) and event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                to_x = 0
            elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                to_y = 0

    if character_x_pos < 20:
        character_x_pos = 20
    elif character_x_pos > 790:
        character_x_pos = 790

    if character_y_pos < 220:
        character_y_pos = 220
    elif character_y_pos > 880:
        character_y_pos = 880

    # Change Difficulty
    if level % 3 == 0 and not difficulty_changed:
        difficulty += 1
        memorize_time = 15
        if color_number < 7:
            color_number += 1
        difficulty_changed = True

    if len(tiles) == 0:
        for i in range(0, 56):
            col = i % 8
            row = i // 8
            tiles.append({
                "img": tile_images[random.randrange(0, color_number)],
                "x_pos": col * 110,
                "y_pos": 200 + (row * 110)
            })

    # draw screen

    # Background
    screen.blit(background, (0, 0))

    # timer
    elapsed_time = (pygame.time.get_ticks() - start_ticks) / 1000
    if memorize:
        if (memorize_time - elapsed_time) <= 0 :
            memorize = False
            find = True
            target_color = random.randrange(0, color_number)
            start_ticks = pygame.time.get_ticks()
    elif find:
        if (find_time - elapsed_time) <= 0:
            find = False
            answer = True
            start_ticks = pygame.time.get_ticks()
    elif answer:
        if (check_time - elapsed_time) <= 0:
            answer = False
            memorize = True
            correct = False
            tiles.clear()
            level += 1
            memorize_time -= 5
            start_ticks = pygame.time.get_ticks()
            difficulty_changed = False

    # check answer
    if answer and (not correct):
        for t in tiles:
            tile_mask = pygame.mask.from_surface(t["img"])
            offset = (int(character_x_pos - t["x_pos"]), int(character_y_pos - t["y_pos"]))
            result = tile_mask.overlap(character_mask, offset)
            if result and t["img"] == tile_images[target_color]:
                correct= True
                break

    if memorize:
        action = game_font.render("Memorize the Colors and their Positions!",\
             True, (255, 255, 255))
        timer = game_font.render("Time Left: {}".format(int(memorize_time - elapsed_time)),\
             True, (255, 255, 255))
    elif find:
        action = game_font.render("Find the correct Color! The color is {}"\
             .format(colors[target_color]), True, (255, 255, 255))
        timer = game_font.render("Time Left: {}".format(int(find_time - elapsed_time))\
             , True, (255,255,255))
    elif answer and correct and level == 17:
        action = game_font.render("You are Correct!", True, (0, 255, 0))
        timer = game_font.render("You have finished all the levels! Congrats!!", True, (0, 255, 0))
        running = False
        win = True
    elif answer and correct:
        action = game_font.render("You are Correct!", True, (0, 255, 0))
        timer = game_font.render("Next round begins in: {}".format(int(check_time - elapsed_time)),\
             True, (255, 255, 255))
    elif answer and (not correct):
        action = game_font.render("Your answer is Wrong", True, (255, 0, 0))
        running = False

    level_display = game_font.render("Level {}".format(level), True, (255, 255, 255))
    difficulty_display = game_font.render("Difficulty : {}".format(difficulty), True, (255, 255, 255))
    screen.blit(level_display, (380, 10))
    screen.blit(difficulty_display, (670, 120))
    screen.blit(action, (20, 60))
    screen.blit(timer, (20, 90))

    # Tiles
    if memorize:
        for idx, val in enumerate(tiles):
            tile_img = val["img"]
            tile_x = val["x_pos"]
            tile_y = val["y_pos"]
            screen.blit(tile_img, (tile_x, tile_y))
    elif answer:
        for idx, val in enumerate(tiles):
            tile_img = val["img"]
            tile_x = val["x_pos"]
            tile_y = val["y_pos"]
            if tile_images[target_color] == tile_img:
                screen.blit(tile_img, (tile_x, tile_y))
            else:
                screen.blit(hidetile, (tile_x, tile_y))
    else:
        for i in range(0, 56):
            col = i % 8
            row = i // 8
            screen.blit(hidetile, ((col * 110), 200 + (row * 110)))

    screen.blit(character, (character_x_pos, character_y_pos))

    pygame.display.update()

game_font = pygame.font.Font(None, 100)
if win:
    msg = game_font.render("You Won!!", True, (0, 0, 0))
else:
    msg = game_font.render("Game Over", True, (0, 0, 0))

msg_rect = msg.get_rect(center=(int(screen_width/2), int(screen_height/2)))
screen.blit(msg, msg_rect)
pygame.display.update()
pygame.time.delay(4000)

pygame.quit()


from FileGenerator import AbstractBaseFileGenerator
from generation.GrammarTemplate import GrammarTemplate
import random
from mutation.mutations import Mutation3Choices
from typing import Union

class GrammarFileGenerator(AbstractBaseFileGenerator.AbstractBaseFileGenerator):

    def __init__(self, grammar_file_path: str, json_schema_file_path: str, mutation_number: Union[int, None]):
        self.mutation_number = mutation_number
        self.grammar_file_path = grammar_file_path
        self.json_schema_file_path = json_schema_file_path
        self.grammar_template = GrammarTemplate(self.grammar_file_path, self.json_schema_file_path)
        self.mutator = Mutation3Choices()

    def generateData(self):
        data = bytearray(self.grammar_template.create_data())
        if self.mutation_number is not None:
            data = self.mutator.mutateCycles(data, self.mutation_number)

        return bytes(data)

    def generateFile(self, path: str):
        self.grammar_template.create_file(path)


import wikipedia
import nltk
class WikiPedia():

    def getDefinition(self, sentence):

        tries = 0
        x = nltk.word_tokenize(sentence)
        w=0

        while tries < 4: #since wikipedia has many different idintefiers for webpages, this while loop tries different forms of the sentence to get an accurate match
            try:
                if(tries == 0):
                    return(wikipedia.summary(sentence + "(mood)",sentences = 1)) #attempts to put the word "mood" in the sentence to avoid other sorts of non related words
                    break   #also prints the summary of the found webpage, first 3 sentences only as it will be too big otherwise.
                elif(tries == 1):
                    return(wikipedia.summary(x[len(x)-1],sentences = 1)) #attemtps to only use the last word in the sentence
                    break
                elif (tries == 2): #attempts to use the first word in the sentence
                    return(wikipedia.summary(x[0],sentences = 1))
                    break
                elif (tries == 3): #uses wikipedias suggest to get another similar word and then searches in wikipedia
                    w = wikipedia.suggest(sentence)
                    return(summary(w,sentences = 1))
                    break
                tries = tries + 1
            except: #since an error is produced if there are too many results found, exception must be used
                 tries = tries + 1

        if tries == 4: #returns false if no information was found
            return False


from abc import abstractmethod, ABCMeta
from typing import List, Union
from app.dto.subject_dto import *
from app.models import Subject

class SubjectRepository(metaclass=ABCMeta):
    @abstractmethod
    def create_subject(self, model: CreateSubjectDto):
        """Create Subject Object"""
        raise NotImplementedError

    @abstractmethod
    def edit_subject(self, subject_id: int, model: EditSubjectDto):
        """Edit Subject Object"""
        raise NotImplementedError

    @abstractmethod
    def list_subjects(self) -> List[ListSubjectDto]:
        """List Subject Objects"""
        raise NotImplementedError

    @abstractmethod
    def get_subject(self, subject_id: int) -> Union[GetSubjectDto, bool]:
        """Get Subject Object"""
        raise NotImplementedError

class DjangoORMSubjectRepository(SubjectRepository):
    def create_subject(self, model: CreateSubjectDto):
        subject = Subject()
        subject.id = model.id
        subject.subject_name = model.subject_name
        subject.save()

    def edit_subject(self, subject_id: int, model: EditSubjectDto):
        try:
            subject = Subject.objects.get(id=subject_id)
            subject.subject_name = model.subject_name
            subject.save()
        except Subject.DoesNotExist as e:
            return e

    def list_subjects(self) -> List[ListSubjectDto]:
        subjects = Subject.objects.all()
        result: List[ListSubjectDto] = []
        for subject in subjects:
            item = ListSubjectDto()
            item.subject_name = subject.subject_name
            result.append(item)
        return result

    def get_subject(self, subject_id: int) -> Union[GetSubjectDto, bool]:
        try:
            subject = Subject.objects.get(id=subject_id)
            item = GetSubjectDto()
            item.id = subject.id
            item.subject_name = subject.subject_name
            return item
        except Subject.DoesNotExist as e:
            return e