9 Commits

Author SHA1 Message Date
github-actions[bot]
4f1f610822 chore(main): release 0.7.0 (#88)
🤖 I have created a release *beep* *boop*
---


## [0.7.0](https://github.com/shizand/statapp/compare/v0.6.0...v0.7.0)
(2023-12-01)


### Новые функции

* добавлена возможность ввода чисел до 5 знаков
([#87](https://github.com/shizand/statapp/issues/87))
([dc7c487](dc7c4875d7)),
closes [#82](https://github.com/shizand/statapp/issues/82)
* Добавлены новые характеристики
([#89](https://github.com/shizand/statapp/issues/89))
([b12db5a](b12db5a300)),
closes [#84](https://github.com/shizand/statapp/issues/84)

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-12-01 14:11:49 +03:00
b12db5a300 feat: Добавлены новые характеристики (#89)
Closes #84
2023-12-01 14:03:20 +03:00
dc7c4875d7 feat: добавлена возможность ввода чисел до 5 знаков (#87)
Closes #82
2023-11-25 14:21:05 +03:00
2f5988a2eb chore: исправляет форматирование 2023-10-25 17:11:09 +03:00
9348138094 chore: исправляет описание в "Установка" 2023-10-25 17:09:30 +03:00
c35b9ca308 chore: исправляет опечатки 2023-10-25 15:58:06 +03:00
e6ba0fc610 ci: Revert "добавил сборку linux x86"
This reverts commit 4be89269b9.
2023-10-20 14:46:57 +03:00
cddacb21b2 Merge remote-tracking branch 'origin/main' 2023-10-20 14:20:27 +03:00
4be89269b9 ci: добавил сборку linux x86 2023-10-20 14:20:12 +03:00
24 changed files with 398 additions and 356 deletions

View File

@@ -1,5 +1,13 @@
# Changelog
## [0.7.0](https://github.com/shizand/statapp/compare/v0.6.0...v0.7.0) (2023-12-01)
### Новые функции
* добавлена возможность ввода чисел до 5 знаков ([#87](https://github.com/shizand/statapp/issues/87)) ([dc7c487](https://github.com/shizand/statapp/commit/dc7c4875d7e15ad8c9ae5fa16b4b589d156632dd)), closes [#82](https://github.com/shizand/statapp/issues/82)
* Добавлены новые характеристики ([#89](https://github.com/shizand/statapp/issues/89)) ([b12db5a](https://github.com/shizand/statapp/commit/b12db5a3003802830784e26a14097ee9d68a0e64)), closes [#84](https://github.com/shizand/statapp/issues/84)
## [0.6.0](https://github.com/shizand/statapp/compare/v0.5.0...v0.6.0) (2023-10-20)

View File

@@ -5,13 +5,13 @@
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/c4e370d74a8a4575b79afa8b9b74d130)](https://app.codacy.com/gh/shizand/statapp/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
![License info](https://img.shields.io/github/license/shizand/statapp)
Автоматизированное программное средство по статистическому анализу и регрессионному моделированию. Является идейным продолжателем программы STAT.exe (Produced by Reutov V.N., Donetsk University, 1990)
Автоматизированное программное средство по статистическому анализу и регрессионному моделированию. Является идейным продолжателем программы STAT.exe (Produced by Reutov V.N., Donetsk University, 1990).
Разработано двумя студентами ФГБОУ ВО «ДонНТУ» для своего университета.
## Поддерживаемые ОС и архитектуры
В теории, должно работать на любой архитектуре и ОС где запускается Python 3.8 и есть Qt 5.
В теории, должно работать на любой архитектуре и ОС, где запускается Python 3.8 и есть Qt 5.
Работоспособность проверена на x64:
@@ -20,7 +20,11 @@
## Установка
Существует два варианта statapp и statapp-onefile. Различия в том, что onefile версия поставляется одним единственным бинарным файлом. На Windows системах с включенным антивирусом это может вызывать [некоторые проблемы](https://qna.habr.com/q/988553).
Программа распространяется с помощью [PyInstaller](https://pyinstaller.org/en/stable/).
Существует две версиии: **statapp** и **statapp-onefile**.
Различия в том, что onefile версия поставляется одним единственным бинарным файлом. На Windows системах с включенным антивирусом это может вызывать [некоторые проблемы](https://qna.habr.com/q/988553).
### Готовые двоичные файлы

View File

@@ -1,6 +1,6 @@
[tool.poetry]
name = "statapp"
version = "0.6.0"
version = "0.7.0"
description = ""
authors = [
"Maxim Slipenko <statapp@maks1ms.addy.io>"

View File

@@ -9,8 +9,7 @@
# See the GPL-3.0 license for details.
import itertools
import numpy as np
from numpy import linalg, zeros, ones, hstack, asarray, diagonal
from numpy import linalg, zeros, ones, hstack, asarray
from sympy import symbols, Mul, Add, S
@@ -90,15 +89,7 @@ def multipolyfit(xs, y, deg, full=False, modelOut=False, powersOut=False):
return beta, powers
if full:
residues = result[1]
dof = len(a) - len(beta)
mse = residues / dof
cov = mse * diagonal(linalg.inv(a.T @ a))
se = np.sqrt(cov)
tStatistics = beta / se
return result, powers, tStatistics, mse
return result, powers, a
return beta

View File

@@ -66,54 +66,72 @@ class RegressionResult:
Attributes:
paramsAndImportance (np.ndarray): Параметры модели. Первая колонка -
residualVariance (np.float64): Остаточная дисперсия
scaledResidualVariance (np.float64): Остаточная дисперсия (масштабированная)
monomials (list): Список одночленов в строковом виде без коэффициентов. Свободный член - c
"""
paramsAndImportance: np.ndarray
residualVariance: np.float64
scaledResidualVariance: np.float64
rSquared: np.float64
fStatistic: np.float64
monomials: list
def linearPolynom(inputData) -> RegressionResult:
def commonPolynom(inputData, deg) -> RegressionResult:
x = inputData[:, 1:]
y = inputData[:, 0]
data = pd.DataFrame(x)
data.insert(0, 'const', 1)
# ---
result = np.linalg.lstsq(data, y, rcond=None)
# Коэффициенты регрессии
params = result[0]
# Остатки
residues = result[1]
dof = len(data) - len(params)
result, powers, data = multipolyfit(x, y, deg, full=True)
(out, mse, scaledResidualVariance,
rSquared, fStatistic) = calculateStats(data, result[0], result[1], y)
return RegressionResult(
out.to_numpy(),
np.float64(mse),
np.float64(scaledResidualVariance),
np.float64(rSquared),
np.float64(fStatistic),
['c' if str(x) == '1' else str(x) for x in getTerms(powers)]
)
def linearPolynom(inputData) -> RegressionResult:
return commonPolynom(inputData, 1)
def squaredPolynom(inputData) -> RegressionResult:
return commonPolynom(inputData, 2)
def calculateStats(data, params, residues, y):
# pylint: disable-msg=too-many-locals
k = len(params) # Количество оцениваемых параметров (коэффициентов)
n = len(data) # Количество наблюдений
# Степень свободы (degrees of freedom) для остатков
dof = n - k # Количество наблюдений минус количество оцениваемых параметров
# Остаточная дисперсия (Mean Squared Error, MSE)
mse = residues / dof
# Среднее значение остатков
meanResiduals = np.sum(residues) / dof
# Масштабированная остаточная дисперсия
scaledResidualVariance = residues / meanResiduals ** 2
# Ковариационная матрица коэффициентов
cov = mse * np.diagonal(np.linalg.inv(data.T @ data))
# Стандартные ошибки коэффициентов
se = np.sqrt(cov)
# T-статистики для каждого коэффициента регрессии
tStatistics = params / se
# возможно стоит сделать через np.reshape + np.concatenate
# R-squared (коэффициент множественной детерминации)
sst = np.sum((y - np.mean(y)) ** 2) # Сумма квадратов отклонений
rSquared = 1 - (mse[0] / sst)
# F-statistic (статистика Фишера)
fStatistic = (rSquared / (k - 1)) / ((1 - rSquared) / (n - k))
out = pd.DataFrame()
out[0] = params
out[1] = tStatistics
return RegressionResult(
out.to_numpy(),
np.float64(mse[0]),
['c'] + [f'x{i}' for i in range(1, len(params))]
)
def squaredPolynom(inputData):
x = inputData[:, 1:]
y = inputData[:, 0]
result, powers, tStatistics, mse = multipolyfit(x, y, 2, full=True)
betas = result[0]
out = pd.DataFrame()
out[0] = betas
out[1] = tStatistics
return RegressionResult(
out.to_numpy(),
np.float64(mse[0]),
['c' if str(x) == '1' else str(x) for x in getTerms(powers)]
)
return out, mse[0], scaledResidualVariance, rSquared, fStatistic

20
statapp/constants.py Normal file
View File

@@ -0,0 +1,20 @@
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
NUMBERS_PRECISION = 5

View File

@@ -23,6 +23,7 @@ from PySide2.QtGui import QIcon
from PySide2.QtWidgets import QDialog, QHeaderView
from statapp.calculations import correlationAnalysis
from statapp.constants import NUMBERS_PRECISION
from statapp.mathtex_header_view import MathTexHeaderView
from statapp.models.correlation_analysis_model import CorrelationAnalysisModel
from statapp.ui.ui_correlation_analysis_window import Ui_CorrelationAnalysisWindow
@@ -36,7 +37,7 @@ class CorrelationAnalysisWindow(QDialog):
self.ui.setupUi(self)
res = correlationAnalysis(data)
self.model = CorrelationAnalysisModel(res.round(2))
self.model = CorrelationAnalysisModel(res.round(NUMBERS_PRECISION))
self.ui.tableView.setModel(self.model)
self.ui.tableView.setVerticalHeader(
MathTexHeaderView(self.ui.tableView)

View File

@@ -23,16 +23,17 @@ from PySide2.QtCore import Slot
from PySide2.QtWidgets import QMainWindow, QMessageBox
from statapp.calculations import generateXValues, generateYValues
from statapp.constants import NUMBERS_PRECISION
from statapp.generate_factor_window import GenerateFactorWindow
from statapp.linear_polynom_window import LinearPolynomWindow
from statapp.polynoms.linear_polynom_window import LinearPolynomWindow
from statapp.mathtex_header_view import MathTexHeaderView
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
from statapp.squared_polynom_window import SquaredPolynomWindow
from statapp.polynoms.squared_polynom_window import SquaredPolynomWindow
from statapp.ui.ui_main_window import Ui_MainWindow
from statapp.utils import buildMessageBox, addIcon
from statapp.utils import buildMessageBox, addIcon, FloatDelegate
from statapp.variance_analysis import VarianceAnalysisWindow
from statapp.correlation_analysis import CorrelationAnalysisWindow
@@ -62,6 +63,7 @@ class MainWindow(QMainWindow):
self.isDataChanged = False
self.model = InputValuesModel()
self.fileModel = FileSLCModel()
self.ui.tableView.setItemDelegate(FloatDelegate())
self.ui.tableView.setModel(self.model)
self.ui.tableView.setHorizontalHeader(
MathTexHeaderView(self.ui.tableView, orientation=QtCore.Qt.Horizontal)
@@ -150,7 +152,7 @@ class MainWindow(QMainWindow):
if gw.exec():
y = generateYValues(gw.mat, gw.deviation, gw.count)
self.model.updateAllData(y.round(2))
self.model.updateAllData(y.round(NUMBERS_PRECISION))
self.isDataChanged = True
@Slot()
@@ -161,7 +163,7 @@ class MainWindow(QMainWindow):
data = self.model.getData()
y = self.model.getY()
xValues = generateXValues(gfw.mat, gfw.deviation, gfw.typeConnection, y)
data = np.concatenate((data, xValues.round(2)), axis=1)
data = np.concatenate((data, xValues.round(NUMBERS_PRECISION)), axis=1)
self.model.updateAllData(data)
self.isDataChanged = True

View File

@@ -20,6 +20,7 @@
import numpy as np
from PySide2.QtWidgets import QFileDialog, QMessageBox
from statapp.constants import NUMBERS_PRECISION
from statapp.utils import buildMessageBox
@@ -57,7 +58,7 @@ class FileSLCModel:
None, "Сохранить файл", "", "Text Files (*.txt);;CSV Files (*.csv)"
)
if self.fileName:
np.savetxt(self.fileName, data, delimiter=",", fmt='%10.5f')
np.savetxt(self.fileName, data, delimiter=",", fmt=f"%.{NUMBERS_PRECISION}f")
return True
return False

View File

@@ -0,0 +1,27 @@
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from statapp.calculations import linearPolynom
from statapp.polynoms.polynom_window import PolynomWindow
class LinearPolynomWindow(PolynomWindow):
def __init__(self, data):
result = linearPolynom(data)
super().__init__(result, "Линейный полином")

View File

@@ -18,27 +18,28 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from PySide2.QtWidgets import QDialog, QHeaderView
from statapp.calculations import linearPolynom
from statapp.mathtex_header_view import MathTexHeaderView
from statapp.models.regression_result_model import RegressionResultModel
from statapp.ui.ui_linear_polynom_window import Ui_LinearPolynomWindow
from statapp.utils import addIcon
from statapp.ui.ui_polynom_window import Ui_PolynomWindow
from statapp.utils import addIcon, FloatDelegate
class LinearPolynomWindow(QDialog):
def __init__(self, data):
class PolynomWindow(QDialog):
def __init__(self, result, windowTitle):
super().__init__()
self.ui = Ui_LinearPolynomWindow()
self.ui = Ui_PolynomWindow()
self.ui.setupUi(self)
addIcon(self)
result = linearPolynom(data)
self.setWindowTitle(windowTitle)
self.model = RegressionResultModel(result)
self.ui.tableView.setItemDelegate(FloatDelegate())
self.ui.tableView.setModel(self.model)
self.ui.tableView.setVerticalHeader(MathTexHeaderView(self.ui.tableView))
header = self.ui.tableView.horizontalHeader()
header.setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
self.ui.residualVarianceValueLabel.setText(str(result.residualVariance))
self.ui.scaledResidualVarianceValueLabel.setText(str(result.scaledResidualVariance))
self.ui.fStatisticValueLabel.setText(str(result.fStatistic))
self.ui.rSquaredValueLabel.setText(str(result.scaledResidualVariance))

View File

@@ -17,28 +17,11 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from PySide2.QtWidgets import QDialog, QHeaderView
from statapp.calculations import squaredPolynom
from statapp.mathtex_header_view import MathTexHeaderView
from statapp.models.regression_result_model import RegressionResultModel
from statapp.ui.ui_squared_polynom_window import Ui_SquaredPolynomWindow
from statapp.utils import addIcon
from statapp.polynoms.polynom_window import PolynomWindow
class SquaredPolynomWindow(QDialog):
class SquaredPolynomWindow(PolynomWindow):
def __init__(self, data):
super().__init__()
self.ui = Ui_SquaredPolynomWindow()
self.ui.setupUi(self)
addIcon(self)
result = squaredPolynom(data)
self.model = RegressionResultModel(result)
self.ui.tableView.setModel(self.model)
self.ui.tableView.setVerticalHeader(MathTexHeaderView(self.ui.tableView))
header = self.ui.tableView.horizontalHeader()
header.setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
self.ui.residualVarianceValueLabel.setText(str(result.residualVariance))
super().__init__(result, "Квадратичный полином")

View File

@@ -71,6 +71,9 @@
<pointsize>12</pointsize>
</font>
</property>
<property name="decimals">
<number>5</number>
</property>
<property name="maximum">
<double>1000000.000000000000000</double>
</property>
@@ -83,6 +86,9 @@
<pointsize>12</pointsize>
</font>
</property>
<property name="decimals">
<number>5</number>
</property>
<property name="maximum">
<double>1000000.000000000000000</double>
</property>

View File

@@ -44,6 +44,9 @@
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="matSpinBox">
<property name="decimals">
<number>5</number>
</property>
<property name="maximum">
<double>1000000.000000000000000</double>
</property>
@@ -68,6 +71,9 @@
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="deviationSpinBox">
<property name="decimals">
<number>5</number>
</property>
<property name="maximum">
<double>1000000.000000000000000</double>
</property>

View File

@@ -1,59 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>LinearPolynomWindow</class>
<widget class="QDialog" name="LinearPolynomWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>630</width>
<height>400</height>
</rect>
</property>
<property name="windowTitle">
<string>Линейный полином</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QTableView" name="tableView">
<attribute name="horizontalHeaderMinimumSectionSize">
<number>40</number>
</attribute>
<attribute name="verticalHeaderMinimumSectionSize">
<number>40</number>
</attribute>
<attribute name="verticalHeaderDefaultSectionSize">
<number>40</number>
</attribute>
</widget>
</item>
<item row="1" column="0">
<layout class="QGridLayout" name="gridLayout_3">
<property name="topMargin">
<number>10</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="residualVarianceLabel">
<property name="text">
<string>Остаточная дисперсия:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="residualVarianceValueLabel">
<property name="text">
<string>undefined</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PolynomWindow</class>
<widget class="QDialog" name="PolynomWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>630</width>
<height>400</height>
</rect>
</property>
<property name="windowTitle">
<string>Полином</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QTableView" name="tableView">
<attribute name="horizontalHeaderMinimumSectionSize">
<number>40</number>
</attribute>
<attribute name="verticalHeaderMinimumSectionSize">
<number>40</number>
</attribute>
<attribute name="verticalHeaderDefaultSectionSize">
<number>40</number>
</attribute>
</widget>
</item>
<item row="1" column="0">
<layout class="QGridLayout" name="polynomResult">
<property name="topMargin">
<number>10</number>
</property>
<item row="0" column="1">
<widget class="QLabel" name="residualVarianceValueLabel">
<property name="text">
<string>undefined</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="scaledResidualVarianceValueLabel">
<property name="text">
<string>undefined</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="fStatisticLabel">
<property name="text">
<string>F1 - отношение Фишера</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="residualVarianceLabel">
<property name="text">
<string>Остаточная дисперсия:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="scaledResidualVarianceLabel">
<property name="text">
<string>Остаточная дисперсия (масштабированная):</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="rSquaredLabel">
<property name="text">
<string>Коэффициент множественной дереминизации</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="fStatisticValueLabel">
<property name="text">
<string>undefined</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="rSquaredValueLabel">
<property name="text">
<string>undefined</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -1,49 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SquaredPolynomWindow</class>
<widget class="QDialog" name="SquaredPolynomWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>630</width>
<height>400</height>
</rect>
</property>
<property name="windowTitle">
<string>Квадратичный полином</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QTableView" name="tableView"/>
</item>
<item row="1" column="0">
<layout class="QGridLayout" name="gridLayout_3">
<property name="topMargin">
<number>10</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="residualVarianceLabel">
<property name="text">
<string>Остаточная дисперсия:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="residualVarianceValueLabel">
<property name="text">
<string>undefined</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -71,6 +71,7 @@ class Ui_GenerateFactorWindow(object):
self.matSpinBox = QDoubleSpinBox(GenerateFactorWindow)
self.matSpinBox.setObjectName(u"matSpinBox")
self.matSpinBox.setFont(font)
self.matSpinBox.setDecimals(5)
self.matSpinBox.setMaximum(1000000.000000000000000)
self.gridLayout.addWidget(self.matSpinBox, 1, 1, 1, 1)
@@ -78,6 +79,7 @@ class Ui_GenerateFactorWindow(object):
self.deviationSpinBox = QDoubleSpinBox(GenerateFactorWindow)
self.deviationSpinBox.setObjectName(u"deviationSpinBox")
self.deviationSpinBox.setFont(font)
self.deviationSpinBox.setDecimals(5)
self.deviationSpinBox.setMaximum(1000000.000000000000000)
self.gridLayout.addWidget(self.deviationSpinBox, 2, 1, 1, 1)

View File

@@ -62,6 +62,7 @@ class Ui_GenerateWindow(object):
self.matSpinBox = QDoubleSpinBox(GenerateWindow)
self.matSpinBox.setObjectName(u"matSpinBox")
self.matSpinBox.setDecimals(5)
self.matSpinBox.setMaximum(1000000.000000000000000)
self.gridLayout.addWidget(self.matSpinBox, 1, 1, 1, 1)
@@ -80,6 +81,7 @@ class Ui_GenerateWindow(object):
self.deviationSpinBox = QDoubleSpinBox(GenerateWindow)
self.deviationSpinBox.setObjectName(u"deviationSpinBox")
self.deviationSpinBox.setDecimals(5)
self.deviationSpinBox.setMaximum(1000000.000000000000000)
self.gridLayout.addWidget(self.deviationSpinBox, 2, 1, 1, 1)

View File

@@ -1,82 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
## Form generated from reading UI file 'linear_polynom_window.ui'
##
## Created by: Qt User Interface Compiler version 5.15.2
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
class Ui_LinearPolynomWindow(object):
def setupUi(self, LinearPolynomWindow):
if not LinearPolynomWindow.objectName():
LinearPolynomWindow.setObjectName(u"LinearPolynomWindow")
LinearPolynomWindow.resize(630, 400)
self.gridLayout_2 = QGridLayout(LinearPolynomWindow)
self.gridLayout_2.setObjectName(u"gridLayout_2")
self.gridLayout = QGridLayout()
self.gridLayout.setObjectName(u"gridLayout")
self.tableView = QTableView(LinearPolynomWindow)
self.tableView.setObjectName(u"tableView")
self.tableView.horizontalHeader().setMinimumSectionSize(40)
self.tableView.verticalHeader().setMinimumSectionSize(40)
self.tableView.verticalHeader().setDefaultSectionSize(40)
self.gridLayout.addWidget(self.tableView, 0, 0, 1, 1)
self.gridLayout_3 = QGridLayout()
self.gridLayout_3.setObjectName(u"gridLayout_3")
self.gridLayout_3.setContentsMargins(-1, 10, -1, -1)
self.residualVarianceLabel = QLabel(LinearPolynomWindow)
self.residualVarianceLabel.setObjectName(u"residualVarianceLabel")
self.gridLayout_3.addWidget(self.residualVarianceLabel, 0, 0, 1, 1)
self.residualVarianceValueLabel = QLabel(LinearPolynomWindow)
self.residualVarianceValueLabel.setObjectName(u"residualVarianceValueLabel")
self.gridLayout_3.addWidget(self.residualVarianceValueLabel, 0, 1, 1, 1)
self.gridLayout.addLayout(self.gridLayout_3, 1, 0, 1, 1)
self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1)
self.retranslateUi(LinearPolynomWindow)
QMetaObject.connectSlotsByName(LinearPolynomWindow)
# setupUi
def retranslateUi(self, LinearPolynomWindow):
LinearPolynomWindow.setWindowTitle(QCoreApplication.translate("LinearPolynomWindow", u"\u041b\u0438\u043d\u0435\u0439\u043d\u044b\u0439 \u043f\u043e\u043b\u0438\u043d\u043e\u043c", None))
self.residualVarianceLabel.setText(QCoreApplication.translate("LinearPolynomWindow", u"\u041e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u0430\u044f \u0434\u0438\u0441\u043f\u0435\u0440\u0441\u0438\u044f:", None))
self.residualVarianceValueLabel.setText(QCoreApplication.translate("LinearPolynomWindow", u"undefined", None))
# retranslateUi

118
statapp/ui/ui_polynom_window.py generated Normal file
View File

@@ -0,0 +1,118 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
## Form generated from reading UI file 'polynom_window.ui'
##
## Created by: Qt User Interface Compiler version 5.15.2
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
class Ui_PolynomWindow(object):
def setupUi(self, PolynomWindow):
if not PolynomWindow.objectName():
PolynomWindow.setObjectName(u"PolynomWindow")
PolynomWindow.resize(630, 400)
self.gridLayout_2 = QGridLayout(PolynomWindow)
self.gridLayout_2.setObjectName(u"gridLayout_2")
self.gridLayout = QGridLayout()
self.gridLayout.setObjectName(u"gridLayout")
self.tableView = QTableView(PolynomWindow)
self.tableView.setObjectName(u"tableView")
self.tableView.horizontalHeader().setMinimumSectionSize(40)
self.tableView.verticalHeader().setMinimumSectionSize(40)
self.tableView.verticalHeader().setDefaultSectionSize(40)
self.gridLayout.addWidget(self.tableView, 0, 0, 1, 1)
self.polynomResult = QGridLayout()
self.polynomResult.setObjectName(u"polynomResult")
self.polynomResult.setContentsMargins(-1, 10, -1, -1)
self.residualVarianceValueLabel = QLabel(PolynomWindow)
self.residualVarianceValueLabel.setObjectName(u"residualVarianceValueLabel")
self.polynomResult.addWidget(self.residualVarianceValueLabel, 0, 1, 1, 1)
self.scaledResidualVarianceValueLabel = QLabel(PolynomWindow)
self.scaledResidualVarianceValueLabel.setObjectName(u"scaledResidualVarianceValueLabel")
self.polynomResult.addWidget(self.scaledResidualVarianceValueLabel, 1, 1, 1, 1)
self.fStatisticLabel = QLabel(PolynomWindow)
self.fStatisticLabel.setObjectName(u"fStatisticLabel")
self.polynomResult.addWidget(self.fStatisticLabel, 2, 0, 1, 1)
self.residualVarianceLabel = QLabel(PolynomWindow)
self.residualVarianceLabel.setObjectName(u"residualVarianceLabel")
self.polynomResult.addWidget(self.residualVarianceLabel, 0, 0, 1, 1)
self.scaledResidualVarianceLabel = QLabel(PolynomWindow)
self.scaledResidualVarianceLabel.setObjectName(u"scaledResidualVarianceLabel")
self.polynomResult.addWidget(self.scaledResidualVarianceLabel, 1, 0, 1, 1)
self.rSquaredLabel = QLabel(PolynomWindow)
self.rSquaredLabel.setObjectName(u"rSquaredLabel")
self.polynomResult.addWidget(self.rSquaredLabel, 3, 0, 1, 1)
self.fStatisticValueLabel = QLabel(PolynomWindow)
self.fStatisticValueLabel.setObjectName(u"fStatisticValueLabel")
self.polynomResult.addWidget(self.fStatisticValueLabel, 2, 1, 1, 1)
self.rSquaredValueLabel = QLabel(PolynomWindow)
self.rSquaredValueLabel.setObjectName(u"rSquaredValueLabel")
self.polynomResult.addWidget(self.rSquaredValueLabel, 3, 1, 1, 1)
self.gridLayout.addLayout(self.polynomResult, 1, 0, 1, 1)
self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1)
self.retranslateUi(PolynomWindow)
QMetaObject.connectSlotsByName(PolynomWindow)
# setupUi
def retranslateUi(self, PolynomWindow):
PolynomWindow.setWindowTitle(QCoreApplication.translate("PolynomWindow", u"\u041f\u043e\u043b\u0438\u043d\u043e\u043c", None))
self.residualVarianceValueLabel.setText(QCoreApplication.translate("PolynomWindow", u"undefined", None))
self.scaledResidualVarianceValueLabel.setText(QCoreApplication.translate("PolynomWindow", u"undefined", None))
self.fStatisticLabel.setText(QCoreApplication.translate("PolynomWindow", u"F1 - \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0424\u0438\u0448\u0435\u0440\u0430", None))
self.residualVarianceLabel.setText(QCoreApplication.translate("PolynomWindow", u"\u041e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u0430\u044f \u0434\u0438\u0441\u043f\u0435\u0440\u0441\u0438\u044f:", None))
self.scaledResidualVarianceLabel.setText(QCoreApplication.translate("PolynomWindow", u"\u041e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u0430\u044f \u0434\u0438\u0441\u043f\u0435\u0440\u0441\u0438\u044f (\u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f):", None))
self.rSquaredLabel.setText(QCoreApplication.translate("PolynomWindow", u"\u041a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0434\u0435\u0440\u0435\u043c\u0438\u043d\u0438\u0437\u0430\u0446\u0438\u0438", None))
self.fStatisticValueLabel.setText(QCoreApplication.translate("PolynomWindow", u"undefined", None))
self.rSquaredValueLabel.setText(QCoreApplication.translate("PolynomWindow", u"undefined", None))
# retranslateUi

View File

@@ -1,79 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
## Form generated from reading UI file 'squared_polynom_window.ui'
##
## Created by: Qt User Interface Compiler version 5.15.2
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
class Ui_SquaredPolynomWindow(object):
def setupUi(self, SquaredPolynomWindow):
if not SquaredPolynomWindow.objectName():
SquaredPolynomWindow.setObjectName(u"SquaredPolynomWindow")
SquaredPolynomWindow.resize(630, 400)
self.gridLayout_2 = QGridLayout(SquaredPolynomWindow)
self.gridLayout_2.setObjectName(u"gridLayout_2")
self.gridLayout = QGridLayout()
self.gridLayout.setObjectName(u"gridLayout")
self.tableView = QTableView(SquaredPolynomWindow)
self.tableView.setObjectName(u"tableView")
self.gridLayout.addWidget(self.tableView, 0, 0, 1, 1)
self.gridLayout_3 = QGridLayout()
self.gridLayout_3.setObjectName(u"gridLayout_3")
self.gridLayout_3.setContentsMargins(-1, 10, -1, -1)
self.residualVarianceLabel = QLabel(SquaredPolynomWindow)
self.residualVarianceLabel.setObjectName(u"residualVarianceLabel")
self.gridLayout_3.addWidget(self.residualVarianceLabel, 0, 0, 1, 1)
self.residualVarianceValueLabel = QLabel(SquaredPolynomWindow)
self.residualVarianceValueLabel.setObjectName(u"residualVarianceValueLabel")
self.gridLayout_3.addWidget(self.residualVarianceValueLabel, 0, 1, 1, 1)
self.gridLayout.addLayout(self.gridLayout_3, 1, 0, 1, 1)
self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1)
self.retranslateUi(SquaredPolynomWindow)
QMetaObject.connectSlotsByName(SquaredPolynomWindow)
# setupUi
def retranslateUi(self, SquaredPolynomWindow):
SquaredPolynomWindow.setWindowTitle(QCoreApplication.translate("SquaredPolynomWindow", u"\u041a\u0432\u0430\u0434\u0440\u0430\u0442\u0438\u0447\u043d\u044b\u0439 \u043f\u043e\u043b\u0438\u043d\u043e\u043c", None))
self.residualVarianceLabel.setText(QCoreApplication.translate("SquaredPolynomWindow", u"\u041e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u0430\u044f \u0434\u0438\u0441\u043f\u0435\u0440\u0441\u0438\u044f:", None))
self.residualVarianceValueLabel.setText(QCoreApplication.translate("SquaredPolynomWindow", u"undefined", None))
# retranslateUi

View File

@@ -22,7 +22,9 @@ import sys
from PySide2.QtCore import QSize
from PySide2.QtGui import QIcon
from PySide2.QtWidgets import QMessageBox
from PySide2.QtWidgets import QMessageBox, QDoubleSpinBox, QStyledItemDelegate
from statapp.constants import NUMBERS_PRECISION
def resourcePath(relative):
@@ -58,3 +60,19 @@ def buildMessageBox(title, text, icon, buttons, defaultButton):
msgBox.setDefaultButton(defaultButton)
return msgBox
class FloatDelegate(QStyledItemDelegate):
def __init__(self, parent=None):
QStyledItemDelegate.__init__(self, parent=parent)
def createEditor(self, parent, option, index):
editor = QDoubleSpinBox(parent)
editor.setDecimals(NUMBERS_PRECISION)
editor.setMaximum(10**8)
editor.setMinimum(-10**8)
return editor
def displayText(self, value, locale):
# Грязный хак, скорее всего нужно было использовать locale
return f'{value:.{NUMBERS_PRECISION}f}'

View File

@@ -20,10 +20,11 @@
from PySide2.QtWidgets import QDialog, QHeaderView
from statapp.calculations import varianceAnalysis
from statapp.constants import NUMBERS_PRECISION
from statapp.mathtex_header_view import MathTexHeaderView
from statapp.models.variance_analysis_model import VarianceAnalysisModel
from statapp.ui.ui_variance_analysis_window import Ui_VarianceAnalysisWindow
from statapp.utils import addIcon
from statapp.utils import addIcon, FloatDelegate
class VarianceAnalysisWindow(QDialog):
@@ -33,7 +34,8 @@ class VarianceAnalysisWindow(QDialog):
self.ui.setupUi(self)
res = varianceAnalysis(data)
self.model = VarianceAnalysisModel(res.round(2))
self.model = VarianceAnalysisModel(res.round(NUMBERS_PRECISION))
self.ui.tableView.setItemDelegate(FloatDelegate())
self.ui.tableView.setModel(self.model)
self.ui.tableView.setVerticalHeader(
MathTexHeaderView(self.ui.tableView)