From 86346b9c5bb9c382d8380c63213fe6657c65aba8 Mon Sep 17 00:00:00 2001 From: Maxim Slipenko Date: Mon, 2 Oct 2023 21:24:28 +0300 Subject: [PATCH] =?UTF-8?q?refactor:=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BF?= =?UTF-8?q?=D0=B8=D1=81=D0=B0=D0=BD=D1=8B=20=D0=BC=D0=BE=D0=B4=D0=B5=D0=BB?= =?UTF-8?q?=D0=B8=20(#52)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #47 --- statapp/calculations.py | 25 ++++++++++ statapp/main_window.py | 32 ++---------- statapp/models/data_model.py | 59 ----------------------- statapp/models/editable_table_model.py | 30 ++++++++++++ statapp/models/input_values_model.py | 16 ++++++ statapp/models/ro_table_model.py | 4 -- statapp/models/utils.py | 2 + statapp/models/variance_analysis_model.py | 3 +- 8 files changed, 80 insertions(+), 91 deletions(-) delete mode 100644 statapp/models/data_model.py create mode 100644 statapp/models/editable_table_model.py create mode 100644 statapp/models/input_values_model.py create mode 100644 statapp/models/utils.py diff --git a/statapp/calculations.py b/statapp/calculations.py index 08ce6cd..d06abd1 100644 --- a/statapp/calculations.py +++ b/statapp/calculations.py @@ -1,5 +1,30 @@ import numpy as np +DIRECT_LINK = 0 +INDIRECT_LINK = 1 + +def generate_x_values(mean, std, typeConnection, y): + yMean = np.mean(y) + values = [] + for cur_y in y: + k = np.abs(cur_y / yMean) + if k > 1: + k = 2 - 1 / k + if typeConnection == INDIRECT_LINK: + k = 1 / k + if std == 0: + k = 1 + + x = np.random.normal(mean * (k ** 3), std * k) + values.append(x) + # if (x > gfw.mat and cur_y > yMat) or (x < gfw.mat and cur_y < yMat): + # dd = np.append(dd, 1) + # else: + # dd = np.append(dd, 0) + + # x_arr = x_arr.reshape(len(x_arr), 1) + + return np.array(values) def variance_analysis(data): return np.array([ diff --git a/statapp/main_window.py b/statapp/main_window.py index 9973cb7..e6e02f0 100644 --- a/statapp/main_window.py +++ b/statapp/main_window.py @@ -3,8 +3,9 @@ from PySide2.QtCore import Slot, QLocale, QSize from PySide2.QtGui import QIcon from PySide2.QtWidgets import QMainWindow, QMessageBox, QApplication +from statapp.calculations import generate_x_values from statapp.generate_factor_window import GenerateFactorWindow, INDIRECT_LINK -from statapp.models.data_model import DataModel +from statapp.models.input_values_model import InputValuesModel from statapp.generate_window import GenerateWindow from statapp.about_window import AboutWindow from statapp.models.fileslc_model import FileSLCModel @@ -25,7 +26,7 @@ class MainWindow(QMainWindow): self.setWindowIcon(icon) self.isDataChanged = False - self.model = DataModel() + self.model = InputValuesModel() self.fileModel = FileSLCModel() self.ui.tableView.setModel(self.model) @@ -81,36 +82,13 @@ class MainWindow(QMainWindow): def on_generateXaction_triggered(self): gfw = GenerateFactorWindow() - # dd = np.array([]) - if gfw.exec(): - y = self.model.getY() - yMat = np.mean(y) - - x_arr = np.array([]) - - for cur_y in y: - k = np.abs(cur_y / yMat) - if k > 1: - k = 2 - 1 / k - if gfw.typeConnection == INDIRECT_LINK: - k = 1 / k - if gfw.deviation == 0: - k = 1 - - x = np.random.normal(gfw.mat * (k ** 3), gfw.deviation * k, size=1) - x_arr = np.append(x_arr, x) - # if (x > gfw.mat and cur_y > yMat) or (x < gfw.mat and cur_y < yMat): - # dd = np.append(dd, 1) - # else: - # dd = np.append(dd, 0) - data = self.model.getData() - + y = self.model.getY() + x_arr = generate_x_values(gfw.mat, gfw.deviation, gfw.typeConnection, y) x_arr = x_arr.reshape(len(x_arr), 1).round(2) # dd = dd.reshape(len(dd), 1) data = np.concatenate((data, x_arr), axis=1) - # data = np.concatenate((data, dd), axis=1) self.model.updateAllData(data) self.isDataChanged = True diff --git a/statapp/models/data_model.py b/statapp/models/data_model.py deleted file mode 100644 index c9ade7d..0000000 --- a/statapp/models/data_model.py +++ /dev/null @@ -1,59 +0,0 @@ -import numpy as np -from PySide2 import QtCore -from PySide2.QtCore import Qt - - -class DataModel(QtCore.QAbstractTableModel): - def __init__(self, data=np.array([[]], dtype=np.float32)): - super().__init__() - - self._data = data - - def updateAllData(self, data): - self.layoutAboutToBeChanged.emit() - self._data = data - self.layoutChanged.emit() - - def rowCount(self, index): - return self._data.shape[0] - - def columnCount(self, index): - return self._data.shape[1] - - def headerData(self, section: int, orientation: Qt.Orientation, role: int = ...): - if role == Qt.DisplayRole: - # if orientation == Qt.Orientation.Horizontal: - - if section == 0: - return 'Y' - - return f'X{section}' - - return None - - def flags(self, index): - return Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable - - def setData(self, index, value, role): - if role == Qt.EditRole: - try: - value = float(value) - except ValueError: - return False - self._data[index.row(), index.column()] = value - return True - return False - - def getData(self): - return self._data - - def getY(self): - return self._data[:, 0] - - - def data(self, index, role): - if role == Qt.DisplayRole or role == Qt.EditRole: - # ? - return float(self._data[index.row(), index.column()]) - - return None \ No newline at end of file diff --git a/statapp/models/editable_table_model.py b/statapp/models/editable_table_model.py new file mode 100644 index 0000000..e2328e6 --- /dev/null +++ b/statapp/models/editable_table_model.py @@ -0,0 +1,30 @@ +import numpy as np +from PySide2.QtCore import Qt + +from statapp.models.ro_table_model import ROTableModel + + +class EditableTableModel(ROTableModel): + def __init__(self, data=np.array([[]], dtype=np.float32)): + super().__init__() + + self._data = data + + def flags(self, index): + return Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable + + def setData(self, index, value, role): + if role == Qt.EditRole: + try: + value = float(value) + except ValueError: + return False + self._data[index.row(), index.column()] = value + return True + return False + + def data(self, index, role): + if role == Qt.DisplayRole or role == Qt.EditRole: + return float(self._data[index.row(), index.column()]) + + return None diff --git a/statapp/models/input_values_model.py b/statapp/models/input_values_model.py new file mode 100644 index 0000000..6f5629c --- /dev/null +++ b/statapp/models/input_values_model.py @@ -0,0 +1,16 @@ +import numpy as np +from PySide2.QtCore import Qt, QModelIndex + +from statapp.models.editable_table_model import EditableTableModel +from statapp.models.utils import yx_header + + +class InputValuesModel(EditableTableModel): + def __init__(self, data=np.array([[]], dtype=np.float32)): + super().__init__(data) + + def getHorizontalHeader(self): + return yx_header(self.rowCount(QModelIndex())) + + def getY(self): + return self._data[:, 0] diff --git a/statapp/models/ro_table_model.py b/statapp/models/ro_table_model.py index cb67ee9..aad69aa 100644 --- a/statapp/models/ro_table_model.py +++ b/statapp/models/ro_table_model.py @@ -43,10 +43,6 @@ class ROTableModel(QtCore.QAbstractTableModel): def getData(self): return self._data - def getY(self): - return self._data[:, 0] - - def data(self, index, role): if role == Qt.DisplayRole: return float(self._data[index.row(), index.column()]) diff --git a/statapp/models/utils.py b/statapp/models/utils.py new file mode 100644 index 0000000..6f8b3ba --- /dev/null +++ b/statapp/models/utils.py @@ -0,0 +1,2 @@ +def yx_header(count): + return ['Y'] + [f'X{i}' for i in range(1, count)] diff --git a/statapp/models/variance_analysis_model.py b/statapp/models/variance_analysis_model.py index 8a57895..fc37522 100644 --- a/statapp/models/variance_analysis_model.py +++ b/statapp/models/variance_analysis_model.py @@ -1,6 +1,7 @@ from PySide2.QtCore import QModelIndex from statapp.models.ro_table_model import ROTableModel +from statapp.models.utils import yx_header class VarianceAnalysisModel(ROTableModel): @@ -11,4 +12,4 @@ class VarianceAnalysisModel(ROTableModel): return ['Мат. ожидание', 'Среднекв. отклонение', 'Минимум', 'Максимум'] def getVerticalHeader(self): - return ['Y'] + [f'X{i}' for i in range(1, self.rowCount(QModelIndex()))] + return yx_header(self.rowCount(QModelIndex()))