# coding=utf-8

from __future__ import division
from design.MainData import MainData
from canvas import *
from algorithm import *
from PyQt5.QtCore import Qt
from PyQt5.QtGui import (QIcon, QFont)
from PyQt5.QtWidgets import (qApp,
                             QAction,
                             QComboBox,
                             QDesktopWidget,
                             QFileDialog,
                             QGridLayout,
                             QInputDialog,
                             QRadioButton,
                             QLabel,
                             QLCDNumber,
                             QMainWindow,
                             QMessageBox,
                             QPushButton,
                             QSpinBox,
                             QTableWidget,
                             QTableWidgetItem,
                             QTabWidget,
                             QTextEdit,
                             QToolTip,
                             QWidget)

# noinspection PyNonAsciiChar
class App(QMainWindow, MainData):
    """
    @
    """

    # noinspection PyArgumentList,PyMissingConstructor
    def __init__(self):
        # noinspection PyCompatibility
        QMainWindow.__init__(self)

        # noinspection PyCallByClass,PyTypeChecker
        QToolTip.setFont(QFont('SansSerif', 10))
        self.setGeometry(100, 100, 900, 550)
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())
        self.setWindowTitle('MathDemo')
        self.setWindowIcon(QIcon('python.png'))
        self.setWindowFlags(Qt.WindowStaysOnTopHint)

        self.actionLoad()

        self.menuBarLoad()

        #############################################
        # set current image that you are operating. #
        #############################################
        self.currentImage = ""
        self.rainImage()

        self.statusBar().showMessage('Ready')

        self.show()

    def actionLoad(self):
        """
        set MainData.action
        """

        self.action["showOpenDialog"] = QAction('Open File', self)
        self.action["showOpenDialog"].setIcon(QIcon('open.png'))
        self.action["showOpenDialog"].setShortcut('Ctrl+O')
        self.action["showOpenDialog"].setStatusTip('Open File')
        self.action["showOpenDialog"].triggered.connect(self.showOpenDialog)

        self.action["qApp.quit"] = QAction('Exit application', self)
        self.action["qApp.quit"].setIcon(QIcon('exit.jpg'))
        self.action["qApp.quit"].setShortcut('Ctrl+Q')
        self.action["qApp.quit"].setStatusTip('Exit application')
        self.action["qApp.quit"].triggered.connect(qApp.quit)

        self.action["orthogonalTableImage"] = QAction('Orthogonal Table', self)
        self.action["orthogonalTableImage"].setIcon(QIcon('numpy_logo.jpg'))
        self.action["orthogonalTableImage"].setShortcut('Ctrl+T')
        self.action["orthogonalTableImage"].setStatusTip('Orthogonal Table')
        self.action["orthogonalTableImage"].triggered.connect(self.orthogonalTableImage)

        self.action["convexHullImage"] = QAction('Convex Hull', self)
        self.action["convexHullImage"].setIcon(QIcon('numpy_logo.jpg'))
        self.action["convexHullImage"].setShortcut('Ctrl+C')
        self.action["convexHullImage"].setStatusTip('Convex Hull')
        self.action["convexHullImage"].triggered.connect(self.convexHullImage)

        self.action["gravitationalSystemImage"] = QAction('Gravitational System', self)
        self.action["gravitationalSystemImage"].setIcon(QIcon('scipy_logo.jpg'))
        self.action["gravitationalSystemImage"].setShortcut('Ctrl+G')
        self.action["gravitationalSystemImage"].setStatusTip('Gravitational System')
        self.action["gravitationalSystemImage"].triggered.connect(self.gravitationalSystemImage)

        self.action["analyticFunctionImage"] = QAction('Analytic Function', self)
        self.action["analyticFunctionImage"].setIcon(QIcon('numpy_logo.jpg'))
        self.action["analyticFunctionImage"].setShortcut('Ctrl+A')
        self.action["analyticFunctionImage"].setStatusTip('Analytic Function')
        self.action["analyticFunctionImage"].triggered.connect(self.analyticFunctionImage)

        self.action["sourceCodeImage"] = QAction('Source Code', self)
        self.action["sourceCodeImage"].setShortcut('F2')
        self.action["sourceCodeImage"].setStatusTip('Source Code')
        self.action["sourceCodeImage"].triggered.connect(self.sourceCodeImage)

    def menuBarLoad(self):
        """
        set MainWindow.menuBar
        """
        self.statusBar()
        menubar = self.menuBar()

        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(self.action["showOpenDialog"])
        fileMenu.addAction(self.action["qApp.quit"])

        statisticsMenu = menubar.addMenu('&Statistics')
        statisticsMenu.addAction(self.action["orthogonalTableImage"])

        statisticsMenu = menubar.addMenu('&Geometry')
        statisticsMenu.addAction(self.action["convexHullImage"])

        statisticsMenu = menubar.addMenu('&Ode')
        statisticsMenu.addAction(self.action["gravitationalSystemImage"])

        statisticsMenu = menubar.addMenu('&Complex')
        statisticsMenu.addAction(self.action["analyticFunctionImage"])

        statisticsMenu = menubar.addMenu('&Help')
        statisticsMenu.addAction(self.action["sourceCodeImage"])

    def controlLayout(self, layout=None, name=None, var=None, position=None, signal=None):
        """
        control layout
        :param layout: GridLayout = QGridLayout()
        :param name: name of control, name is a string
        :param var: var is a dict
        :param position: position is a list with 4 numeric
        :param signal: signal function
        """
        if name == "QLabel":
            # var = {"text": [string]}
            for j in range(0, len(position)):
                self.control[name].append(QLabel(var["text"][j]))
                self.control[name][-1].setAlignment(Qt.AlignCenter)
                # noinspection PyArgumentList
                layout.addWidget(self.control[name][-1], position[j][0], position[j][1], position[j][2], position[j][3])

        if name == "QTabWidget":
            # var = {"text": [[string]], "widget": [[PyQt5.QtWidgets.QWidget]]}
            for j in range(0, len(position)):
                self.control[name].append(QTabWidget())
                for k in range(0, len(var["text"][j])):
                    self.control[name][-1].addTab(var["widget"][j][k], self.tr(var["text"][j][k]))
                # noinspection PyArgumentList
                layout.addWidget(self.control[name][-1], position[j][0], position[j][1], position[j][2], position[j][3])

        if name == "QPushButton":
            # var = {"text": [string]}
            for j in range(0, len(position)):
                self.control[name].append(QPushButton(var["text"][j]))
                # noinspection PyArgumentList
                layout.addWidget(self.control[name][-1], position[j][0], position[j][1], position[j][2], position[j][3])
                if signal is not None:
                    self.control[name][-1].clicked.connect(signal)

        if name == "QTextEdit":
            # var = {"text": [[string]]}
            for j in range(0, len(position)):
                self.control[name].append(QTextEdit())
                if len(var["text"]) != 0:
                    if len(var["text"][j]) != 0:
                        for line in var["text"][j]:
                            self.control[name][-1].append(line)
                # noinspection PyArgumentList
                layout.addWidget(self.control[name][-1], position[j][0], position[j][1], position[j][2], position[j][3])

        if name == "QRadioButton":
            # var = {"text": [string], "isChecked": [bool]}
            for j in range(0, len(position)):
                self.control[name].append(QRadioButton(var["text"][j]))
                self.control[name][-1].setChecked(var["isChecked"][j])
                # noinspection PyArgumentList
                layout.addWidget(self.control[name][-1], position[j][0], position[j][1], position[j][2], position[j][3])
                if signal is not None:
                    self.control[name][-1].clicked.connect(signal)

        if name == "QComboBox":
            # var = {"itemText": [[string]], "currentIndex": [int]}
            for j in range(0, len(position)):
                self.control[name].append(QComboBox())
                self.control[name][-1].addItems(var["itemText"][j])
                if len(var["currentIndex"]) != 0:
                    self.control[name][-1].setCurrentIndex(var["currentIndex"][j])
                # noinspection PyArgumentList
                layout.addWidget(self.control[name][-1], position[j][0], position[j][1], position[j][2], position[j][3])
                if signal is not None:
                    self.control[name][-1].currentIndexChanged.connect(signal)

        if name == "QSpinBox":
            # var = {"range": [[int, int]], "singleStep": [int], "prefix": [string], "suffix": [string], "value": [int]}
            for j in range(0, len(position)):
                self.control[name].append(QSpinBox())
                self.control[name][-1].setRange(var["range"][j][0], var["range"][j][1])
                self.control[name][-1].setSingleStep(var["singleStep"][j])
                if len(var["prefix"]) != 0:
                    if len(var["prefix"][j]) != 0:
                        self.control[name][-1].setPrefix(var["prefix"][j])
                if len(var["suffix"]) != 0:
                    if len(var["suffix"][j]) != 0:
                        self.control[name][-1].setSuffix(var["suffix"][j])
                self.control[name][-1].setValue(var["value"][j])
                # noinspection PyArgumentList
                layout.addWidget(self.control[name][-1], position[j][0], position[j][1], position[j][2], position[j][3])
                if signal is not None:
                    self.control[name][-1].valueChanged.connect(signal)

        if name == "QTableWidget":
            # var = {"headerLabels": [[string]], "data": [numpy.array]}
            for i in range(0, len(position)):
                self.control[name].append(QTableWidget(1, 1))
                if len(var["headerLabels"]) != 0:
                    if len(var["headerLabels"][i]) != 0:
                        self.control[name][-1].setColumnCount(len(var["headerLabels"][i]))
                        self.control[name][-1].setHorizontalHeaderLabels(var["headerLabels"][i])
                if len(var["data"]) != 0:
                    if len(var["data"][i]) != 0:
                        row, column = var["data"][i].shape
                        self.control[name][-1].setRowCount(row)
                        self.control[name][-1].setColumnCount(column)
                        for j in range(0, row):
                            for k in range(0, column):
                                newItem = QTableWidgetItem(str(var["data"][i][j][k]))
                                self.control[name][-1].setItem(j, k, newItem)
                self.control[name][-1].resizeColumnsToContents()
                # noinspection PyArgumentList
                layout.addWidget(self.control[name][-1], position[i][0], position[i][1], position[i][2], position[i][3])

        if name == "QLCDNumber":
            # var = {"value": [int]}
            for j in range(0, len(position)):
                self.control[name].append(QLCDNumber(self))
                if len(var["value"]) != 0:
                    if len(var["value"][j]) != 0:
                        self.control[name][-1].display(var["value"][j])
                    else:
                        self.control[name][-1].display(0)
                # noinspection PyArgumentList
                layout.addWidget(self.control[name][-1], position[j][0], position[j][1], position[j][2], position[j][3])

    def imageRead(self, imageName=None):
        """
        load data into current page, or write data from current page.
        """
        if len(self.control["QRadioButton"]) != 0:
            length = len(self.control["QRadioButton"])
            for j in range(0, length):
                isChecked = self.controlData[imageName]["QRadioButton"]["isChecked"][j]
                self.control["QRadioButton"][j].setChecked(isChecked)

        if len(self.control["QComboBox"]) != 0:
            pass

        if len(self.control["QComboBox"]) != 0:
            length = len(self.control["QComboBox"])
            for j in range(0, length):
                currentIndex = self.controlData[imageName]["QComboBox"]["currentIndex"][j]
                self.control["QComboBox"][j].setCurrentIndex(currentIndex)

        if len(self.control["QSpinBox"]) != 0:
            length = len(self.control["QSpinBox"])
            for j in range(0, length):
                value = self.controlData[imageName]["QSpinBox"]["value"][j]
                self.control["QSpinBox"][j].setValue(value)

        if len(self.control["QTableWidget"]) != 0:
            length = len(self.control["QTableWidget"])
            for i in range(0, length):
                data = self.controlData[imageName]["QTableWidget"]["data"][i]
                row, column = data.shape
                self.control["QTableWidget"][i].setRowCount(row)
                self.control["QTableWidget"][i].setColumnCount(column)
                for j in range(0, row):
                    for k in range(0, column):
                        newItem = QTableWidgetItem(str(data[j][k]))
                        self.control["QTableWidget"][i].setItem(j, k, newItem)
                self.control["QTableWidget"][i].resizeColumnsToContents()

        if len(self.control["QLCDNumber"]) != 0:
            length = len(self.control["QLCDNumber"])
            for j in range(0, length):
                value = self.controlData[imageName]["QLCDNumber"]["value"][j]
                self.control["QLCDNumber"][j].display(value)

    def rainImage(self):
        """
        @
        """
        self.currentImage = "rainImage"
        self.controlClear()

        layout = QGridLayout()
        layout.setSpacing(10)

        # noinspection PyArgumentList
        widget = QWidget()
        self.canvas["rainImage"] = RainCanvas(parent=widget)
        layout.addWidget(self.canvas["rainImage"])

        widget.setLayout(layout)
        self.setCentralWidget(widget)

    def orthogonalTableImage(self):
        """
        layout and initialization data
        """
        ##########################
        # layout of current page #
        ##########################
        self.currentImage = "orthogonalTableImage"
        self.controlClear()

        layout = QGridLayout()
        layout.setSpacing(10)

        text = ['水平数', '重复次数', '实验次数', '因素数']
        position = [[0, 0, 1, 1], [0, 2, 1, 1], [0, 4, 1, 1], [0, 6, 1, 1]]
        self.controlLayout(layout=layout, name="QLabel", var={"text": text}, position=position, signal=None)

        itemText = [list(map(str, range(2, 10))), list(map(str, range(0, 10)))]
        position = [[0, 1, 1, 1], [0, 3, 1, 1]]
        self.controlLayout(layout=layout, name="QComboBox", var={"itemText": itemText, "currentIndex": []},
                           position=position, signal=self.orthogonalTableImageSignal)

        position = [[0, 5, 1, 1], [0, 7, 1, 1]]
        self.controlLayout(layout=layout, name="QLCDNumber", var={"value": []}, position=position, signal=None)

        # noinspection PyArgumentList
        widget = [[QWidget(), QWidget()]]
        for j in range(0, 2):
            widgetLayout = QGridLayout()
            position = [[0, 0, 1, 1]]
            self.controlLayout(layout=widgetLayout, name="QTableWidget", var={"headerLabels": [], "data": []},
                               position=position, signal=None)
            widget[0][j].setLayout(widgetLayout)
        text = [["Table", "Title"]]
        position = [[1, 0, 1, 8]]
        self.controlLayout(layout=layout, name="QTabWidget", var={"text": text, "widget": widget},
                           position=position, signal=None)

        # noinspection PyArgumentList
        widget = QWidget()
        widget.setLayout(layout)
        self.setCentralWidget(widget)

        ###########################################################################
        # initialization self.controlData["orthogonalTableImage"] then refresh it #
        # refresh self.control["orthogonalTableImage"]                            #
        ###########################################################################
        if "orthogonalTableImage" not in self.controlData:
            self.addFrame("orthogonalTableImage")
            self.orthogonalTableImageSignal()
        else:
            for j in range(0, len(self.control["QComboBox"])):
                self.control["QComboBox"][j].currentIndexChanged.disconnect(self.orthogonalTableImageSignal)
            self.imageRead(imageName="orthogonalTableImage")
            for j in range(0, len(self.control["QComboBox"])):
                self.control["QComboBox"][j].currentIndexChanged.connect(self.orthogonalTableImageSignal)

        self.statusBar().showMessage('Ready')

    def orthogonalTableImageSignal(self):
        """
        respond of current page(orthogonalTableImage), then write data into MainData.controlData
        """
        self.statusBar().showMessage('Starting generate table and title...')

        ###########################################################
        # initialization self.controlData["orthogonalTableImage"] #
        ###########################################################
        imageName = "orthogonalTableImage"
        self.controlDataClear(imageName)

        ####################################################
        # refresh self.controlData["orthogonalTableImage"] #
        ####################################################
        for j in range(0, len(self.control["QComboBox"])):
            itemText = list()
            for k in range(0, self.control["QComboBox"][j].count()):
                itemText.append(self.control["QComboBox"][j].itemText(k))
            self.controlData[imageName]["QComboBox"]["itemText"].append(itemText)

            currentIndex = self.control["QComboBox"][j].currentIndex()
            self.controlData[imageName]["QComboBox"]["currentIndex"].append(currentIndex)

        level = int(self.control["QComboBox"][0].currentText())
        time = int(self.control["QComboBox"][1].currentText())
        obj = OrthogonalTableMap(level, time)
        row, column = obj.table.shape

        self.controlData[imageName]["QLCDNumber"]["value"].append(row)
        self.controlData[imageName]["QLCDNumber"]["value"].append(column)

        self.controlData[imageName]["QTableWidget"]["data"].append(obj.table)
        self.controlData[imageName]["QTableWidget"]["data"].append(obj.title)

        self.controlData[imageName]["save"] = [level, time, obj.table, obj.title]

        ################################################
        # refresh self.control["orthogonalTableImage"] #
        ################################################
        for j in range(0, len(self.control["QComboBox"])):
            self.control["QComboBox"][j].currentIndexChanged.disconnect(self.orthogonalTableImageSignal)
        self.imageRead(imageName=imageName)
        for j in range(0, len(self.control["QComboBox"])):
            self.control["QComboBox"][j].currentIndexChanged.connect(self.orthogonalTableImageSignal)

        if obj.error == 1:
            self.statusBar().showMessage('Unable to generate title.')
        else:
            self.statusBar().showMessage('Table and title generated.')

    def gravitationalSystemImage(self):
        """
        layout and initialization data
        """
        ##########################
        # layout of current page #
        ##########################
        self.currentImage = "gravitationalSystemImage"
        self.controlClear()

        layout = QGridLayout()
        layout.setSpacing(10)

        text = ['长度单位', '时间单位', '质量单位', '电量单位',
                '质点类型', '质点个数', '动画时长', '总帧数', '播放速率',
                '坐标轴标签', '视角', '速度矢量', '加速度矢量']
        position = [[0, 0, 1, 1], [0, 1, 1, 1], [0, 2, 1, 1], [0, 3, 1, 1],
                    [0, 4, 1, 1], [0, 5, 1, 1], [0, 6, 1, 1], [2, 0, 1, 1], [2, 1, 1, 1],
                    [2, 2, 1, 1], [2, 3, 1, 1], [2, 4, 1, 1], [2, 5, 1, 1]]
        self.controlLayout(layout=layout, name="QLabel", var={"text": text}, position=position, signal=None)

        itemText = [['ly', 'km', 'm', 'mm', 'nm'], ['year', 'day', 's', 'ms', 'μs'],
                    ['kg', '太阳(1.99+e30kg)', '质子(1.7-e27kg)', '电子(9.1-e31kg)'], ['C', 'e(1.6-e19C)'],
                    ['天体-天体', '电荷-电荷', '自定义-自定义'], list(map(str, range(2, 10))),
                    list(map(str, range(5, 65, 5))), ['100', '1000', '10000', '100000'],
                    ['显示', '隐藏'], ['静止', '旋转'], ['隐藏速度矢量', '显示当前速度矢量', '显示所有速度矢量'],
                    ['隐藏加速度矢量', '显示当前加速度矢量', '显示所有加速度矢量']]
        currentIndex = [2, 2, 0, 0, 2, 1, 2, 2, 0, 1, 1, 1]
        position = [[1, 0, 1, 1], [1, 1, 1, 1], [1, 2, 1, 1], [1, 3, 1, 1],
                    [1, 4, 1, 1], [1, 5, 1, 1], [1, 6, 1, 1], [3, 0, 1, 1],
                    [3, 2, 1, 1], [3, 3, 1, 1], [3, 4, 1, 1], [3, 5, 1, 1]]
        self.controlLayout(layout=layout, name="QComboBox", var={"itemText": itemText, "currentIndex": currentIndex},
                           position=position, signal=self.gravitationalSystemImageSignal)

        var = {"range": [[1, 1000]], "singleStep": [1], "prefix": ['X  '], "suffix": ["  倍"], "value": [100]}
        position = [[3, 1, 1, 1]]
        self.controlLayout(layout=layout, name="QSpinBox", var=var,
                           position=position, signal=self.gravitationalSystemImageSignal)

        text = ['启用调试单位']
        isChecked = [True]
        position = [[2, 6, 1, 1]]
        self.controlLayout(layout=layout, name="QRadioButton", var={"text": text, "isChecked": isChecked},
                           position=position, signal=self.gravitationalSystemImageSignal)

        text = ['播放动画']
        position = [[3, 6, 1, 1]]
        self.controlLayout(layout=layout, name="QPushButton", var={"text": text},
                           position=position, signal=self.gravitationalSystemImageDraw)

        # noinspection PyArgumentList
        widget = [[QWidget(), QWidget()]]
        name = ["QTableWidget", "QTextEdit"]
        var = [{"headerLabels": [["mass", "electricity", "X-coordinate", "Y-coordinate", "Z-coordinate",
                                  "X-velocity", "Y-velocity", "Z-velocity"]],
                "data": [numpy.array([[1, 0, 1, 0, 0, 0, 1, 0],
                                      [1, 1, 0, 1, 0, 0, 0, 1],
                                      [1, -1, 0, 0, 1, 1, 0, 0]])]},
               {"text": [["yes", "no"]]}]
        for j in range(0, 2):
            widgetLayout = QGridLayout()
            position = [[0, 0, 1, 1]]
            self.controlLayout(layout=widgetLayout, name=name[j], var=var[j], position=position, signal=None)
            widget[0][j].setLayout(widgetLayout)
        text = [["Initial Condition", "Note"]]
        position = [[4, 0, 1, 7]]
        self.controlLayout(layout=layout, name="QTabWidget", var={"text": text, "widget": widget},
                           position=position, signal=None)

        # noinspection PyArgumentList
        widget = QWidget()
        widget.setLayout(layout)
        self.setCentralWidget(widget)

        ###############################################################################
        # initialization self.controlData["gravitationalSystemImage"] then refresh it #
        # refresh self.control["gravitationalSystemImage"]                            #
        ###############################################################################
        if "gravitationalSystemImage" not in self.controlData:
            self.addFrame("gravitationalSystemImage")
            self.gravitationalSystemImageSignal()
        else:
            for j in range(0, len(self.control["QComboBox"])):
                self.control["QComboBox"][j].currentIndexChanged.disconnect(self.gravitationalSystemImageSignal)
            for j in range(0, len(self.control["QSpinBox"])):
                self.control["QSpinBox"][j].valueChanged.disconnect(self.gravitationalSystemImageSignal)
            for j in range(0, len(self.control["QRadioButton"])):
                self.control["QRadioButton"][j].clicked.disconnect(self.gravitationalSystemImageSignal)
            self.imageRead(imageName="gravitationalSystemImage")
            for j in range(0, len(self.control["QComboBox"])):
                self.control["QComboBox"][j].currentIndexChanged.connect(self.gravitationalSystemImageSignal)
            for j in range(0, len(self.control["QSpinBox"])):
                self.control["QSpinBox"][j].valueChanged.connect(self.gravitationalSystemImageSignal)
            for j in range(0, len(self.control["QRadioButton"])):
                self.control["QRadioButton"][j].clicked.connect(self.gravitationalSystemImageSignal)

        self.statusBar().showMessage('Ready')

    def gravitationalSystemImageSignal(self):
        """
        respond of current page(gravitationalSystemImage), then write data into MainData.dataClasses
        """
        self.statusBar().showMessage('Saving Page data...')

        ###############################################################
        # initialization self.controlData["gravitationalSystemImage"] #
        ###############################################################
        imageName = "gravitationalSystemImage"
        self.controlDataClear(imageName)

        ########################################################
        # refresh self.controlData["gravitationalSystemImage"] #
        ########################################################
        for j in range(0, len(self.control["QComboBox"])):
            itemText = list()
            for k in range(0, self.control["QComboBox"][j].count()):
                itemText.append(self.control["QComboBox"][j].itemText(k))
            self.controlData[imageName]["QComboBox"]["itemText"].append(itemText)

            currentIndex = self.control["QComboBox"][j].currentIndex()
            self.controlData[imageName]["QComboBox"]["currentIndex"].append(currentIndex)

        for i in range(0, len(self.control["QTableWidget"])):
            currentRow = self.control["QTableWidget"][i].rowCount()
            row = int(self.control["QComboBox"][5].currentText())
            column = self.control["QTableWidget"][i].columnCount()
            data = numpy.zeros((row, column), dtype=numpy.float64)
            for j in range(0, row):
                for k in range(0, column):
                    if j < currentRow:
                        # noinspection PyBroadException
                        try:
                            data[j][k] = float(self.control["QTableWidget"][i].item(j, k).text())
                        except:
                            data[j][k] = 0
            self.controlData[imageName]["QTableWidget"]["data"].append(data)

        for j in range(0, len(self.control["QSpinBox"])):
            value = self.control["QSpinBox"][j].value()
            self.controlData[imageName]["QSpinBox"]["value"].append(value)

        for j in range(0, len(self.control["QRadioButton"])):
            isChecked = self.control["QRadioButton"][j].isChecked()
            self.controlData[imageName]["QRadioButton"]["isChecked"].append(isChecked)

        ####################################################
        # refresh self.control["gravitationalSystemImage"] #
        ####################################################
        for j in range(0, len(self.control["QComboBox"])):
            self.control["QComboBox"][j].currentIndexChanged.disconnect(self.gravitationalSystemImageSignal)
        for j in range(0, len(self.control["QSpinBox"])):
            self.control["QSpinBox"][j].valueChanged.disconnect(self.gravitationalSystemImageSignal)
        for j in range(0, len(self.control["QRadioButton"])):
            self.control["QRadioButton"][j].clicked.disconnect(self.gravitationalSystemImageSignal)
        self.imageRead(imageName="gravitationalSystemImage")
        for j in range(0, len(self.control["QComboBox"])):
            self.control["QComboBox"][j].currentIndexChanged.connect(self.gravitationalSystemImageSignal)
        for j in range(0, len(self.control["QSpinBox"])):
            self.control["QSpinBox"][j].valueChanged.connect(self.gravitationalSystemImageSignal)
        for j in range(0, len(self.control["QRadioButton"])):
            self.control["QRadioButton"][j].clicked.connect(self.gravitationalSystemImageSignal)

        self.statusBar().showMessage('Page data Saved.')

    def gravitationalSystemImageDraw(self):
        """
        Draw animation of solution of ordinary differential equations
        """
        ########################################################
        # refresh self.controlData["gravitationalSystemImage"] #
        ########################################################
        self.gravitationalSystemImageSignal()
        self.statusBar().showMessage('Start to solving the ordinary differential equations...')

        #####################################################
        # get parameters of ordinary differential equations #
        #####################################################
        imageName = "gravitationalSystemImage"
        aniArg = self.controlData[imageName]["QComboBox"]["currentIndex"][8:]

        data = self.controlData[imageName]["QTableWidget"]["data"][0]
        mass = data[:, 0]
        for j in range(0, len(mass)):
            if mass[j] < 0 or mass[j] == 0:
                self.statusBar().showMessage('mass[%d] must be positive.' % j)
                return

        electric = numpy.abs(data[:, 1])

        electricType = numpy.sign(data[:, 1])

        cood = data[:, 2:5]
        coodCheck = numpy.dot(cood, cood.T)
        for j in range(0, len(mass)):
            for k in range(j, len(mass)):
                if (coodCheck[j, j] + coodCheck[k, k]) == 2 * coodCheck[j, k] and j != k:
                    self.statusBar().showMessage('point[%d] and point[%d] share the same coordinate.' % (j, k))
                    return

        vel = data[:, 5:]

        if self.controlData[imageName]["QRadioButton"]["isChecked"][0]:
            GUnit = 1
            KUnit = 1
        else:
            lenUnitMap = {0: 9.46 * 10 ** 15, 1: 1000, 2: 1, 3: 0.001, 4: 10 ** (-9)}
            lenUnit = lenUnitMap[self.controlData[imageName]["QComboBox"]["currentIndex"][0]]

            timeUnitMap = {0: 3.1536 * 10 ** 7, 1: 86400, 2: 1, 3: 0.001, 4: 10 ** (-6)}
            timeUnit = timeUnitMap[self.controlData[imageName]["QComboBox"]["currentIndex"][1]]

            massUnitMap = {0: 1, 1: 1.99 * 10 ** 30, 2: 1.7 * 10 ** (-27), 3: 9.1 * 10 ** (-31)}
            massUnit = massUnitMap[self.controlData[imageName]["QComboBox"]["currentIndex"][2]]

            electricUnitMap = {0: 1, 1: 1.6 * 10 ** (-19)}
            electricUnit = electricUnitMap[self.controlData[imageName]["QComboBox"]["currentIndex"][3]]

            GUnit = 6.67408 * 10 ** (-11) * massUnit * timeUnit ** 2 / lenUnit ** 3
            KUnit = 8.987 * 10 ** 9 * electricUnit ** 2 * timeUnit ** 2 / lenUnit ** 3 / massUnit

        timeLength = int(self.control["QComboBox"][6].currentText())
        nodeNumber = int(self.control["QComboBox"][7].currentText())
        t = numpy.arange(0, timeLength, timeLength / nodeNumber)

        aniSpeed = self.controlData[imageName]["QSpinBox"]["value"][0]

        ########################################################
        # draw the solution of ordinary differential equations #
        ########################################################
        self.controlClear()

        layout = QGridLayout()
        layout.setSpacing(10)

        # noinspection PyArgumentList
        widget = QWidget()
        self.canvas["gravitationalSystemImage"] = GravitationCanvas(aniArg, mass, electric, electricType, cood, vel,
                                                                    GUnit, KUnit, t, aniSpeed, parent=widget)
        self.controlData[imageName]["save"] = [mass, electric, electricType, cood, vel, GUnit, KUnit, t,
                                               self.canvas["gravitationalSystemImage"].track,
                                               self.canvas["gravitationalSystemImage"].vector,
                                               self.canvas["gravitationalSystemImage"].acc]

        layout.addWidget(self.canvas["gravitationalSystemImage"])
        widget.setLayout(layout)
        self.setCentralWidget(widget)

        self.statusBar().showMessage('Ready')

    def convexHullImage(self):
        """
        layout and initialization data
        """
        ##########################
        # layout of current page #
        ##########################
        self.currentImage = "convexHullImage"
        self.controlClear()

        layout = QGridLayout()
        layout.setSpacing(10)

        text = ['空间维数', '散点个数', '查看迭代步数']
        position = [[0, 0, 1, 1], [0, 2, 1, 1], [0, 4, 1, 1]]
        self.controlLayout(layout=layout, name="QLabel", var={"text": text}, position=position, signal=None)

        itemText = [list(map(str, range(2, 15))), list(map(str, range(3, 50))),
                    ["-complete-"] + list(map(str, range(1, 9)))]
        currentIndex = [1, 6, 0]
        position = [[0, 1, 1, 1], [0, 3, 1, 1], [0, 5, 1, 1]]
        self.controlLayout(layout=layout, name="QComboBox", var={"itemText": itemText, "currentIndex": currentIndex},
                           position=position, signal=self.convexHullImageSignal)

        text = ['随机生成散点集']
        position = [[0, 6, 1, 1]]
        self.controlLayout(layout=layout, name="QPushButton", var={"text": text},
                           position=position, signal=self.convexHullImageRandom)

        # noinspection PyArgumentList
        widget = [[QWidget(), QWidget(), QWidget()]]
        matrixLayout = QGridLayout()
        matrix = [numpy.array([[6, 0, 9, 9, 6, 6, 2, 0, 6],
                               [5, 7, 2, 6, 7, 3, 7, 4, 4],
                               [8, 3, 2, 5, 0, 0, 7, 6, 5]])]
        self.controlLayout(layout=matrixLayout, name="QTableWidget", var={"headerLabels": [], "data": matrix},
                           position=[[0, 0, 1, 1]], signal=None)
        widget[0][0].setLayout(matrixLayout)

        patches_listLayout = QGridLayout()
        patches_list = [numpy.array([[4, 2, 6, 0, 1, 1, 0, 0, 2, 5, 5, 5],
                                     [6, 4, 0, 6, 6, 7, 2, 7, 5, 2, 1, 7],
                                     [3, 3, 3, 7, 4, 6, 3, 2, 4, 7, 4, 1]])]
        self.controlLayout(layout=patches_listLayout, name="QTableWidget",
                           var={"headerLabels": [], "data": patches_list}, position=[[0, 0, 1, 1]], signal=None)
        widget[0][1].setLayout(patches_listLayout)

        canvasLayout = QGridLayout()
        self.canvas["convexHullImage"] = ConvexHullCanvas(matrix[0], patches_list, parent=widget[0][2])
        canvasLayout.addWidget(self.canvas["convexHullImage"])
        widget[0][2].setLayout(canvasLayout)

        text = [["Points", "Patches", "Convex Hull 3D"]]
        position = [[1, 0, 1, 7]]
        self.controlLayout(layout=layout, name="QTabWidget", var={"text": text, "widget": widget},
                           position=position, signal=None)

        # noinspection PyArgumentList
        widget = QWidget()
        widget.setLayout(layout)
        self.setCentralWidget(widget)

        ######################################################################
        # initialization self.controlData["convexHullImage"] then refresh it #
        # refresh self.control["convexHullImage"]                            #
        ######################################################################
        if "convexHullImage" not in self.controlData:
            self.addFrame("convexHullImage")
            self.convexHullImageSignal()
        else:
            for j in range(0, len(self.control["QComboBox"])):
                self.control["QComboBox"][j].currentIndexChanged.disconnect(self.convexHullImageSignal)
            self.imageRead(imageName="convexHullImage")
            for j in range(0, len(self.control["QComboBox"])):
                self.control["QComboBox"][j].currentIndexChanged.connect(self.convexHullImageSignal)

        self.statusBar().showMessage('Ready')

    def convexHullImageSignal(self):
        """
        respond of current page(convexHullImage), then write data into MainData.controlData
        """
        self.statusBar().showMessage('Setting patches...')

        ######################################################
        # initialization self.controlData["convexHullImage"] #
        ######################################################
        imageName = "convexHullImage"
        self.controlDataClear(imageName)

        ###############################################
        # refresh self.controlData["convexHullImage"] #
        ###############################################
        m = int(self.control["QComboBox"][0].itemText(self.control["QComboBox"][0].currentIndex()))
        n = int(self.control["QComboBox"][1].itemText(self.control["QComboBox"][1].currentIndex()))
        if m < n:
            pass
        else:
            self.statusBar().showMessage('The number of points should be more than dimension.')
            return

        list(map(str, range(4, 50)))
        for j in range(0, len(self.control["QComboBox"])):
            itemText = list()
            for k in range(0, self.control["QComboBox"][j].count()):
                itemText.append(self.control["QComboBox"][j].itemText(k))
            self.controlData[imageName]["QComboBox"]["itemText"].append(itemText)

            currentIndex = self.control["QComboBox"][j].currentIndex()
            self.controlData[imageName]["QComboBox"]["currentIndex"].append(currentIndex)

        row = int(self.control["QComboBox"][0].currentText())
        column = int(self.control["QComboBox"][1].currentText())
        currentRow = self.control["QTableWidget"][0].rowCount()
        currentColumn = self.control["QTableWidget"][0].columnCount()
        matrix = numpy.zeros((row, column), dtype=numpy.float64)
        for j in range(0, row):
            for k in range(0, column):
                if j < currentRow and k < currentColumn:
                    # noinspection PyBroadException
                    try:
                        matrix[j][k] = float(self.control["QTableWidget"][0].item(j, k).text())
                    except:
                        matrix[j][k] = 0
        self.controlData[imageName]["QTableWidget"]["data"].append(matrix)

        obj = ConvexHullMap(matrix=matrix)
        obj.complete()
        patches = numpy.array(obj.patches).T
        self.controlData[imageName]["QTableWidget"]["data"].append(patches)

        self.controlData[imageName]["save"] = [matrix, patches]

        ##############
        # draw image #
        ##############
        if int(self.control["QComboBox"][0].currentText()) == 3:
            self.canvas[imageName].canvasData["matrix"] = matrix
            if self.control["QComboBox"][2].currentIndex() == 0:
                self.canvas[imageName].canvasData["patches_list"] = [obj.patches]
            else:
                new_obj = ConvexHullMap(matrix=matrix)
                self.canvas[imageName].canvasData["patches_list"] = [copy.deepcopy(new_obj.patches)]
                for j in range(0, int(self.control["QComboBox"][2].currentText())):
                    new_obj.classify_points()
                    if new_obj.next_points.count(None) == len(new_obj.next_points):
                        break
                    new_obj.expand_patches()
                    self.canvas[imageName].canvasData["patches_list"].append(copy.deepcopy(new_obj.patches))
        self.canvas[imageName].fig.clf()
        self.canvas[imageName].axes = axes3d.Axes3D(self.canvas[imageName].fig)
        self.canvas[imageName].complete_draw()
        self.canvas[imageName].fig.canvas.draw()

        ###########################################
        # refresh self.control["convexHullImage"] #
        ###########################################
        for j in range(0, len(self.control["QComboBox"])):
            self.control["QComboBox"][j].currentIndexChanged.disconnect(self.convexHullImageSignal)
        self.imageRead(imageName=imageName)
        for j in range(0, len(self.control["QComboBox"])):
            self.control["QComboBox"][j].currentIndexChanged.connect(self.convexHullImageSignal)

        self.statusBar().showMessage('End of setting title.')

    def convexHullImageRandom(self):
        """
        Reset coordinates of scattered point set
        """
        ###############################################
        # refresh self.controlData["convexHullImage"] #
        ###############################################
        self.statusBar().showMessage('Start to resetting coordinates of scattered points...')

        #########################################
        # get parameters of scattered point set #
        #########################################
        imageName = "convexHullImage"

        n = int(self.control["QComboBox"][0].currentText())
        m = int(self.control["QComboBox"][1].currentText())
        matrix = numpy.random.random_integers(low=0, high=10, size=(n, m))
        self.controlData[imageName]["QTableWidget"]["data"][0] = matrix
        self.controlData[imageName]["save"][0] = matrix

        self.imageRead(imageName=imageName)

        self.convexHullImageSignal()

        self.statusBar().showMessage('End of resetting coordinates of scattered points.')

    def analyticFunctionImage(self):
        """
        layout and initialization data
        """
        ##########################
        # layout of current page #
        ##########################
        self.currentImage = "analyticFunctionImage"
        self.controlClear()

        layout = QGridLayout()
        layout.setSpacing(10)

        text = ['次方数', '拉伸系数', '辐角']
        position = [[0, 0, 1, 1], [0, 2, 1, 1], [0, 4, 1, 1]]
        self.controlLayout(layout=layout, name="QLabel", var={"text": text}, position=position, signal=None)

        itemText = [list(map(str, range(1, 20)))]
        position = [[0, 1, 1, 1]]
        self.controlLayout(layout=layout, name="QComboBox", var={"itemText": itemText, "currentIndex": []},
                           position=position, signal=self.analyticFunctionImageSignal)

        var = {"range": [[1, 100], [-180, 180]], "singleStep": [1, 1],
               "prefix": [], "suffix": ['*0.1', '*pi/180'], "value": [10, 0]}
        position = [[0, 3, 1, 1], [0, 5, 1, 1]]
        self.controlLayout(layout=layout, name="QSpinBox", var=var,
                           position=position, signal=self.analyticFunctionImageSignal)

        text = [['%f*e**(i*%f)*z**%d + z = 1' % (1, 1, 0)]]
        # noinspection PyArgumentList
        widget = [[QWidget()]]
        position = [[1, 0, 1, 6]]
        widgetLayout = QGridLayout()
        self.canvas["analyticFunctionImage"] = AnalyticFunctionCanvas(1, 1, 0, parent=widget[0][0])
        widgetLayout.addWidget(self.canvas["analyticFunctionImage"])
        widget[0][0].setLayout(widgetLayout)
        self.controlLayout(layout=layout, name="QTabWidget", var={"text": text, "widget": widget},
                           position=position, signal=None)

        # noinspection PyArgumentList
        widget = QWidget()
        widget.setLayout(layout)
        self.setCentralWidget(widget)

        ############################################################################
        # initialization self.controlData["analyticFunctionImage"] then refresh it #
        # refresh self.control["analyticFunctionImage"]                            #
        ############################################################################
        if "analyticFunctionImage" not in self.controlData:
            self.addFrame("analyticFunctionImage")
            self.analyticFunctionImageSignal()
        else:
            for j in range(0, len(self.control["QComboBox"])):
                self.control["QComboBox"][j].currentIndexChanged.disconnect(self.analyticFunctionImageSignal)
            for j in range(0, len(self.control["QSpinBox"])):
                self.control["QSpinBox"][j].valueChanged.disconnect(self.analyticFunctionImageSignal)
            self.imageRead(imageName="analyticFunctionImage")
            for j in range(0, len(self.control["QComboBox"])):
                self.control["QComboBox"][j].currentIndexChanged.connect(self.analyticFunctionImageSignal)
            for j in range(0, len(self.control["QSpinBox"])):
                self.control["QSpinBox"][j].valueChanged.disconnect(self.analyticFunctionImageSignal)

        self.statusBar().showMessage('Ready')

    def analyticFunctionImageSignal(self):
        """
        respond of current page(analyticFunctionImage), then write data into MainData.controlData
        """
        self.statusBar().showMessage('Starting draw image...')

        ############################################################
        # initialization self.controlData["analyticFunctionImage"] #
        ############################################################
        imageName = "analyticFunctionImage"
        self.controlDataClear(imageName)

        #####################################################
        # refresh self.controlData["analyticFunctionImage"] #
        #####################################################
        for j in range(0, len(self.control["QComboBox"])):
            itemText = list()
            for k in range(0, self.control["QComboBox"][j].count()):
                itemText.append(self.control["QComboBox"][j].itemText(k))
            self.controlData[imageName]["QComboBox"]["itemText"].append(itemText)

            currentIndex = self.control["QComboBox"][j].currentIndex()
            self.controlData[imageName]["QComboBox"]["currentIndex"].append(currentIndex)

        for j in range(0, len(self.control["QSpinBox"])):
            value = self.control["QSpinBox"][j].value()
            self.controlData[imageName]["QSpinBox"]["value"].append(value)

        ##############
        # draw image #
        ##############
        self.canvas[imageName].n = self.controlData[imageName]["QComboBox"]["currentIndex"][0] + 1
        self.canvas[imageName].r = self.controlData[imageName]["QSpinBox"]["value"][0] * 0.1
        self.canvas[imageName].t = self.controlData[imageName]["QSpinBox"]["value"][1] * math.pi / 180
        text = '%f*e**(i*%f)*z**%d + z = 1' % (self.canvas[imageName].n, self.canvas[imageName].r,
                                               self.canvas[imageName].t)
        self.control["QTabWidget"][0].setTabText(0, text)
        self.canvas[imageName].fig.clf()
        self.canvas[imageName].axes = self.canvas[imageName].fig.add_subplot(111)
        self.canvas[imageName].axes.grid(True)
        self.canvas[imageName].complete_draw()
        self.canvas[imageName].fig.canvas.draw()

        ################################################
        # refresh self.control["analyticFunctionImage"] #
        ################################################
        for j in range(0, len(self.control["QComboBox"])):
            self.control["QComboBox"][j].currentIndexChanged.disconnect(self.analyticFunctionImageSignal)
        self.imageRead(imageName=imageName)
        for j in range(0, len(self.control["QComboBox"])):
            self.control["QComboBox"][j].currentIndexChanged.connect(self.analyticFunctionImageSignal)

        self.statusBar().showMessage('Image is drawn.')

    @staticmethod
    def sourceCodeImage():
        """
        @
        """
        pass

    def keyPressEvent(self, event):
        """
        :param event:
        :return:
        """
        if event.key() == Qt.Key_Escape:
            try:
                if self.currentImage == "rainImage":
                    self.orthogonalTableImage()
                elif self.currentImage == "orthogonalTableImage":
                    pass
                elif self.currentImage == "convexHullImage":
                    pass
                elif self.currentImage == "gravitationalSystemImage":
                    self.gravitationalSystemImage()
                elif self.currentImage == "analyticFunctionImage":
                    pass
            except KeyError:
                self.startImage()
            self.statusBar().showMessage('Esc is pressed!')

    def showOpenDialog(self):
        """
        @
        """
        # noinspection PyCallByClass,SpellCheckingInspection
        fname = QFileDialog.getOpenFileName(self, 'Open file', '/home')

        # if fname[0]:
        #     # noinspection PyArgumentEqualDefault
        #     f = open(fname[0], 'r')
        #     with f:
        #         data = f.read()
        #         self.textEdit.setText(data)

    def buttonClicked(self):
        """
        @
        """
        sender = self.sender()
        self.statusBar().showMessage(sender.text() + ' was pressed')
        # noinspection PyCallByClass,PyTypeChecker
        QInputDialog.getText(self, 'Input Dialog', 'Enter your name:')

    def closeEvent(self, event):
        """
        @
        """
        # noinspection PyCallByClass,PyTypeChecker
        reply = QMessageBox.question(self, 'Message', "Are you sure to quit?",
                                     QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        if reply == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()


#!/usr/bin/env python

from PyQt4 import QtGui, QtCore
from item import Item

class DescItem(Item):

    def __init__(self, scene, x, y, parent):

        self.text = ""
        self.scale = 1.0
        self.color = QtCore.Qt.gray
        self.hover_color = QtCore.Qt.white

        super(DescItem, self).__init__(scene, x, y, parent=parent)

    def boundingRect(self):

        if not self.scene():
            return QtCore.QRectF()

        font = QtGui.QFont(self.default_font, self.get_font_size(self.scale))
        metrics = QtGui.QFontMetrics(font)

        return QtCore.QRectF(
            metrics.boundingRect(
                QtCore.QRect(
                    0,
                    0,
                    10000,
                    10000),
                QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop | QtCore.Qt.TextWordWrap,
                self.text))

    def set_content(self, text, scale=1.0, color=None, hover_color=None):

        self.prepareGeometryChange()
        self.scale = scale
        self.text = text
        if color:
            self.color = color
        if hover_color:
            self.hover_color = hover_color
        self.update()

    def paint(self, painter, option, widget):

        if not self.scene():
            return

        painter.setClipRect(option.exposedRect)
        painter.setRenderHint(QtGui.QPainter.Antialiasing)

        if self.parentItem() and self.parentItem().hover:

            painter.setBrush(self.hover_color)
            painter.setPen(self.hover_color)

        else:

            painter.setBrush(self.color)
            painter.setPen(self.color)

        font = QtGui.QFont(self.default_font, self.get_font_size(self.scale))
        painter.setFont(font)
        painter.drawText(self.boundingRect(), QtCore.Qt.AlignLeft |
                         QtCore.Qt.AlignTop | QtCore.Qt.TextWordWrap, self.text)


# Covid Resistant Husky 3 - ADA price prediction

# import pip to install necessary libraries
import math

import pip
pip.main(['install', 'python-binance', 'pandas', 'scikit-learn', 'matplotlib', 'keras', 'tensorflow', 'plotly',
          'mplfinance'])
from keras.losses import mean_squared_error
from matplotlib.dates import date2num

# import the necessary libraries
import config
from binance.client import Client
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
import numpy as np
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM, Dropout, GRU
import matplotlib.pyplot as plt
import plotly.graph_objects as go
import talib
from sklearn.metrics import r2_score
from mplfinance.original_flavor import candlestick_ohlc

# function call to split the data for training and test
def train_test_split(df, test_size=0.2):
    # split the data into 80 and 20
    split_row = len(df) - int(len(df) * test_size)
    # train data contains 80% of data
    train_data = df.iloc[:split_row]
    # test data contains 20% of the data
    test_data = df.iloc[split_row:]
    return train_data, test_data

# function to calcualte MACD, MA10,MA30 and RSI
def get_indicators(data2):
    # Get MACD
    data2["macd"], data2["macd_signal"], data2["macd_hist"] = talib.MACD(data2['Close'])

    # Get MA10 and MA30
    data2["ma10"] = talib.MA(data2["Close"], timeperiod=10)
    data2["ma30"] = talib.MA(data2["Close"], timeperiod=30)

    # Get RSI
    data2["rsi"] = talib.RSI(data2["Close"])
    return data2

# function call to initialise the RNN - GRU model
def Model_Initialisation_GRU(X_train, mod):
    model = Sequential()
    # Layer 1
    model.add(mod(70, activation='relu', return_sequences=True, input_shape=(X_train.shape[1], X_train.shape[2])))
    # Dropout is set to 20%
    model.add(Dropout(0.2))
    # Layer 2
    model.add(mod(80, activation='relu'))
    # Dropout is set to 20%
    model.add(Dropout(0.2))
    model.add(Dense(units=1))
    print(model.summary())
    return model

# function call to initialise the RNN -LSTM model
def Model_Initialisation_LSTM(X_train, mod):
    model = Sequential()
    # Layer 1
    model.add(mod(300, activation='relu', return_sequences=True, input_shape=(X_train.shape[1], X_train.shape[2])))
    # Dropout is set to 20%
    model.add(Dropout(0.2))
    # Layer 2
    model.add(mod(300, activation='relu'))
    # Dropout is set to 20%
    model.add(Dropout(0.2))
    model.add(Dense(units=1))
    print(model.summary())
    return model

# function call to plot the RSI, MACD, MA10 and MA30
def plot_chart(data, n, ticker):
    # Filter number of observations to plot
    data = data.iloc[-n:]

    # Create figure and set axes for subplots
    fig = plt.figure()
    fig.set_size_inches((30, 20))
    ax_candle = fig.add_axes((0, 0.72, 1, 0.32))
    ax_macd = fig.add_axes((0, 0.48, 1, 0.2), sharex=ax_candle)
    ax_rsi = fig.add_axes((0, 0.24, 1, 0.2), sharex=ax_candle)
    ax_vol = fig.add_axes((0, 0, 1, 0.2), sharex=ax_candle)

    # Format x-axis ticks as dates
    ax_candle.xaxis_date()

    # Get nested list of date, open, high, low and close prices
    ohlc = []
    for date, row in data.iterrows():
        openp, highp, lowp, closep = row[:4]
        ohlc.append([date2num(date), openp, highp, lowp, closep])

    # Plot candlestick chart
    ax_candle.plot(data.index, data["ma10"], label="MA10")
    ax_candle.plot(data.index, data["ma30"], label="MA30")
    candlestick_ohlc(ax_candle, ohlc, colorup="g", colordown="r", width=0.8)
    ax_candle.legend()

    # Plot MACD
    ax_macd.plot(data.index, data["macd"], label="macd")
    ax_macd.bar(data.index, data["macd_hist"] * 3, label="hist")
    ax_macd.plot(data.index, data["macd_signal"], label="signal")
    ax_macd.legend()

    # Plot RSI
    # Above 70% = overbought, below 30% = oversold
    ax_rsi.set_ylabel("(%)")
    ax_rsi.plot(data.index, [70] * len(data.index), label="overbought")
    ax_rsi.plot(data.index, [30] * len(data.index), label="oversold")
    ax_rsi.plot(data.index, data["rsi"], label="rsi")
    ax_rsi.legend()

    # Show volume in millions
    ax_vol.bar(data.index, data["Volume"] / 1000000)
    ax_vol.set_ylabel("(Million)")

    # Save the chart as PNG
    fig.savefig(ticker + ".png", bbox_inches="tight")

    plt.show()

# function call to train and predict the close values
def fit_model(train_set, test_set, X_train, y_train, model, scaler, model_name):
    model.compile(loss='mse', optimizer='adam')
    # fit the model with the training data
    model.fit(X_train, y_train, epochs=50, batch_size=32, shuffle=False)
    # storing the training data
    train_set = pd.DataFrame(train_set, columns=['Open', 'High', 'Low', 'Close', 'Volume'])
    # specifying the window as 10
    past_10_days = train_set.tail(10)
    df = past_10_days.append(test_set, ignore_index=True)
    print(df.head())
    # transforming the data
    inputs = scaler.transform(df)
    print(inputs)

    X_test = []
    y_test = []

    for i in range(10, inputs.shape[0]):
        X_test.append(inputs[i - 10:i])
        y_test.append(inputs[i, 0])
    # converting the data into array
    X_test, y_test = np.array(X_test), np.array(y_test)
    print(X_test.shape, y_test.shape)
    # predicting the close value on test data
    y_pred = model.predict(X_test)
    print(y_pred, y_test)

    # performing inverse of scalar transformation to get the actual value
    arr = scaler.scale_
    scale = 1 / arr[0]
    print(scale)
    y_pred = y_pred * scale
    y_test = y_test * scale
    # calculates the r2 value
    print("R2 score", round(r2_score(y_test, y_pred) * 100, 2))
    # calculates the RMSE value for training data
    trainScore = math.sqrt(mean_squared_error(y_train[0], y_pred[:, 0]))
    print('Train Score: %.2f RMSE' % (trainScore))
    # calculates the RMSE value for test data
    testScore = math.sqrt(mean_squared_error(y_test[0], y_pred[:, 0]))
    print('Test Score: %.2f RMSE' % (testScore))

    # plotting the graph to show predicted vs test value of the models
    plt.figure(figsize=(14, 5))
    plt.plot(y_test, color='red', label='ADA Price')
    plt.plot(y_pred, color='blue', label='Predicted ADA Price')
    plt.title('ADA Price Prediction')
    plt.xlabel('Time (in Hours)')
    plt.ylabel('ADA Price')
    plt.legend()
    plt.show()

# function to call to initialise the models and call the model to predict the data
def Model_Prediction(df):
    # split the data into 80:20 for training and testing
    train_set, test_set = train_test_split(data, test_size=0.2)
    scaler = MinMaxScaler()
    # transforming the data using Min, Max scaler
    train_set = scaler.fit_transform(train_set)
    print(train_set)
    # specifiying the window size as 10 and values are stored accordingly in train data
    X_train = []
    y_train = []
    for i in range(10, train_set.shape[0]):
        X_train.append(train_set[i - 10:i])
        y_train.append(train_set[i, 0])
    # converting the train data into array
    X_train, y_train = np.array(X_train), np.array(y_train)
    print(X_train.shape)
    # initialising RNN - GRU model
    model_GRU = Model_Initialisation_GRU(X_train, GRU)
    # initialising RNN - LSTM
    model_LSTM = Model_Initialisation_LSTM(X_train, LSTM)
    # training the LSTM model and predicting the close value
    fit_model(train_set, test_set, X_train, y_train, model_LSTM, scaler, 'LSTM')
    # training the GRU model and predicting the close value
    fit_model(train_set, test_set, X_train, y_train, model_GRU, scaler, 'GRU')

# Function call to plot the candelstick chart
def CandleStickChart(data):
    # using TA lib library for recognising the patterns in data
    candle_names = talib.get_function_groups()['Pattern Recognition']
    # Plotting the candelstick data
    fig = go.Figure(data=[go.Candlestick(x=data.index, open=data['Open'], high=data['High'], low=data['Low'],
                                         close=data['Close'])])
    fig.update_layout(title='ADA price over the time', yaxis_title='Price')
    fig.show()

# function to plot log10 close price of ADA
def LogReturnsPlot(data):
    # calculates log10 of close price of ADA
    change = pd.DataFrame(data['Close']).apply(lambda x: np.log(x) - np.log(x.shift(1)))
    print(change)
    # plots the graph
    fig = go.Figure([go.Scatter(x=change.index, y=change['Close'])])
    fig.update_layout(title='log10 value of Closing price', xaxis_title='log10')
    fig.show()

# function call to download the dataset
def get_ADA_BinanceAPI():
    # connecting to the Binance API to fetch the data
    client = Client(config.binance_API, config.binance_Secret)
    # downloading the ADA data from Binance API for 1 day interval, 500 entries.
    ADA = client.get_klines(symbol='ADAUSDT', interval=Client.KLINE_INTERVAL_1DAY, limit=500)
    # converting the data into Dataframe and assigning columns
    ADA = pd.DataFrame(ADA, columns=['Open time', 'Open', 'High', 'Low', 'Close', 'Volume', 'Close time',
                                     'Quote asset volume', 'Number of trades', 'Taker buy base asset volume',
                                     'Taker buy quote asset volume', 'Ignore'])
    # converting the open time column to datetime type
    ADA['Open time'] = pd.to_datetime(ADA['Open time'], unit='ms')
    # formatting the data in ascending order of time
    ADA.sort_values(by=['Open time'], inplace=True, ascending=True)
    # setting time column as index
    ADA.set_index('Open time', inplace=True)
    # converting the variables into float type
    ADA['Open'] = ADA['Open'].astype(float)
    ADA['High'] = ADA['High'].astype(float)
    ADA['Low'] = ADA['Low'].astype(float)
    ADA['Close'] = ADA['Close'].astype(float)
    ADA['Volume'] = ADA['Volume'].astype(float)
    # the 5 variables are used to predict close and are stored as dataframe and returned
    data = pd.DataFrame(ADA[['Open', 'High', 'Low', 'Close', 'Volume']])
    print(data.head(15))
    return data

# main function
if __name__ == '__main__':
    # function to download the data from Binance API
    data = get_ADA_BinanceAPI()
    # Function to plot log10 close price
    LogReturnsPlot(data)
    # fucntion call to calculate MACD, RSI, MA10 and MA30
    data2 = data.copy()
    data2 = get_indicators(data2)
    # fucntion call to plot MACD, RSI, MA10 and MA30
    plot_chart(data2, 150, "PLOTS")
    # function to plot the candelstick chart
    CandleStickChart(data)
    # model to predict the close price of ADA
    Model_Prediction(data)


import unittest
from pathlib import Path

from tests import CdsTestMixin
from . import CDSCase

class DumpTest(CdsTestMixin, unittest.TestCase):
    def test_trace_json(self):
        with CDSCase(self, self.NAME_LIST, self.TEST_ARCHIVE) as cds:
            cds.run_trace('import json')
            cds.verify_files(check_archive=False)

            cds.verify(lambda _: self.assertIn(
                'json',
                [line.strip() for line in Path(self.NAME_LIST).read_text().split('\n')]))

    def test_dump_archive_from_list_json(self):
        with open(self.NAME_LIST, 'w') as f:
            print('json', file=f)

        with CDSCase(self, self.NAME_LIST, self.TEST_ARCHIVE, clear_list=False) as cds:
            cds.run_dump()


from collections import deque

def bfs(graph, start):
    queue = deque([start]) #방문할 노드를 넣어두는 곳
    visited = [] #방문한 노드들

    while queue:
        v = queue.popleft()
        print(v, end=" ")
        if v not in visited:
            visited.append(v)
            queue += graph[v]

    return visited

graph = [
    [],
    [2,3,8],
    [1,7],
    [1,4,5],
    [3,5],
    [3,4],
    [7],
    [2,6,8],
    [1,7]
]

print(bfs(graph, 1))


# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

from rp_ui_harness import RequestPolicyTestCase

class TestBeforeAllOtherTests(RequestPolicyTestCase):

    def test_gecko_log(self):
        error_lines = self.gecko_log.get_error_lines_before_first_test()
        if len(error_lines) != 0:
            self.fail(
                "Found " + str(len(error_lines)) + " error lines before " +
                "the first test! First error line: " + str(error_lines[0]))


import datetime
import jsonlines

# Appends json to a jsonl file
def append_to_jsonl(timeline, file_path):
	print("Writing contents to jsonl...")

	# Sort major events array by timestamp
	sorted_timeline = sorted(timeline, key=lambda event: int(event['date']))

	# Pretty print JSON of human datetime
	for event in sorted_timeline:
		date = datetime.datetime.fromtimestamp(int(event['date'])/1000).strftime('%c')
		event['date_pretty'] = date
		# print(f"[{date}] {event['name']} ({len(event['citationIds'])})")

	with jsonlines.open(file_path, mode='a') as writer:
		for item in sorted_timeline:
			writer.write(item)


import cv2
import cvzone
from cvzone.PoseModule import PoseDetector
import numpy as np

cap = cv2.VideoCapture(1)

detector = PoseDetector()
per = 0
a1 = 0
color = (0,0,255)
situps = 0
dir = 0
while True:
    __ , img = cap.read()
    #assert isinstance(img, object)

    img = detector.findPose(img)
    lmlist, bbox = detector.findPosition(img,False)
    assert isinstance(lmlist, object)
    if lmlist:
        a1 = detector.findAngle(img,24,26,28)
        per = np.interp(a1,(75,160),(100,0))
        bar_value = np.interp(a1,(75,160),(15,15+300))
        # print(per)
        cv2.rectangle(img,(580,int(bar_value)),(580 + 20,15 + 350),color,cv2.FILLED)
        cv2.rectangle(img,(580,15),(580 + 20,15 + 350),(0,0,0),3)
        cvzone.putTextRect(img,f'{int(per)} %',(575,410),1.2,2,colorT=(),colorR=color,border=3,colorB=())
        if per ==100:
            if dir == 0:
                situps += 0.5
                dir = 1
                color = (0,255,0)
        elif per == 0:
            if dir == 1:
                situps += 0.5
                dir = 0
                color = (0,255,0)
        else:
            color = (0,0,255)
        #print(situps)
        cvzone.putTextRect(img,f'SIT UPS : {str(int(situps))}',(30,30),2,2,colorT=(),colorR=(255,0,0),border=3,colorB=())
    cv2.imshow('Situps Counter', img)
    if cv2.waitKey(1) == ord('q'):
        break


# -*- coding: utf-8 -*-

import html

from gi.repository import Gtk

from mcomix.preferences import config

class MessageDialogRemember(Gtk.MessageDialog):
    __slots__ = ('__dialog_id', '__choices', '__remember_checkbox')

    def __init__(self):
        """
        Creates a dialog window.
        """

        super().__init__()

        self.set_modal(True)

        #: Unique dialog identifier (for storing 'Do not ask again')
        self.__dialog_id = None
        #: List of response IDs that should be remembered
        self.__choices = []

        self.__remember_checkbox = Gtk.CheckButton(label='Do not ask again.')
        self.__remember_checkbox.set_no_show_all(True)
        self.__remember_checkbox.set_can_focus(False)
        self.get_message_area().pack_end(self.__remember_checkbox, True, True, 6)

        self.set_default_response(Gtk.ResponseType.OK)

    def set_text(self, primary: str, secondary: str = None):
        """
        Formats the dialog's text fields.

        :param primary: Main text.
        :param secondary: Descriptive text
        """

        self.set_markup(f'{html.escape(primary)}')

        if secondary:
            self.format_secondary_markup(html.escape(secondary))

    def should_remember_choice(self):
        """
        :returns: True when the dialog choice should be remembered
        """

        return self.__remember_checkbox.get_active()

    def set_should_remember_choice(self, dialog_id: str, choices: tuple):
        """
        This method enables the 'Do not ask again' checkbox.

        :param dialog_id: Unique identifier for the dialog (a string).
        :param choices: List of response IDs that should be remembered
        """

        self.__remember_checkbox.show()
        self.__dialog_id = dialog_id
        self.__choices = [int(choice) for choice in choices]

    def run(self):
        """
        Makes the dialog visible and waits for a result. Also destroys
        the dialog after the result has been returned
        """

        if self.__dialog_id in config['STORED_DIALOG_CHOICES']:
            self.destroy()
            return config['STORED_DIALOG_CHOICES'][self.__dialog_id]

        self.show_all()
        # Prevent checkbox from grabbing focus by only enabling it after show
        self.__remember_checkbox.set_can_focus(True)

        result = super().run()

        if self.should_remember_choice() and int(result) in self.__choices:
            config['STORED_DIALOG_CHOICES'][self.__dialog_id] = int(result)

        self.destroy()
        return result


import numpy as np
import torch

# # np.argwhere的用法
# a=np.zeros((4,3), dtype=np.uint32)
# b=np.argwhere(np.zeros((4,3), dtype=np.uint32) == 0)
# print(a)
# print(b)
# print(type(b),b.shape)

# # reshape的用法，torch和numpy都有类似的用法
# a = torch.arange(4.)
# print(a.shape)
# a=torch.reshape(a, (2, 2))
# print(a.shape)
# b = torch.rand(4,4,2)
# print(b.shape)
# b=torch.reshape(b, (-1,2))
# print(b.shape)

# # np.arange和np.linspace的一点比较
# print(np.arange(-6, 6, 2))
# I_r_grid_x = (np.arange(-6, 6, 2) + 1.0) / 6
# I_r_grid_y = (np.arange(-6, 6, 2) + 1.0) / 6
# print(I_r_grid_x)
# print(I_r_grid_y)

# I_r_grid_x=np.linspace(-1,1,6)
# print(I_r_grid_x)

# # np.concatenate用法
# a = np.concatenate([np.zeros((1, 3)), np.ones((1, 9))], axis=1)
# print(a)

# # np.fill_diagonal用法
# hat_C=5*np.ones((4,4))
# np.fill_diagonal(hat_C, 1)
# print(hat_C)

# 参考点生成
# xs = torch.linspace(0, 1020, steps=61)
# ys = torch.linspace(0, 1020, steps=61)
# x, y = torch.meshgrid(xs, ys, indexing='xy')
# P = torch.dstack([x, y])
# print(P)

# 归一化测试
# 只有当requires_grad=True时，讨论叶张量才有意义
batch_pt = torch.ones((4, 2, 31, 31), requires_grad=True)
batch_pt_norm = batch_pt / 992
batch_pt_norm.sum().backward()
print(batch_pt_norm.max())
print("OK")

# 赋值测试
a,b,c,d=0,0,0,0
print(a,b,c,d)


from django.shortcuts import render
from .models import *
from django.http import HttpResponse
import json
from rest_framework import generics
from .serializers import *

# Create your views here.
def dashboard(request):
    return render(request,"dashboard.html")

def department(request):
    #department_list = Department.objects.all()
    department_list = Department.objects.raw('SELECT * FROM emp_department')
    return render(request,'departments.html',{'department_list':department_list})

def manage_departments(request):
    department = {}
    if request.method == 'GET':
        data =  request.GET
        id = ''
        if 'id' in data:
            id= data['id']
            print(id)
        if id.isnumeric() and int(id) > 0:
            department = Department.objects.raw(f'SELECT * FROM emp_department WHERE emp_department.id = {id}')[0]
            #department = Department.objects.filter(pk=id).first()
            print(department)

    context = {
        'department' : department
    }
    return render(request, 'manage_department.html',context)

def save_department(request):
    data =  request.POST
    resp = {'status':'failed'}
    try:
        if (data['id']).isnumeric() and int(data['id']) > 0 :
            d_name=data['name']
            d_id=data['id']
            #save_department = Department.objects.filter(id = data['id']).update(department=data['name'])
            q=f'UPDATE emp_department SET department = \'{d_name}\' WHERE emp_department.id = {d_id}'
            Department.objects.raw(q)[:]
        else:
            d_name=data['name']
            q=f'INSERT INTO emp_department (department) VALUES (\'{d_name}\') RETURNING emp_department.id'
            Department.objects.raw(q)[:]
            #save_department = Department(department=data['name'])
        resp['status'] = 'success'
    except Exception as e:
        print(e)
        resp['status'] = 'success'
    return HttpResponse(json.dumps(resp), content_type="application/json")

def delete_department(request):
    data =  request.POST
    resp = {'status':''}
    try:
        d_id=data['id']
        resp['status'] = 'success'
        Department.objects.raw(f'DELETE FROM emp_department WHERE emp_department.id = {d_id}')[:]
        #Department.objects.filter(id = data['id']).delete()

    except:
        resp['status'] = 'success'
    return HttpResponse(json.dumps(resp), content_type="application/json")

def employee(request):
    #employee_list = Employee.objects.all()
    employee_list =Employee.objects.raw('SELECT * FROM emp_employee')
    return render(request,'employees.html',{'employee_list':employee_list})

def view_employee(request):
    employee = {}
    if request.method == 'GET':
        data =  request.GET
        id = ''
        if 'id' in data:
            id= data['id']
        if id.isnumeric() and int(id) > 0:
            employee = Employee.objects.raw(f'SELECT * FROM emp_employee WHERE emp_employee.id = {id}')[0]
            #employee = Employee.objects.filter(pk=id).first()
    context = {
        'employee' : employee,

    }
    return render(request, 'view_employee.html',context)

def manage_employees(request):
    employee = {}
    #departments = Department.objects.all()
    departments =Department.objects.raw('SELECT * FROM emp_department')
    if request.method == 'GET':
        data =  request.GET
        id = ''
        if 'id' in data:
            id= data['id']
        if id.isnumeric() and int(id) > 0:
            employee = Employee.objects.raw(f'SELECT * FROM emp_employee WHERE emp_employee.id = {id}')[0]
            #employee = Employee.objects.filter(id=id).first()
    context = {
        'employee' : employee,
        'departments' : departments,

    }
    return render(request, 'manage_employee.html',context)

def save_employee(request):
    data =  request.POST
    resp = {'status':'failed'}
    print(data)
    if (data['id']).isnumeric() and int(data['id']) > 0:
        check  = Employee.objects.filter(pk = data['id'])
        if check:
            d_id=data['department_id']
            e_id=data['id']
            name=data['firstname']
            salary=data['salary']
            #dept = Department.objects.filter(id=data['department_id']).first()

            q=f'UPDATE emp_employee SET name = \'{name}\', department_id = {d_id}, salary = {salary} WHERE emp_employee.id = {e_id}'
            Employee.objects.raw(q)[:]

            #Employee.objects.filter(id = data['id']).update(name = data['firstname'],department = dept,salary = data['salary'])
        resp['status'] = 'success'

    else:
        try:
            d_id=data['department_id']
            e_id=data['id']
            name=data['firstname']
            salary=data['salary']
            # dept = Department.objects.filter(id=data['department_id']).first()
            # save_employee = Employee(name = data['firstname'],department= dept,salary = data['salary'])
            # save_employee.save()
            q=f'INSERT INTO emp_employee (name, salary, department_id) VALUES (\'{name}\', {salary}, {d_id}) RETURNING emp_employee.id'
            Employee.objects.raw(q)[:]
            resp['status'] = 'success'
        except Exception as e:
            resp['status'] = 'success'
            print(e)
    return HttpResponse(json.dumps(resp), content_type="application/json")

def delete_employee(request):
    data =  request.POST
    resp = {'status':''}
    try:
        #Employee.objects.filter(pk = data['id']).delete()
        e_id=data['id']
        Employee.objects.raw(f'DELETE FROM emp_employee WHERE emp_employee.id= {e_id}')[:]
        resp['status'] = 'success'
    except:
        resp['status'] = 'success'
    return HttpResponse(json.dumps(resp), content_type="application/json")

def task(request):
    #task_list = Task.objects.all()
    task_list =Task.objects.raw('SELECT * FROM emp_task')
    return render(request,'task.html',{'task_list':task_list})

def view_task(request):
    task = {}
    if request.method == 'GET':
        data =  request.GET
        id = ''
        if 'id' in data:
            id= data['id']
            print("aaaa",id)
        if id.isnumeric() and int(id) > 0:
            #task = Task.objects.filter(pk=id).first()
            task=Task.objects.raw(f'SELECT * FROM emp_task WHERE emp_task.id = {id}')[0]
    context = {
        'task' : task,

    }
    return render(request, 'view_task.html',context)

def manage_task(request):
    task = {}
    status = ["ACCEPTED","COMPLETED"]
    if request.method == 'GET':
        data =  request.GET
        id = ''
        if 'id' in data:
            id= data['id']
        if id.isnumeric() and int(id) > 0:
            #task = Task.objects.filter(id=id).first()
            task=Task.objects.raw(f'SELECT * FROM emp_task WHERE emp_task.id = {id}')[0]
    context = {
        'task' : task,
        'status' : status,

    }
    return render(request, 'manage_task.html',context)

def save_task(request):
    data =  request.POST
    resp = {'statuss':'failed'}
    try:
        if (data['id']).isnumeric() and int(data['id']) > 0 :
            t_id=data['id']
            t_name=data['id']
            t_status=data['status']
            #save_task = Task.objects.filter(pk = data['id']).update(t_name=data['id'],status=data['status'])
            q=f'UPDATE emp_task SET t_name = \'{t_name}\', status = \'{t_status}\' WHERE emp_task.id = {t_id}'
            Task.objects.raw(q)[:]

            resp['statuss'] = 'success'
    except:
        resp['statuss'] = 'success'
    return HttpResponse(json.dumps(resp), content_type="application/json")

def delete_task(request):
    data =  request.POST
    resp = {'status':''}
    try:
        #Task.objects.filter(id = data['id']).delete()
        t_id=data['id']
        Task.objects.raw(f'DELETE FROM emp_task WHERE emp_task.id = {t_id}')[:]
        resp['status'] = 'success'
    except:
        resp['status'] = 'success'
    return HttpResponse(json.dumps(resp), content_type="application/json")

def add_new_task(request):
    status = ["ACCEPTED","COMPLETED"]
    #employee = Employee.objects.all()
    employee =Employee.objects.raw('SELECT * FROM emp_employee')
    context = {
        'employee' : employee,
        'status' : status,

    }
    return render(request, 'add_new_task.html',context)

def save_new_task(request):
    data =  request.POST
    resp = {'status':''}
    try:
        # emp=Employee.objects.get(pk=data['employee_id'])
        # Task(employee=emp,t_name=data['task_name'],status=data['status_id']).save()
        e_id=data['employee_id']
        t_name=data['task_name']
        t_status=data['status_id']
        q=f'INSERT INTO emp_task (employee_id, t_name, status) VALUES ({e_id}, \'{t_name}\', \'{t_status}\') RETURNING emp_task.id'
        Task.objects.raw(q)[:]
        resp['status'] = 'success'
    except:

        resp['status'] = 'success'
    return HttpResponse(json.dumps(resp), content_type="application/json")

def signle_emp(request):
    emp=Employee.objects.all()
    return render(request,"single.html",{"emp":emp})

def emp_task(request):
    task = {}
    if request.method == 'GET':
        data =  request.GET
        id = ''
        if 'id' in data:
            id= data['id']
            print("aaaa",id)
        if id.isnumeric() and int(id) > 0:
            #task = Task.objects.filter(pk=id).first()
            task=Task.objects.raw(f'SELECT * FROM emp_task WHERE emp_task.id = {id}')[0]
    context = {
        'task' : task,

    }
    return render(request, 'single.html',context)

##############################################################################################################
class DepartmentList(generics.ListAPIView):
    queryset = Department.objects.raw('SELECT * FROM emp_department')
    serializer_class = DepartmentSerializer

class DepartmentCreate(generics.CreateAPIView):
    queryset = Department.objects.raw('SELECT * FROM emp_department')
    serializer_class = DepartmentSerializer

class DepartmentRetrieve(generics.RetrieveAPIView):
    queryset = Department.objects.raw('SELECT * FROM emp_department')
    serializer_class = DepartmentSerializer

class DepartmentUpdate(generics.UpdateAPIView):
    queryset = Department.objects.raw('SELECT * FROM emp_department')
    serializer_class = DepartmentSerializer

class DepartmentDestroy(generics.DestroyAPIView):
    queryset = Department.objects.raw('SELECT * FROM emp_department')
    serializer_class = DepartmentSerializer

class EmployeeList(generics.ListAPIView):
    queryset = Employee.objects.raw('SELECT * FROM emp_employee')
    serializer_class = EmployeeSerializer

class EmployeeCreate(generics.CreateAPIView):
    queryset = Employee.objects.raw('SELECT * FROM emp_employee')
    serializer_class = EmployeeSerializer

class EmployeeRetrieve(generics.RetrieveAPIView):
    queryset = Employee.objects.raw('SELECT * FROM emp_employee')
    serializer_class = EmployeeSerializer

class EmployeeUpdate(generics.UpdateAPIView):
    queryset = Employee.objects.raw('SELECT * FROM emp_employee')
    serializer_class = EmployeeSerializer

class EmployeeDestroy(generics.DestroyAPIView):
    queryset = Employee.objects.raw('SELECT * FROM emp_employee')
    serializer_class = EmployeeSerializer

class TaskList(generics.ListAPIView):
    queryset = Task.objects.raw('SELECT * FROM emp_task')
    serializer_class = TaskSerializer

class TaskCreate(generics.CreateAPIView):
    queryset = Task.objects.raw('SELECT * FROM emp_task')
    serializer_class = TaskSerializer

class TaskRetrieve(generics.RetrieveAPIView):
    queryset = Task.objects.raw('SELECT * FROM emp_task')
    serializer_class = TaskSerializer

class TaskUpdate(generics.UpdateAPIView):
    queryset = Task.objects.raw('SELECT * FROM emp_task')
    serializer_class = TaskSerializer

class TaskDestroy(generics.DestroyAPIView):
    queryset = Task.objects.raw('SELECT * FROM emp_task')
    serializer_class = TaskSerializer


from django.db import models

from applications.locations.models import Location

class Schedule(models.Model):

    id = models.BigAutoField(
        primary_key=True,
        verbose_name='Id Horario'
    )

    location = models.ForeignKey(
        Location,
        verbose_name='Sede',
        null=False,
        on_delete=models.CASCADE
    )

    begin_validity = models.DateField(
        verbose_name='Inicio de vigencia'
    )

    end_validity = models.DateField(
        verbose_name='Fin vigencia'
    )

    class Meta:
        verbose_name='Horario'
        verbose_name_plural='Horarios'

    def __str__(self):
        return '{0} - {1}'.format(self.id, self.location)

class Schedule_Day(models.Model):

    WEEKDAY  = 'WD'
    SATURDAY = 'SA'
    SUNDAY   = 'SU'
    HOLIDAY  = 'HO'

    DAYS_CHOICES = [
        ( WEEKDAY, 'Lunes a Viernes' ),
        ( SATURDAY, 'Sábado' ),
        ( SUNDAY, 'Domingo' ),
        ( HOLIDAY, 'Festivo' )
    ]

    schedule = models.ForeignKey(
        Schedule,
        related_name='day_type',
        verbose_name='Id Horario',
        on_delete=models.CASCADE
    )

    daytype = models.CharField(
        verbose_name='Tipo de Día',
        max_length=2,
        choices=DAYS_CHOICES,
        default=WEEKDAY
    )

    is_open = models.BooleanField(
        verbose_name='¿Está abierto?',
        default=False
    )

    class Meta:
        verbose_name='Día horario'
        verbose_name_plural='Días horario'
        unique_together = ['schedule','daytype']

    def __str__(self):
        return '{0} - {1}'.format(self.schedule, self.daytype)

    def get_daytype(self,weekday: int):

        if weekday >= 1 and weekday <= 5:
            return self.WEEKDAY
        elif weekday == 6:
            return self.SATURDAY
        elif weekday == 7:
            return self.SUNDAY

class Schedule_Slot(models.Model):

    schedule_day = models.ForeignKey(
        Schedule_Day,
        related_name='timeslot',
        verbose_name='Día',
        on_delete=models.CASCADE
    )

    slot = models.IntegerField(
        verbose_name='Slot'
    )

    starttime = models.TimeField(
        verbose_name='Hora Inicio'
    )

    endtime = models.TimeField(
        verbose_name='Hora Fin'
    )

    class Meta:
        verbose_name = 'Bloque horario'
        verbose_name_plural = 'Bloques horario'
        unique_together = ['schedule_day','slot']
        ordering = ['slot']

    def __str__(self):
        return '{0} : {1} - {2}'.format(
            self.schedule_day,
            self.starttime,
            self.endtime
        )


import pyautogui
from random import random
import pyscreenshot as ImageGrab
import math
import cv2 as cv
from utilities import inventory as inv
from utilities.core import get_bounding_rect_from_pts

def get_pickup_rects(o_img, cnts):  # returns bounding rect(s) of item(s) to pickup
    items = []
    line_pts = []
    for c in cnts:
        # compute the center of each contour
        M = cv.moments(c)
        if M["m00"] != 0:
            cX = int(M["m10"] / M["m00"])
            cY = int(M["m01"] / M["m00"])
            line_pts.append((cX, cY))
    # cv.rectangle(output,(minx,miny),(maxx,maxy),(0,255,255),2)
    maxslope = 0
    item_split_indices = [0]
    for x in range(1, len(line_pts) - 2):
        x1, y1 = (line_pts[x - 1])
        x2, y2 = (line_pts[x])
        if (x2 - x1) != 0:
            m = (y2 - y1) / (x2 - x1)
            if m > maxslope:
                maxslope = m
            if (m <= 0.05) and (m >= -0.05):
                cv.line(o_img, line_pts[x - 1], line_pts[x], (0, 255, 255), 2)
            else:
                # split lines based on slope and dist
                # print(item_split_indices)
                # print(math.dist((x1,y1),(x2,y2)))
                if (math.dist((x1, y1), (x2, y2))) >= 40 and x != 1:
                    item_split_indices.append(x)
    if len(item_split_indices) == 1:
        rect = get_bounding_rect_from_pts(line_pts[1:len(line_pts)])
        if rect not in items:
            items.append(rect)
    elif (len(item_split_indices) > 1):
        for i in range(0, len(item_split_indices) - 1):
            if i == 0:
                rect = get_bounding_rect_from_pts(line_pts[1:item_split_indices[i + 1]])
            elif (i + 1 <= len(item_split_indices) + 1):
                rect = get_bounding_rect_from_pts(line_pts[item_split_indices[i]:item_split_indices[i + 1]])
            if rect not in items:
                items.append(rect)
    for item in items:
        cv.rectangle(o_img, item[0], item[1], (0, 0, 255), 1)
    return items

def bury_bones(min_bone_count):
    inv_img, bones = inv.get_item_rects(inv.get_icon(526))
    inv_img2, big_bones = inv.get_item_rects(inv.get_icon(532))
    if len(bones) + len(big_bones) > min_bone_count:
        for rect in bones:
            rect[0]
            pt = ((rect[0][0] + 625 + rect[1][0] + 625) / 2, (rect[0][1] + 485 + rect[1][1] + 485) / 2)
            pyautogui.moveTo(pt)
            pyautogui.click(clicks=1, interval=random() * 3, button='left')
        for rect in big_bones:
            rect[0]
            pt = ((rect[0][0] + 625 + rect[1][0] + 625) / 2, (rect[0][1] + 485 + rect[1][1] + 485) / 2)
            pyautogui.moveTo(pt)
            pyautogui.click(clicks=1, interval=random() * 3, button='left')

def start(targets, items, players, target_mask, selected):
    combat_img = ImageGrab.grab(bbox=[10, 50, 140, 69])
    enemy_name = pytesseract.image_to_string(combat_img)
    for name in marked_enemy_names:
        if enemy_name != None:
            if similar(enemy_name, name) > 0.7:
                enemy_name = name

    min_dist = 3000
    other_players_target = None

    for r in targets:
        for p in players:
            dist = math.sqrt(math.pow(r[0] - p[0][0], 2) + math.pow(r[1] - p[0][1], 2))
            if p in items:
                players.remove(p)

            if dist < 200:
                if r in targets:
                    if (dist < min_dist):
                        if r[2] > 30:
                            other_players_target = r
                    targets.remove(r)
                continue
        if r[2] > 10 and r in targets:
            cv.rectangle(target_mask, (r[0], r[1]), (r[0] + r[2], r[1] + r[3]), (0, 255, 255), 2)

    if other_players_target is not None:
        if len(players) >= 1:
            if players[0] not in items:
                cv.line(target_mask, (other_players_target[0], other_players_target[1]),
                        (players[0][0][0], players[0][0][1]), (0, 255, 255), 2)
        cv.rectangle(target_mask, (other_players_target[0], other_players_target[1]), (
        other_players_target[0] + other_players_target[2], other_players_target[1] + other_players_target[3]),
                     (0, 40, 255), 2)

    if random() > 0.95:
        bury_bones(0)
    if enemy_name not in marked_enemy_names:
        if len(items) >= 1:
            # item pickup
            item = items[0]
            min = item[0]
            max = item[1]
            pyautogui.moveTo((min[0] + max[0]) / 2, ((min[1] + max[1]) / 2) + 10)
            pyautogui.click(clicks=2, interval=random(), button='left')
        elif len(rects[4]) > 0:
            # need combat panel screengrab and imagetotext
            # if in combat dont move cursor or click
            #
            if selected != targets[0]:
                selected = targets[0]
                pyautogui.moveTo((selected[0] + selected[2] / 2), (selected[1] + selected[3] / 2))
                pyautogui.click(button='left', clicks=1, interval=random())


import numpy as np
n=np.genfromtxt('matrix1.csv',delimiter=',')
import numpy as ap
a=ap.genfromtxt('inmat.csv',delimiter=' ')
import numpy as bp
b=bp.genfromtxt('outmat.csv',delimiter=' ')
k=n[:,0:7]
k1=n[:,8:83]
p=[sum(k[i]) for i in range(83)]
p1=[sum(k1[i]) for i in range(83)]
cluster1=[]
cluster2=[]
cluster3=[]
cluster4=[]
for i in range(len(p)):
 if p1[i]<=5*p[i] and a[i]<=3 and b[i]<=3:
  cluster1.append(i)
 elif p1[i]<=6*p[i] and a[i]<=3 and b[i]<=3:
  cluster2.append(i)
 elif p1[i]<=7*p[i] and a[i]<=3 and b[i]<=3:
  cluster3.append(i)
 else:
   cluster4.append(i)
len(cluster1)
len(cluster2)
len(cluster3)
len(cluster4)
print("cluster1")
cluster1
print("cluster2")
cluster2
print("cluster3")
cluster3
print("cluster4")
cluster4