36 Commits

Author SHA1 Message Date
github-actions[bot]
1c88acf772 chore(main): release 0.10.0 (#95)
🤖 I have created a release *beep* *boop*
---


## [0.10.0](https://github.com/shizand/statapp/compare/v0.9.0...v0.10.0)
(2024-01-08)


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

* добавлен график ([#94](https://github.com/shizand/statapp/issues/94))
([bb1b2f1](bb1b2f1ec5)),
closes [#86](https://github.com/shizand/statapp/issues/86)

---
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>
2024-01-08 18:57:33 +03:00
bb1b2f1ec5 feat: добавлен график (#94)
Closes #86
2024-01-08 16:09:12 +03:00
github-actions[bot]
7cbb93e37c chore(main): release 0.9.0 (#93)
🤖 I have created a release *beep* *boop*
---


## [0.9.0](https://github.com/shizand/statapp/compare/v0.8.0...v0.9.0)
(2024-01-02)


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

* добавлен "Прогноз"
([#92](https://github.com/shizand/statapp/issues/92))
([8ea3cff](8ea3cffa7e)),
closes [#85](https://github.com/shizand/statapp/issues/85)

---
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>
2024-01-02 17:29:45 +03:00
8ea3cffa7e feat: добавлен "Прогноз" (#92)
Closes #85
2024-01-02 17:22:59 +03:00
github-actions[bot]
51fc413fca chore(main): release 0.8.0 (#91)
🤖 I have created a release *beep* *boop*
---


## [0.8.0](https://github.com/shizand/statapp/compare/v0.7.0...v0.8.0)
(2023-12-31)


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

* добавлены преобразования
([#90](https://github.com/shizand/statapp/issues/90))
([f70be43](f70be431cf))

---
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-31 10:17:56 +03:00
f70be431cf feat: добавлены преобразования (#90)
Closes #41

---------

Co-authored-by: MisterMLiL <eugenelazurenko@gmail.com>
2023-12-31 10:12:01 +03:00
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
github-actions[bot]
9f7181513b chore(main): release 0.6.0 (#80)
🤖 I have created a release *beep* *boop*
---


## [0.6.0](https://github.com/shizand/statapp/compare/v0.5.0...v0.6.0)
(2023-10-20)


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

* добавлен "Квадратичный полином"
([#81](https://github.com/shizand/statapp/issues/81))
([9033770](9033770406))


### Исправления

* исправлен формат сохранения файлов
([#79](https://github.com/shizand/statapp/issues/79))
([044d2b6](044d2b61cf))

---
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-10-20 13:53:26 +03:00
725289ca06 chore: понизил версию Pillow 2023-10-20 13:47:45 +03:00
a6cda1ab3d chore: удалена отладка 2023-10-20 13:47:15 +03:00
9033770406 feat: добавлен "Квадратичный полином" (#81)
Closes #34.
2023-10-20 13:26:49 +03:00
MisterMLiL
044d2b61cf fix: исправлен формат сохранения файлов (#79) 2023-10-13 22:06:24 +03:00
github-actions[bot]
dd765ae981 chore(main): release 0.5.0 (#75)
🤖 I have created a release *beep* *boop*
---


## [0.5.0](https://github.com/shizand/statapp/compare/v0.4.2...v0.5.0)
(2023-10-06)


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

* добавлен "Линейный полином"
([#74](https://github.com/shizand/statapp/issues/74))
([232de9f](232de9f145))


### Исправления

* добавлены переводы для QMessageBox
([#73](https://github.com/shizand/statapp/issues/73))
([e653c3d](e653c3df29))

---
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-10-06 09:51:47 +03:00
bdb346fd17 ci: try fix ci 2023-10-06 09:44:00 +03:00
79297850df ci: try fix ci 2023-10-06 09:23:03 +03:00
232de9f145 feat: добавлен "Линейный полином" (#74) 2023-10-05 21:28:11 +03:00
e653c3df29 fix: добавлены переводы для QMessageBox (#73) 2023-10-05 21:27:51 +03:00
a89d7896e3 refactor: исправлены ВСЕ замечания pylint (#72) 2023-10-04 14:38:42 +03:00
d387a79d6d ci: fix version 2023-10-04 14:29:32 +03:00
dd3ab2e1cf ci: добавляет permissions для labeler 2023-10-04 14:21:58 +03:00
2115490b2c ci: добавляет labeler 2023-10-04 14:20:28 +03:00
d89837e34a chore: заменил codacy badge 2023-10-04 09:04:23 +03:00
af8d9cbdde chore: добавил too-few-public-methods 2023-10-04 09:02:24 +03:00
18157b9e82 chore: переименовал файл pylint 2023-10-04 08:55:13 +03:00
25bc63ee51 chore: добавлен pylint (#71) 2023-10-04 08:42:16 +03:00
fea99f0985 chore: добавлен файл README.md (#69)
Closes #26.

---------

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>
2023-10-03 20:49:35 +03:00
github-actions[bot]
390dbdc087 chore(main): release 0.4.2 (#68)
🤖 I have created a release *beep* *boop*
---


## [0.4.2](https://github.com/shizand/statapp/compare/v0.4.1...v0.4.2)
(2023-10-03)


### Исправления

* добавлены иконки во все окна
([#67](https://github.com/shizand/statapp/issues/67))
([9310a5e](9310a5e622))

---
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-10-03 18:41:46 +03:00
MisterMLiL
9310a5e622 fix: добавлены иконки во все окна (#67)
Closes #65

---------

Co-authored-by: Maxim Slipenko <no-reply@maxim.slipenko.com>
2023-10-03 18:18:32 +03:00
59 changed files with 2511 additions and 259 deletions

2
.gitattributes vendored
View File

@@ -1 +1 @@
statapp/ui/ui_*.py linguist-generated=true
statapp/ui/ui_*.py linguist-generated=true

View File

@@ -13,4 +13,4 @@ jobs:
- uses: actions-ecosystem/action-add-assignees@v1
with:
github_token: ${{ secrets.github_token }}
assignees: ${{ github.actor }}
assignees: ${{ github.actor }}

View File

@@ -18,4 +18,4 @@ jobs:
- uses: pixta-dev/repository-mirroring-action@674e65a7d483ca28dafaacba0d07351bdcc8bd75 # v1.1.1
with:
target_repo_url: "git@gitflic.ru:shizand/statapp.git"
ssh_private_key: ${{ secrets.GITFLIC_SSH }}
ssh_private_key: ${{ secrets.GITFLIC_SSH }}

View File

@@ -47,7 +47,7 @@ jobs:
- name: Установка зависимостей
run: poetry install
- name: Сборка
run: poetry run pyinstaller ${{ matrix.spec }}.spec\
run: poetry run pyinstaller statapp.spec -- -- ${{ matrix.spec == 'statapp-onefile' && '--one-file' || '' }}
- name: Архивация
uses: thedoctor0/zip-release@0.7.1
with:

31
.github/workflows/size-labeler.yml vendored Normal file
View File

@@ -0,0 +1,31 @@
name: labeler
on: [pull_request]
jobs:
labeler:
runs-on: ubuntu-latest
name: Label the PR size
permissions:
issues: write
pull-requests: write
steps:
- uses: codelytv/pr-size-labeler@v1.7.0
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
xs_label: 'size/xs'
xs_max_size: '10'
s_label: 'size/s'
s_max_size: '100'
m_label: 'size/m'
m_max_size: '500'
l_label: 'size/l'
l_max_size: '1000'
xl_label: 'size/xl'
fail_if_xl: 'false'
message_if_xl: >
Этот PR превышает рекомендуемый размер в 1000 строк.
Пожалуйста, убедитесь, что вы НЕ решаете несколько проблем с помощью одного PR.
github_api_url: 'api.github.com'
files_to_ignore: |
"ui_*.py"

View File

@@ -11,4 +11,4 @@
</option>
</inspection_tool>
</profile>
</component>
</component>

View File

@@ -3,4 +3,4 @@
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>
</component>

7
.idea/misc.xml generated
View File

@@ -1,4 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Poetry (statapp)" project-jdk-type="Python SDK" />
</project>
<component name="Black">
<option name="sdkName" value="Poetry (statapp)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="statapp" project-jdk-type="Python SDK" />
</project>

2
.idea/modules.xml generated
View File

@@ -5,4 +5,4 @@
<module fileurl="file://$PROJECT_DIR$/.idea/stat.iml" filepath="$PROJECT_DIR$/.idea/stat.iml" />
</modules>
</component>
</project>
</project>

View File

@@ -1,15 +1,15 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="statapp" type="PythonConfigurationType" factoryName="Python" nameIsGenerated="true">
<module name="stat" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="SDK_NAME" value="Poetry (statapp)" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="statapp" />

4
.idea/stat.iml generated
View File

@@ -2,7 +2,7 @@
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Poetry (statapp)" jdkType="Python SDK" />
<orderEntry type="jdk" jdkName="statapp" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
</module>

View File

@@ -1,5 +1,9 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
ci:
autofix_commit_msg: 'chore: [pre-commit.ci] auto fixes from pre-commit.com hooks'
autoupdate_commit_msg: 'chore: [pre-commit.ci] pre-commit autoupdate'
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0
@@ -12,5 +16,18 @@ repos:
rev: v0.8.8
hooks:
- id: licenseheaders
args: ["-t", ".copyright.tmpl", "-cy", "-f", "-d", "statapp"]
args: ["-t", ".copyright.tmpl", "-cy", "-f", "-d", "statapp", "-x", "statapp/_vendor/*.py"]
pass_filenames: false
- repo: local
hooks:
- id: pylint
name: pylint
entry: pylint
language: system
types: [python]
args:
[
"-rn", # Only display messages
"-sn", # Don't display the score
"--rcfile=.pylintrc",
]

27
.pylintrc Normal file
View File

@@ -0,0 +1,27 @@
[MAIN]
ignored-modules=PySide2
extension-pkg-whitelist=PySide2
[MASTER]
init-hook="import sys; sys.path.append('./statapp')"
ignore-patterns=ui_.+\.py
[BASIC]
attr-rgx=^_?[a-z][a-zA-Z0-9]+$|^_?[a-z0-9]+$|^_?[a-z0-9]+(_[a-z0-9]+)*$ # camelCase, lowercase, snake_case
class-attribute-rgx=^_?[a-z][a-zA-Z0-9]+$|^_?[a-z0-9]+$|^_?[a-z0-9]+(_[a-z0-9]+)*$ # camelCase, lowercase
variable-rgx=^_?[a-z][a-zA-Z0-9]+$|^_?[a-z0-9]+$ # camelCase, lowercase
argument-rgx=^_?[a-z][a-zA-Z0-9]+$|^_?[a-z0-9]+$ # camelCase, lowercase
function-rgx=^_?[a-z][a-zA-Z0-9]+$ # camelCase
method-rgx=^_?[a-z][a-zA-Z0-9]+$|^_?on_[a-z][a-zA-Z]+_[a-z][a-zA-Z]+|^__init__$ # camelCase, on_camelCaseWidget_camelCaseSignal and __init__
[SIMILARITIES]
min-similarity-lines=8
[MESSAGES CONTROL]
disable=
unused-argument,
fixme,
missing-docstring,
too-many-public-methods,
too-few-public-methods,
too-many-arguments

View File

@@ -1,5 +1,65 @@
# Changelog
## [0.10.0](https://github.com/shizand/statapp/compare/v0.9.0...v0.10.0) (2024-01-08)
### Новые функции
* добавлен график ([#94](https://github.com/shizand/statapp/issues/94)) ([bb1b2f1](https://github.com/shizand/statapp/commit/bb1b2f1ec5b988bcb8ddd7500b95fe9e35c826f5)), closes [#86](https://github.com/shizand/statapp/issues/86)
## [0.9.0](https://github.com/shizand/statapp/compare/v0.8.0...v0.9.0) (2024-01-02)
### Новые функции
* добавлен "Прогноз" ([#92](https://github.com/shizand/statapp/issues/92)) ([8ea3cff](https://github.com/shizand/statapp/commit/8ea3cffa7e0d920141c8eda71952ff02d2c02905)), closes [#85](https://github.com/shizand/statapp/issues/85)
## [0.8.0](https://github.com/shizand/statapp/compare/v0.7.0...v0.8.0) (2023-12-31)
### Новые функции
* добавлены преобразования ([#90](https://github.com/shizand/statapp/issues/90)) ([f70be43](https://github.com/shizand/statapp/commit/f70be431cfb4ecda5c3e706f4ca95171bbe779b3))
## [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)
### Новые функции
* добавлен "Квадратичный полином" ([#81](https://github.com/shizand/statapp/issues/81)) ([9033770](https://github.com/shizand/statapp/commit/9033770406a6163bee794be80da9d5eebf0fcb87))
### Исправления
* исправлен формат сохранения файлов ([#79](https://github.com/shizand/statapp/issues/79)) ([044d2b6](https://github.com/shizand/statapp/commit/044d2b61cf068065a0fa0f33c8b0be94753eb84b))
## [0.5.0](https://github.com/shizand/statapp/compare/v0.4.2...v0.5.0) (2023-10-06)
### Новые функции
* добавлен "Линейный полином" ([#74](https://github.com/shizand/statapp/issues/74)) ([232de9f](https://github.com/shizand/statapp/commit/232de9f145862a1a1e493478ba5fe8a6e4866e5a))
### Исправления
* добавлены переводы для QMessageBox ([#73](https://github.com/shizand/statapp/issues/73)) ([e653c3d](https://github.com/shizand/statapp/commit/e653c3df29355e84f5845d428d2265b902f5abeb))
## [0.4.2](https://github.com/shizand/statapp/compare/v0.4.1...v0.4.2) (2023-10-03)
### Исправления
* добавлены иконки во все окна ([#67](https://github.com/shizand/statapp/issues/67)) ([9310a5e](https://github.com/shizand/statapp/commit/9310a5e6226bfaff4a7fe4fb9395d5cd1553fee9))
## [0.4.1](https://github.com/shizand/statapp/compare/v0.4.0...v0.4.1) (2023-10-03)

View File

@@ -1 +1 @@
* @Maks1mS @MisterMLiL
* @Maks1mS @MisterMLiL

View File

@@ -0,0 +1,60 @@
# Statapp
![Release info](https://img.shields.io/github/v/release/shizand/statapp)
![Python version](https://img.shields.io/badge/python-3.8-blue.svg)
[![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).
Разработано двумя студентами ФГБОУ ВО «ДонНТУ» для своего университета.
## Поддерживаемые ОС и архитектуры
В теории, должно работать на любой архитектуре и ОС, где запускается Python 3.8 и есть Qt 5.
Работоспособность проверена на x64:
* на Windows 7, 10;
* на ALT Linux 10.2.
## Установка
Программа распространяется с помощью [PyInstaller](https://pyinstaller.org/en/stable/).
Существует две версиии: **statapp** и **statapp-onefile**.
Различия в том, что onefile версия поставляется одним единственным бинарным файлом. На Windows системах с включенным антивирусом это может вызывать [некоторые проблемы](https://qna.habr.com/q/988553).
### Готовые двоичные файлы
[Скачайте архив](https://github.com/shizand/statapp/releases) под вашу платформу и распакуйте в любом месте.
### Сборка из исходников
В этом проекте используется [poetry](https://python-poetry.org/).
```bash
poetry install
pyinstaller statapp.spec # или pyinstaller statapp.spec -- --one-file
```
## Использование
<!-- TODO -->
## Чем я могу помочь проекту?
* [Сообщить об ошибке](https://github.com/shizand/statapp/issues/new?labels=%D0%B1%D0%B0%D0%B3)
## Исходный код
Исходный код доступен на [GitHub](https://github.com/shizand/statapp).
Также есть зеркала:
* [GitFic](https://gitflic.ru/project/shizand/statapp);
* [Gitea сервер](https://git.slipenko.com/shizand/statapp).
## Лицензия
[GPL-3.0 © Maxim Slipenko, Eugene Lazurenko.](https://github.com/shizand/statapp/blob/main/LICENSE)

812
poetry.lock generated
View File

@@ -11,6 +11,22 @@ files = [
{file = "altgraph-0.17.4.tar.gz", hash = "sha256:1b5afbb98f6c4dcadb2e2ae6ab9fa994bbb8c1d75f4fa96d340f9437ae454406"},
]
[[package]]
name = "astroid"
version = "2.15.8"
description = "An abstract syntax tree for Python with inference support."
optional = false
python-versions = ">=3.7.2"
files = [
{file = "astroid-2.15.8-py3-none-any.whl", hash = "sha256:1aa149fc5c6589e3d0ece885b4491acd80af4f087baafa3fb5203b113e68cd3c"},
{file = "astroid-2.15.8.tar.gz", hash = "sha256:6c107453dffee9055899705de3c9ead36e74119cee151e5a9aaf7f0b0e020a6a"},
]
[package.dependencies]
lazy-object-proxy = ">=1.4.0"
typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""}
wrapt = {version = ">=1.11,<2", markers = "python_version < \"3.11\""}
[[package]]
name = "cfgv"
version = "3.4.0"
@@ -22,6 +38,117 @@ files = [
{file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"},
]
[[package]]
name = "colorama"
version = "0.4.6"
description = "Cross-platform colored terminal text."
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
files = [
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
]
[[package]]
name = "contourpy"
version = "1.1.1"
description = "Python library for calculating contours of 2D quadrilateral grids"
optional = false
python-versions = ">=3.8"
files = [
{file = "contourpy-1.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:46e24f5412c948d81736509377e255f6040e94216bf1a9b5ea1eaa9d29f6ec1b"},
{file = "contourpy-1.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e48694d6a9c5a26ee85b10130c77a011a4fedf50a7279fa0bdaf44bafb4299d"},
{file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a66045af6cf00e19d02191ab578a50cb93b2028c3eefed999793698e9ea768ae"},
{file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ebf42695f75ee1a952f98ce9775c873e4971732a87334b099dde90b6af6a916"},
{file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6aec19457617ef468ff091669cca01fa7ea557b12b59a7908b9474bb9674cf0"},
{file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:462c59914dc6d81e0b11f37e560b8a7c2dbab6aca4f38be31519d442d6cde1a1"},
{file = "contourpy-1.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6d0a8efc258659edc5299f9ef32d8d81de8b53b45d67bf4bfa3067f31366764d"},
{file = "contourpy-1.1.1-cp310-cp310-win32.whl", hash = "sha256:d6ab42f223e58b7dac1bb0af32194a7b9311065583cc75ff59dcf301afd8a431"},
{file = "contourpy-1.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:549174b0713d49871c6dee90a4b499d3f12f5e5f69641cd23c50a4542e2ca1eb"},
{file = "contourpy-1.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:407d864db716a067cc696d61fa1ef6637fedf03606e8417fe2aeed20a061e6b2"},
{file = "contourpy-1.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe80c017973e6a4c367e037cb31601044dd55e6bfacd57370674867d15a899b"},
{file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e30aaf2b8a2bac57eb7e1650df1b3a4130e8d0c66fc2f861039d507a11760e1b"},
{file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3de23ca4f381c3770dee6d10ead6fff524d540c0f662e763ad1530bde5112532"},
{file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:566f0e41df06dfef2431defcfaa155f0acfa1ca4acbf8fd80895b1e7e2ada40e"},
{file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b04c2f0adaf255bf756cf08ebef1be132d3c7a06fe6f9877d55640c5e60c72c5"},
{file = "contourpy-1.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d0c188ae66b772d9d61d43c6030500344c13e3f73a00d1dc241da896f379bb62"},
{file = "contourpy-1.1.1-cp311-cp311-win32.whl", hash = "sha256:0683e1ae20dc038075d92e0e0148f09ffcefab120e57f6b4c9c0f477ec171f33"},
{file = "contourpy-1.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:8636cd2fc5da0fb102a2504fa2c4bea3cbc149533b345d72cdf0e7a924decc45"},
{file = "contourpy-1.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:560f1d68a33e89c62da5da4077ba98137a5e4d3a271b29f2f195d0fba2adcb6a"},
{file = "contourpy-1.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24216552104ae8f3b34120ef84825400b16eb6133af2e27a190fdc13529f023e"},
{file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56de98a2fb23025882a18b60c7f0ea2d2d70bbbcfcf878f9067234b1c4818442"},
{file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:07d6f11dfaf80a84c97f1a5ba50d129d9303c5b4206f776e94037332e298dda8"},
{file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1eaac5257a8f8a047248d60e8f9315c6cff58f7803971170d952555ef6344a7"},
{file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19557fa407e70f20bfaba7d55b4d97b14f9480856c4fb65812e8a05fe1c6f9bf"},
{file = "contourpy-1.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:081f3c0880712e40effc5f4c3b08feca6d064cb8cfbb372ca548105b86fd6c3d"},
{file = "contourpy-1.1.1-cp312-cp312-win32.whl", hash = "sha256:059c3d2a94b930f4dafe8105bcdc1b21de99b30b51b5bce74c753686de858cb6"},
{file = "contourpy-1.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:f44d78b61740e4e8c71db1cf1fd56d9050a4747681c59ec1094750a658ceb970"},
{file = "contourpy-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:70e5a10f8093d228bb2b552beeb318b8928b8a94763ef03b858ef3612b29395d"},
{file = "contourpy-1.1.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8394e652925a18ef0091115e3cc191fef350ab6dc3cc417f06da66bf98071ae9"},
{file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bd5680f844c3ff0008523a71949a3ff5e4953eb7701b28760805bc9bcff217"},
{file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:66544f853bfa85c0d07a68f6c648b2ec81dafd30f272565c37ab47a33b220684"},
{file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0c02b75acfea5cab07585d25069207e478d12309557f90a61b5a3b4f77f46ce"},
{file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41339b24471c58dc1499e56783fedc1afa4bb018bcd035cfb0ee2ad2a7501ef8"},
{file = "contourpy-1.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f29fb0b3f1217dfe9362ec55440d0743fe868497359f2cf93293f4b2701b8251"},
{file = "contourpy-1.1.1-cp38-cp38-win32.whl", hash = "sha256:f9dc7f933975367251c1b34da882c4f0e0b2e24bb35dc906d2f598a40b72bfc7"},
{file = "contourpy-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:498e53573e8b94b1caeb9e62d7c2d053c263ebb6aa259c81050766beb50ff8d9"},
{file = "contourpy-1.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ba42e3810999a0ddd0439e6e5dbf6d034055cdc72b7c5c839f37a7c274cb4eba"},
{file = "contourpy-1.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6c06e4c6e234fcc65435223c7b2a90f286b7f1b2733058bdf1345d218cc59e34"},
{file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca6fab080484e419528e98624fb5c4282148b847e3602dc8dbe0cb0669469887"},
{file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:93df44ab351119d14cd1e6b52a5063d3336f0754b72736cc63db59307dabb718"},
{file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eafbef886566dc1047d7b3d4b14db0d5b7deb99638d8e1be4e23a7c7ac59ff0f"},
{file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efe0fab26d598e1ec07d72cf03eaeeba8e42b4ecf6b9ccb5a356fde60ff08b85"},
{file = "contourpy-1.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f08e469821a5e4751c97fcd34bcb586bc243c39c2e39321822060ba902eac49e"},
{file = "contourpy-1.1.1-cp39-cp39-win32.whl", hash = "sha256:bfc8a5e9238232a45ebc5cb3bfee71f1167064c8d382cadd6076f0d51cff1da0"},
{file = "contourpy-1.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:c84fdf3da00c2827d634de4fcf17e3e067490c4aea82833625c4c8e6cdea0887"},
{file = "contourpy-1.1.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:229a25f68046c5cf8067d6d6351c8b99e40da11b04d8416bf8d2b1d75922521e"},
{file = "contourpy-1.1.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a10dab5ea1bd4401c9483450b5b0ba5416be799bbd50fc7a6cc5e2a15e03e8a3"},
{file = "contourpy-1.1.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:4f9147051cb8fdb29a51dc2482d792b3b23e50f8f57e3720ca2e3d438b7adf23"},
{file = "contourpy-1.1.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a75cc163a5f4531a256f2c523bd80db509a49fc23721b36dd1ef2f60ff41c3cb"},
{file = "contourpy-1.1.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b53d5769aa1f2d4ea407c65f2d1d08002952fac1d9e9d307aa2e1023554a163"},
{file = "contourpy-1.1.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:11b836b7dbfb74e049c302bbf74b4b8f6cb9d0b6ca1bf86cfa8ba144aedadd9c"},
{file = "contourpy-1.1.1.tar.gz", hash = "sha256:96ba37c2e24b7212a77da85004c38e7c4d155d3e72a45eeaf22c1f03f607e8ab"},
]
[package.dependencies]
numpy = {version = ">=1.16,<2.0", markers = "python_version <= \"3.11\""}
[package.extras]
bokeh = ["bokeh", "selenium"]
docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"]
mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.4.1)", "types-Pillow"]
test = ["Pillow", "contourpy[test-no-images]", "matplotlib"]
test-no-images = ["pytest", "pytest-cov", "wurlitzer"]
[[package]]
name = "cycler"
version = "0.12.1"
description = "Composable style cycles"
optional = false
python-versions = ">=3.8"
files = [
{file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"},
{file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"},
]
[package.extras]
docs = ["ipython", "matplotlib", "numpydoc", "sphinx"]
tests = ["pytest", "pytest-cov", "pytest-xdist"]
[[package]]
name = "dill"
version = "0.3.7"
description = "serialize all of Python"
optional = false
python-versions = ">=3.7"
files = [
{file = "dill-0.3.7-py3-none-any.whl", hash = "sha256:76b122c08ef4ce2eedcd4d1abd8e641114bfc6c2867f49f3c41facf65bf19f5e"},
{file = "dill-0.3.7.tar.gz", hash = "sha256:cc1c8b182eb3013e24bd475ff2e9295af86c1a38eb1aff128dac8962a9ce3c03"},
]
[package.extras]
graph = ["objgraph (>=1.7.2)"]
[[package]]
name = "distlib"
version = "0.3.7"
@@ -49,15 +176,80 @@ docs = ["furo (>=2023.7.26)", "sphinx (>=7.1.2)", "sphinx-autodoc-typehints (>=1
testing = ["covdefaults (>=2.3)", "coverage (>=7.3)", "diff-cover (>=7.7)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)", "pytest-timeout (>=2.1)"]
typing = ["typing-extensions (>=4.7.1)"]
[[package]]
name = "fonttools"
version = "4.43.1"
description = "Tools to manipulate font files"
optional = false
python-versions = ">=3.8"
files = [
{file = "fonttools-4.43.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:bf11e2cca121df35e295bd34b309046c29476ee739753bc6bc9d5050de319273"},
{file = "fonttools-4.43.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:10b3922875ffcba636674f406f9ab9a559564fdbaa253d66222019d569db869c"},
{file = "fonttools-4.43.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f727c3e3d08fd25352ed76cc3cb61486f8ed3f46109edf39e5a60fc9fecf6ca"},
{file = "fonttools-4.43.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad0b3f6342cfa14be996971ea2b28b125ad681c6277c4cd0fbdb50340220dfb6"},
{file = "fonttools-4.43.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3b7ad05b2beeebafb86aa01982e9768d61c2232f16470f9d0d8e385798e37184"},
{file = "fonttools-4.43.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4c54466f642d2116686268c3e5f35ebb10e49b0d48d41a847f0e171c785f7ac7"},
{file = "fonttools-4.43.1-cp310-cp310-win32.whl", hash = "sha256:1e09da7e8519e336239fbd375156488a4c4945f11c4c5792ee086dd84f784d02"},
{file = "fonttools-4.43.1-cp310-cp310-win_amd64.whl", hash = "sha256:1cf9e974f63b1080b1d2686180fc1fbfd3bfcfa3e1128695b5de337eb9075cef"},
{file = "fonttools-4.43.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5db46659cfe4e321158de74c6f71617e65dc92e54980086823a207f1c1c0e24b"},
{file = "fonttools-4.43.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1952c89a45caceedf2ab2506d9a95756e12b235c7182a7a0fff4f5e52227204f"},
{file = "fonttools-4.43.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c36da88422e0270fbc7fd959dc9749d31a958506c1d000e16703c2fce43e3d0"},
{file = "fonttools-4.43.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bbbf8174501285049e64d174e29f9578495e1b3b16c07c31910d55ad57683d8"},
{file = "fonttools-4.43.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d4071bd1c183b8d0b368cc9ed3c07a0f6eb1bdfc4941c4c024c49a35429ac7cd"},
{file = "fonttools-4.43.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d21099b411e2006d3c3e1f9aaf339e12037dbf7bf9337faf0e93ec915991f43b"},
{file = "fonttools-4.43.1-cp311-cp311-win32.whl", hash = "sha256:b84a1c00f832feb9d0585ca8432fba104c819e42ff685fcce83537e2e7e91204"},
{file = "fonttools-4.43.1-cp311-cp311-win_amd64.whl", hash = "sha256:9a2f0aa6ca7c9bc1058a9d0b35483d4216e0c1bbe3962bc62ce112749954c7b8"},
{file = "fonttools-4.43.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:4d9740e3783c748521e77d3c397dc0662062c88fd93600a3c2087d3d627cd5e5"},
{file = "fonttools-4.43.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:884ef38a5a2fd47b0c1291647b15f4e88b9de5338ffa24ee52c77d52b4dfd09c"},
{file = "fonttools-4.43.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9648518ef687ba818db3fcc5d9aae27a369253ac09a81ed25c3867e8657a0680"},
{file = "fonttools-4.43.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95e974d70238fc2be5f444fa91f6347191d0e914d5d8ae002c9aa189572cc215"},
{file = "fonttools-4.43.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:34f713dad41aa21c637b4e04fe507c36b986a40f7179dcc86402237e2d39dcd3"},
{file = "fonttools-4.43.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:360201d46165fc0753229afe785900bc9596ee6974833124f4e5e9f98d0f592b"},
{file = "fonttools-4.43.1-cp312-cp312-win32.whl", hash = "sha256:bb6d2f8ef81ea076877d76acfb6f9534a9c5f31dc94ba70ad001267ac3a8e56f"},
{file = "fonttools-4.43.1-cp312-cp312-win_amd64.whl", hash = "sha256:25d3da8a01442cbc1106490eddb6d31d7dffb38c1edbfabbcc8db371b3386d72"},
{file = "fonttools-4.43.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8da417431bfc9885a505e86ba706f03f598c85f5a9c54f67d63e84b9948ce590"},
{file = "fonttools-4.43.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:51669b60ee2a4ad6c7fc17539a43ffffc8ef69fd5dbed186a38a79c0ac1f5db7"},
{file = "fonttools-4.43.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:748015d6f28f704e7d95cd3c808b483c5fb87fd3eefe172a9da54746ad56bfb6"},
{file = "fonttools-4.43.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7a58eb5e736d7cf198eee94844b81c9573102ae5989ebcaa1d1a37acd04b33d"},
{file = "fonttools-4.43.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6bb5ea9076e0e39defa2c325fc086593ae582088e91c0746bee7a5a197be3da0"},
{file = "fonttools-4.43.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5f37e31291bf99a63328668bb83b0669f2688f329c4c0d80643acee6e63cd933"},
{file = "fonttools-4.43.1-cp38-cp38-win32.whl", hash = "sha256:9c60ecfa62839f7184f741d0509b5c039d391c3aff71dc5bc57b87cc305cff3b"},
{file = "fonttools-4.43.1-cp38-cp38-win_amd64.whl", hash = "sha256:fe9b1ec799b6086460a7480e0f55c447b1aca0a4eecc53e444f639e967348896"},
{file = "fonttools-4.43.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:13a9a185259ed144def3682f74fdcf6596f2294e56fe62dfd2be736674500dba"},
{file = "fonttools-4.43.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2adca1b46d69dce4a37eecc096fe01a65d81a2f5c13b25ad54d5430ae430b13"},
{file = "fonttools-4.43.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18eefac1b247049a3a44bcd6e8c8fd8b97f3cad6f728173b5d81dced12d6c477"},
{file = "fonttools-4.43.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2062542a7565091cea4cc14dd99feff473268b5b8afdee564f7067dd9fff5860"},
{file = "fonttools-4.43.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:18a2477c62a728f4d6e88c45ee9ee0229405e7267d7d79ce1f5ce0f3e9f8ab86"},
{file = "fonttools-4.43.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a7a06f8d95b7496e53af80d974d63516ffb263a468e614978f3899a6df52d4b3"},
{file = "fonttools-4.43.1-cp39-cp39-win32.whl", hash = "sha256:10003ebd81fec0192c889e63a9c8c63f88c7d72ae0460b7ba0cd2a1db246e5ad"},
{file = "fonttools-4.43.1-cp39-cp39-win_amd64.whl", hash = "sha256:e117a92b07407a061cde48158c03587ab97e74e7d73cb65e6aadb17af191162a"},
{file = "fonttools-4.43.1-py3-none-any.whl", hash = "sha256:4f88cae635bfe4bbbdc29d479a297bb525a94889184bb69fa9560c2d4834ddb9"},
{file = "fonttools-4.43.1.tar.gz", hash = "sha256:17dbc2eeafb38d5d0e865dcce16e313c58265a6d2d20081c435f84dc5a9d8212"},
]
[package.extras]
all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0,<5)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.0.0)", "xattr", "zopfli (>=0.1.4)"]
graphite = ["lz4 (>=1.7.4.2)"]
interpolatable = ["munkres", "scipy"]
lxml = ["lxml (>=4.0,<5)"]
pathops = ["skia-pathops (>=0.5.0)"]
plot = ["matplotlib"]
repacker = ["uharfbuzz (>=0.23.0)"]
symfont = ["sympy"]
type1 = ["xattr"]
ufo = ["fs (>=2.2.0,<3)"]
unicode = ["unicodedata2 (>=15.0.0)"]
woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"]
[[package]]
name = "identify"
version = "2.5.29"
version = "2.5.30"
description = "File identification library for Python"
optional = false
python-versions = ">=3.8"
files = [
{file = "identify-2.5.29-py2.py3-none-any.whl", hash = "sha256:24437fbf6f4d3fe6efd0eb9d67e24dd9106db99af5ceb27996a5f7895f24bf1b"},
{file = "identify-2.5.29.tar.gz", hash = "sha256:d43d52b86b15918c137e3a74fff5224f60385cd0e9c38e99d07c257f02f151a5"},
{file = "identify-2.5.30-py2.py3-none-any.whl", hash = "sha256:afe67f26ae29bab007ec21b03d4114f41316ab9dd15aa8736a167481e108da54"},
{file = "identify-2.5.30.tar.gz", hash = "sha256:f302a4256a15c849b91cfcdcec052a8ce914634b2f77ae87dad29cd749f2d88d"},
]
[package.extras]
@@ -82,6 +274,199 @@ docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker
perf = ["ipython"]
testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"]
[[package]]
name = "importlib-resources"
version = "6.1.0"
description = "Read resources from Python packages"
optional = false
python-versions = ">=3.8"
files = [
{file = "importlib_resources-6.1.0-py3-none-any.whl", hash = "sha256:aa50258bbfa56d4e33fbd8aa3ef48ded10d1735f11532b8df95388cc6bdb7e83"},
{file = "importlib_resources-6.1.0.tar.gz", hash = "sha256:9d48dcccc213325e810fd723e7fbb45ccb39f6cf5c31f00cf2b965f5f10f3cb9"},
]
[package.dependencies]
zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""}
[package.extras]
docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"]
testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff", "zipp (>=3.17)"]
[[package]]
name = "isort"
version = "5.12.0"
description = "A Python utility / library to sort Python imports."
optional = false
python-versions = ">=3.8.0"
files = [
{file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"},
{file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"},
]
[package.extras]
colors = ["colorama (>=0.4.3)"]
pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"]
plugins = ["setuptools"]
requirements-deprecated-finder = ["pip-api", "pipreqs"]
[[package]]
name = "kiwisolver"
version = "1.4.5"
description = "A fast implementation of the Cassowary constraint solver"
optional = false
python-versions = ">=3.7"
files = [
{file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:05703cf211d585109fcd72207a31bb170a0f22144d68298dc5e61b3c946518af"},
{file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:146d14bebb7f1dc4d5fbf74f8a6cb15ac42baadee8912eb84ac0b3b2a3dc6ac3"},
{file = "kiwisolver-1.4.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ef7afcd2d281494c0a9101d5c571970708ad911d028137cd558f02b851c08b4"},
{file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9eaa8b117dc8337728e834b9c6e2611f10c79e38f65157c4c38e9400286f5cb1"},
{file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ec20916e7b4cbfb1f12380e46486ec4bcbaa91a9c448b97023fde0d5bbf9e4ff"},
{file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39b42c68602539407884cf70d6a480a469b93b81b7701378ba5e2328660c847a"},
{file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa12042de0171fad672b6c59df69106d20d5596e4f87b5e8f76df757a7c399aa"},
{file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a40773c71d7ccdd3798f6489aaac9eee213d566850a9533f8d26332d626b82c"},
{file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:19df6e621f6d8b4b9c4d45f40a66839294ff2bb235e64d2178f7522d9170ac5b"},
{file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:83d78376d0d4fd884e2c114d0621624b73d2aba4e2788182d286309ebdeed770"},
{file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e391b1f0a8a5a10ab3b9bb6afcfd74f2175f24f8975fb87ecae700d1503cdee0"},
{file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:852542f9481f4a62dbb5dd99e8ab7aedfeb8fb6342349a181d4036877410f525"},
{file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59edc41b24031bc25108e210c0def6f6c2191210492a972d585a06ff246bb79b"},
{file = "kiwisolver-1.4.5-cp310-cp310-win32.whl", hash = "sha256:a6aa6315319a052b4ee378aa171959c898a6183f15c1e541821c5c59beaa0238"},
{file = "kiwisolver-1.4.5-cp310-cp310-win_amd64.whl", hash = "sha256:d0ef46024e6a3d79c01ff13801cb19d0cad7fd859b15037aec74315540acc276"},
{file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:11863aa14a51fd6ec28688d76f1735f8f69ab1fabf388851a595d0721af042f5"},
{file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8ab3919a9997ab7ef2fbbed0cc99bb28d3c13e6d4b1ad36e97e482558a91be90"},
{file = "kiwisolver-1.4.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fcc700eadbbccbf6bc1bcb9dbe0786b4b1cb91ca0dcda336eef5c2beed37b797"},
{file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfdd7c0b105af050eb3d64997809dc21da247cf44e63dc73ff0fd20b96be55a9"},
{file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76c6a5964640638cdeaa0c359382e5703e9293030fe730018ca06bc2010c4437"},
{file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbea0db94288e29afcc4c28afbf3a7ccaf2d7e027489c449cf7e8f83c6346eb9"},
{file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ceec1a6bc6cab1d6ff5d06592a91a692f90ec7505d6463a88a52cc0eb58545da"},
{file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:040c1aebeda72197ef477a906782b5ab0d387642e93bda547336b8957c61022e"},
{file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f91de7223d4c7b793867797bacd1ee53bfe7359bd70d27b7b58a04efbb9436c8"},
{file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:faae4860798c31530dd184046a900e652c95513796ef51a12bc086710c2eec4d"},
{file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b0157420efcb803e71d1b28e2c287518b8808b7cf1ab8af36718fd0a2c453eb0"},
{file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:06f54715b7737c2fecdbf140d1afb11a33d59508a47bf11bb38ecf21dc9ab79f"},
{file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fdb7adb641a0d13bdcd4ef48e062363d8a9ad4a182ac7647ec88f695e719ae9f"},
{file = "kiwisolver-1.4.5-cp311-cp311-win32.whl", hash = "sha256:bb86433b1cfe686da83ce32a9d3a8dd308e85c76b60896d58f082136f10bffac"},
{file = "kiwisolver-1.4.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c08e1312a9cf1074d17b17728d3dfce2a5125b2d791527f33ffbe805200a355"},
{file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:32d5cf40c4f7c7b3ca500f8985eb3fb3a7dfc023215e876f207956b5ea26632a"},
{file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f846c260f483d1fd217fe5ed7c173fb109efa6b1fc8381c8b7552c5781756192"},
{file = "kiwisolver-1.4.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5ff5cf3571589b6d13bfbfd6bcd7a3f659e42f96b5fd1c4830c4cf21d4f5ef45"},
{file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7269d9e5f1084a653d575c7ec012ff57f0c042258bf5db0954bf551c158466e7"},
{file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da802a19d6e15dffe4b0c24b38b3af68e6c1a68e6e1d8f30148c83864f3881db"},
{file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3aba7311af82e335dd1e36ffff68aaca609ca6290c2cb6d821a39aa075d8e3ff"},
{file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:763773d53f07244148ccac5b084da5adb90bfaee39c197554f01b286cf869228"},
{file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2270953c0d8cdab5d422bee7d2007f043473f9d2999631c86a223c9db56cbd16"},
{file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d099e745a512f7e3bbe7249ca835f4d357c586d78d79ae8f1dcd4d8adeb9bda9"},
{file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:74db36e14a7d1ce0986fa104f7d5637aea5c82ca6326ed0ec5694280942d1162"},
{file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e5bab140c309cb3a6ce373a9e71eb7e4873c70c2dda01df6820474f9889d6d4"},
{file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0f114aa76dc1b8f636d077979c0ac22e7cd8f3493abbab152f20eb8d3cda71f3"},
{file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:88a2df29d4724b9237fc0c6eaf2a1adae0cdc0b3e9f4d8e7dc54b16812d2d81a"},
{file = "kiwisolver-1.4.5-cp312-cp312-win32.whl", hash = "sha256:72d40b33e834371fd330fb1472ca19d9b8327acb79a5821d4008391db8e29f20"},
{file = "kiwisolver-1.4.5-cp312-cp312-win_amd64.whl", hash = "sha256:2c5674c4e74d939b9d91dda0fae10597ac7521768fec9e399c70a1f27e2ea2d9"},
{file = "kiwisolver-1.4.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3a2b053a0ab7a3960c98725cfb0bf5b48ba82f64ec95fe06f1d06c99b552e130"},
{file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cd32d6c13807e5c66a7cbb79f90b553642f296ae4518a60d8d76243b0ad2898"},
{file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59ec7b7c7e1a61061850d53aaf8e93db63dce0c936db1fda2658b70e4a1be709"},
{file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da4cfb373035def307905d05041c1d06d8936452fe89d464743ae7fb8371078b"},
{file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2400873bccc260b6ae184b2b8a4fec0e4082d30648eadb7c3d9a13405d861e89"},
{file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1b04139c4236a0f3aff534479b58f6f849a8b351e1314826c2d230849ed48985"},
{file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:4e66e81a5779b65ac21764c295087de82235597a2293d18d943f8e9e32746265"},
{file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7931d8f1f67c4be9ba1dd9c451fb0eeca1a25b89e4d3f89e828fe12a519b782a"},
{file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:b3f7e75f3015df442238cca659f8baa5f42ce2a8582727981cbfa15fee0ee205"},
{file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:bbf1d63eef84b2e8c89011b7f2235b1e0bf7dacc11cac9431fc6468e99ac77fb"},
{file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4c380469bd3f970ef677bf2bcba2b6b0b4d5c75e7a020fb863ef75084efad66f"},
{file = "kiwisolver-1.4.5-cp37-cp37m-win32.whl", hash = "sha256:9408acf3270c4b6baad483865191e3e582b638b1654a007c62e3efe96f09a9a3"},
{file = "kiwisolver-1.4.5-cp37-cp37m-win_amd64.whl", hash = "sha256:5b94529f9b2591b7af5f3e0e730a4e0a41ea174af35a4fd067775f9bdfeee01a"},
{file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:11c7de8f692fc99816e8ac50d1d1aef4f75126eefc33ac79aac02c099fd3db71"},
{file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:53abb58632235cd154176ced1ae8f0d29a6657aa1aa9decf50b899b755bc2b93"},
{file = "kiwisolver-1.4.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:88b9f257ca61b838b6f8094a62418421f87ac2a1069f7e896c36a7d86b5d4c29"},
{file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3195782b26fc03aa9c6913d5bad5aeb864bdc372924c093b0f1cebad603dd712"},
{file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc579bf0f502e54926519451b920e875f433aceb4624a3646b3252b5caa9e0b6"},
{file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a580c91d686376f0f7c295357595c5a026e6cbc3d77b7c36e290201e7c11ecb"},
{file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cfe6ab8da05c01ba6fbea630377b5da2cd9bcbc6338510116b01c1bc939a2c18"},
{file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:d2e5a98f0ec99beb3c10e13b387f8db39106d53993f498b295f0c914328b1333"},
{file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a51a263952b1429e429ff236d2f5a21c5125437861baeed77f5e1cc2d2c7c6da"},
{file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3edd2fa14e68c9be82c5b16689e8d63d89fe927e56debd6e1dbce7a26a17f81b"},
{file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:74d1b44c6cfc897df648cc9fdaa09bc3e7679926e6f96df05775d4fb3946571c"},
{file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:76d9289ed3f7501012e05abb8358bbb129149dbd173f1f57a1bf1c22d19ab7cc"},
{file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:92dea1ffe3714fa8eb6a314d2b3c773208d865a0e0d35e713ec54eea08a66250"},
{file = "kiwisolver-1.4.5-cp38-cp38-win32.whl", hash = "sha256:5c90ae8c8d32e472be041e76f9d2f2dbff4d0b0be8bd4041770eddb18cf49a4e"},
{file = "kiwisolver-1.4.5-cp38-cp38-win_amd64.whl", hash = "sha256:c7940c1dc63eb37a67721b10d703247552416f719c4188c54e04334321351ced"},
{file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9407b6a5f0d675e8a827ad8742e1d6b49d9c1a1da5d952a67d50ef5f4170b18d"},
{file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15568384086b6df3c65353820a4473575dbad192e35010f622c6ce3eebd57af9"},
{file = "kiwisolver-1.4.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0dc9db8e79f0036e8173c466d21ef18e1befc02de8bf8aa8dc0813a6dc8a7046"},
{file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cdc8a402aaee9a798b50d8b827d7ecf75edc5fb35ea0f91f213ff927c15f4ff0"},
{file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6c3bd3cde54cafb87d74d8db50b909705c62b17c2099b8f2e25b461882e544ff"},
{file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:955e8513d07a283056b1396e9a57ceddbd272d9252c14f154d450d227606eb54"},
{file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:346f5343b9e3f00b8db8ba359350eb124b98c99efd0b408728ac6ebf38173958"},
{file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9098e0049e88c6a24ff64545cdfc50807818ba6c1b739cae221bbbcbc58aad3"},
{file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:00bd361b903dc4bbf4eb165f24d1acbee754fce22ded24c3d56eec268658a5cf"},
{file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7b8b454bac16428b22560d0a1cf0a09875339cab69df61d7805bf48919415901"},
{file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f1d072c2eb0ad60d4c183f3fb44ac6f73fb7a8f16a2694a91f988275cbf352f9"},
{file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:31a82d498054cac9f6d0b53d02bb85811185bcb477d4b60144f915f3b3126342"},
{file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6512cb89e334e4700febbffaaa52761b65b4f5a3cf33f960213d5656cea36a77"},
{file = "kiwisolver-1.4.5-cp39-cp39-win32.whl", hash = "sha256:9db8ea4c388fdb0f780fe91346fd438657ea602d58348753d9fb265ce1bca67f"},
{file = "kiwisolver-1.4.5-cp39-cp39-win_amd64.whl", hash = "sha256:59415f46a37f7f2efeec758353dd2eae1b07640d8ca0f0c42548ec4125492635"},
{file = "kiwisolver-1.4.5-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5c7b3b3a728dc6faf3fc372ef24f21d1e3cee2ac3e9596691d746e5a536de920"},
{file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:620ced262a86244e2be10a676b646f29c34537d0d9cc8eb26c08f53d98013390"},
{file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:378a214a1e3bbf5ac4a8708304318b4f890da88c9e6a07699c4ae7174c09a68d"},
{file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf7be1207676ac608a50cd08f102f6742dbfc70e8d60c4db1c6897f62f71523"},
{file = "kiwisolver-1.4.5-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ba55dce0a9b8ff59495ddd050a0225d58bd0983d09f87cfe2b6aec4f2c1234e4"},
{file = "kiwisolver-1.4.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fd32ea360bcbb92d28933fc05ed09bffcb1704ba3fc7942e81db0fd4f81a7892"},
{file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5e7139af55d1688f8b960ee9ad5adafc4ac17c1c473fe07133ac092310d76544"},
{file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dced8146011d2bc2e883f9bd68618b8247387f4bbec46d7392b3c3b032640126"},
{file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9bf3325c47b11b2e51bca0824ea217c7cd84491d8ac4eefd1e409705ef092bd"},
{file = "kiwisolver-1.4.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5794cf59533bc3f1b1c821f7206a3617999db9fbefc345360aafe2e067514929"},
{file = "kiwisolver-1.4.5-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e368f200bbc2e4f905b8e71eb38b3c04333bddaa6a2464a6355487b02bb7fb09"},
{file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5d706eba36b4c4d5bc6c6377bb6568098765e990cfc21ee16d13963fab7b3e7"},
{file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85267bd1aa8880a9c88a8cb71e18d3d64d2751a790e6ca6c27b8ccc724bcd5ad"},
{file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210ef2c3a1f03272649aff1ef992df2e724748918c4bc2d5a90352849eb40bea"},
{file = "kiwisolver-1.4.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:11d011a7574eb3b82bcc9c1a1d35c1d7075677fdd15de527d91b46bd35e935ee"},
{file = "kiwisolver-1.4.5.tar.gz", hash = "sha256:e57e563a57fb22a142da34f38acc2fc1a5c864bc29ca1517a88abc963e60d6ec"},
]
[[package]]
name = "lazy-object-proxy"
version = "1.9.0"
description = "A fast and thorough lazy object proxy."
optional = false
python-versions = ">=3.7"
files = [
{file = "lazy-object-proxy-1.9.0.tar.gz", hash = "sha256:659fb5809fa4629b8a1ac5106f669cfc7bef26fbb389dda53b3e010d1ac4ebae"},
{file = "lazy_object_proxy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b40387277b0ed2d0602b8293b94d7257e17d1479e257b4de114ea11a8cb7f2d7"},
{file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8c6cfb338b133fbdbc5cfaa10fe3c6aeea827db80c978dbd13bc9dd8526b7d4"},
{file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:721532711daa7db0d8b779b0bb0318fa87af1c10d7fe5e52ef30f8eff254d0cd"},
{file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:66a3de4a3ec06cd8af3f61b8e1ec67614fbb7c995d02fa224813cb7afefee701"},
{file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1aa3de4088c89a1b69f8ec0dcc169aa725b0ff017899ac568fe44ddc1396df46"},
{file = "lazy_object_proxy-1.9.0-cp310-cp310-win32.whl", hash = "sha256:f0705c376533ed2a9e5e97aacdbfe04cecd71e0aa84c7c0595d02ef93b6e4455"},
{file = "lazy_object_proxy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:ea806fd4c37bf7e7ad82537b0757999264d5f70c45468447bb2b91afdbe73a6e"},
{file = "lazy_object_proxy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:946d27deaff6cf8452ed0dba83ba38839a87f4f7a9732e8f9fd4107b21e6ff07"},
{file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79a31b086e7e68b24b99b23d57723ef7e2c6d81ed21007b6281ebcd1688acb0a"},
{file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f699ac1c768270c9e384e4cbd268d6e67aebcfae6cd623b4d7c3bfde5a35db59"},
{file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bfb38f9ffb53b942f2b5954e0f610f1e721ccebe9cce9025a38c8ccf4a5183a4"},
{file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:189bbd5d41ae7a498397287c408617fe5c48633e7755287b21d741f7db2706a9"},
{file = "lazy_object_proxy-1.9.0-cp311-cp311-win32.whl", hash = "sha256:81fc4d08b062b535d95c9ea70dbe8a335c45c04029878e62d744bdced5141586"},
{file = "lazy_object_proxy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:f2457189d8257dd41ae9b434ba33298aec198e30adf2dcdaaa3a28b9994f6adb"},
{file = "lazy_object_proxy-1.9.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d9e25ef10a39e8afe59a5c348a4dbf29b4868ab76269f81ce1674494e2565a6e"},
{file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cbf9b082426036e19c6924a9ce90c740a9861e2bdc27a4834fd0a910742ac1e8"},
{file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f5fa4a61ce2438267163891961cfd5e32ec97a2c444e5b842d574251ade27d2"},
{file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8fa02eaab317b1e9e03f69aab1f91e120e7899b392c4fc19807a8278a07a97e8"},
{file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e7c21c95cae3c05c14aafffe2865bbd5e377cfc1348c4f7751d9dc9a48ca4bda"},
{file = "lazy_object_proxy-1.9.0-cp37-cp37m-win32.whl", hash = "sha256:f12ad7126ae0c98d601a7ee504c1122bcef553d1d5e0c3bfa77b16b3968d2734"},
{file = "lazy_object_proxy-1.9.0-cp37-cp37m-win_amd64.whl", hash = "sha256:edd20c5a55acb67c7ed471fa2b5fb66cb17f61430b7a6b9c3b4a1e40293b1671"},
{file = "lazy_object_proxy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d0daa332786cf3bb49e10dc6a17a52f6a8f9601b4cf5c295a4f85854d61de63"},
{file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cd077f3d04a58e83d04b20e334f678c2b0ff9879b9375ed107d5d07ff160171"},
{file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:660c94ea760b3ce47d1855a30984c78327500493d396eac4dfd8bd82041b22be"},
{file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:212774e4dfa851e74d393a2370871e174d7ff0ebc980907723bb67d25c8a7c30"},
{file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0117049dd1d5635bbff65444496c90e0baa48ea405125c088e93d9cf4525b11"},
{file = "lazy_object_proxy-1.9.0-cp38-cp38-win32.whl", hash = "sha256:0a891e4e41b54fd5b8313b96399f8b0e173bbbfc03c7631f01efbe29bb0bcf82"},
{file = "lazy_object_proxy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:9990d8e71b9f6488e91ad25f322898c136b008d87bf852ff65391b004da5e17b"},
{file = "lazy_object_proxy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9e7551208b2aded9c1447453ee366f1c4070602b3d932ace044715d89666899b"},
{file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f83ac4d83ef0ab017683d715ed356e30dd48a93746309c8f3517e1287523ef4"},
{file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7322c3d6f1766d4ef1e51a465f47955f1e8123caee67dd641e67d539a534d006"},
{file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:18b78ec83edbbeb69efdc0e9c1cb41a3b1b1ed11ddd8ded602464c3fc6020494"},
{file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:09763491ce220c0299688940f8dc2c5d05fd1f45af1e42e636b2e8b2303e4382"},
{file = "lazy_object_proxy-1.9.0-cp39-cp39-win32.whl", hash = "sha256:9090d8e53235aa280fc9239a86ae3ea8ac58eff66a705fa6aa2ec4968b95c821"},
{file = "lazy_object_proxy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:db1c1722726f47e10e0b5fdbf15ac3b8adb58c091d12b3ab713965795036985f"},
]
[[package]]
name = "macholib"
version = "1.16.3"
@@ -96,6 +481,103 @@ files = [
[package.dependencies]
altgraph = ">=0.17"
[[package]]
name = "matplotlib"
version = "3.7.3"
description = "Python plotting package"
optional = false
python-versions = ">=3.8"
files = [
{file = "matplotlib-3.7.3-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:085c33b27561d9c04386789d5aa5eb4a932ddef43cfcdd0e01735f9a6e85ce0c"},
{file = "matplotlib-3.7.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:c568e80e1c17f68a727f30f591926751b97b98314d8e59804f54f86ae6fa6a22"},
{file = "matplotlib-3.7.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7baf98c5ad59c5c4743ea884bb025cbffa52dacdfdac0da3e6021a285a90377e"},
{file = "matplotlib-3.7.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:236024f582e40dac39bca592258888b38ae47a9fed7b8de652d68d3d02d47d2b"},
{file = "matplotlib-3.7.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12b4f6795efea037ce2d41e7c417ad8bd02d5719c6ad4a8450a0708f4a1cfb89"},
{file = "matplotlib-3.7.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b2136cc6c5415b78977e0e8c608647d597204b05b1d9089ccf513c7d913733"},
{file = "matplotlib-3.7.3-cp310-cp310-win32.whl", hash = "sha256:122dcbf9be0086e2a95d9e5e0632dbf3bd5b65eaa68c369363310a6c87753059"},
{file = "matplotlib-3.7.3-cp310-cp310-win_amd64.whl", hash = "sha256:4aab27d9e33293389e3c1d7c881d414a72bdfda0fedc3a6bf46c6fa88d9b8015"},
{file = "matplotlib-3.7.3-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:d5adc743de91e8e0b13df60deb1b1c285b8effea3d66223afceb14b63c9b05de"},
{file = "matplotlib-3.7.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:55de4cf7cd0071b8ebf203981b53ab64f988a0a1f897a2dff300a1124e8bcd8b"},
{file = "matplotlib-3.7.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ac03377fd908aaee2312d0b11735753e907adb6f4d1d102de5e2425249693f6c"},
{file = "matplotlib-3.7.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:755bafc10a46918ce9a39980009b54b02dd249594e5adf52f9c56acfddb5d0b7"},
{file = "matplotlib-3.7.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a6094c6f8e8d18db631754df4fe9a34dec3caf074f6869a7db09f18f9b1d6b2"},
{file = "matplotlib-3.7.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:272dba2f1b107790ed78ebf5385b8d14b27ad9e90419de340364b49fe549a993"},
{file = "matplotlib-3.7.3-cp311-cp311-win32.whl", hash = "sha256:591c123bed1cb4b9996fb60b41a6d89c2ec4943244540776c5f1283fb6960a53"},
{file = "matplotlib-3.7.3-cp311-cp311-win_amd64.whl", hash = "sha256:3bf3a178c6504694cee8b88b353df0051583f2f6f8faa146f67115c27c856881"},
{file = "matplotlib-3.7.3-cp312-cp312-macosx_10_12_universal2.whl", hash = "sha256:edf54cac8ee3603f3093616b40a931e8c063969756a4d78a86e82c2fea9659f7"},
{file = "matplotlib-3.7.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:91e36a85ea639a1ba9f91427041eac064b04829945fe331a92617b6cb21d27e5"},
{file = "matplotlib-3.7.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:caf5eaaf7c68f8d7df269dfbcaf46f48a70ff482bfcebdcc97519671023f2a7d"},
{file = "matplotlib-3.7.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74bf57f505efea376097e948b7cdd87191a7ce8180616390aef496639edf601f"},
{file = "matplotlib-3.7.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee152a88a0da527840a426535514b6ed8ac4240eb856b1da92cf48124320e346"},
{file = "matplotlib-3.7.3-cp312-cp312-win_amd64.whl", hash = "sha256:67a410a9c9e07cbc83581eeea144bbe298870bf0ac0ee2f2e10a015ab7efee19"},
{file = "matplotlib-3.7.3-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:259999c05285cb993d7f2a419cea547863fa215379eda81f7254c9e932963729"},
{file = "matplotlib-3.7.3-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:3f4e7fd5a6157e1d018ce2166ec8e531a481dd4a36f035b5c23edfe05a25419a"},
{file = "matplotlib-3.7.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:faa3d12d8811d08d14080a8b7b9caea9a457dc495350166b56df0db4b9909ef5"},
{file = "matplotlib-3.7.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:336e88900c11441e458da01c8414fc57e04e17f9d3bb94958a76faa2652bcf6b"},
{file = "matplotlib-3.7.3-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:12f4c0dd8aa280d796c8772ea8265a14f11a04319baa3a16daa5556065e8baea"},
{file = "matplotlib-3.7.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1990955b11e7918d256cf3b956b10997f405b7917a3f1c7d8e69c1d15c7b1930"},
{file = "matplotlib-3.7.3-cp38-cp38-win32.whl", hash = "sha256:e78707b751260b42b721507ad7aa60fe4026d7f51c74cca6b9cd8b123ebb633a"},
{file = "matplotlib-3.7.3-cp38-cp38-win_amd64.whl", hash = "sha256:e594ee43c59ea39ca5c6244667cac9d017a3527febc31f5532ad9135cf7469ec"},
{file = "matplotlib-3.7.3-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:6eaa1cf0e94c936a26b78f6d756c5fbc12e0a58c8a68b7248a2a31456ce4e234"},
{file = "matplotlib-3.7.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:0a97af9d22e8ebedc9f00b043d9bbd29a375e9e10b656982012dded44c10fd77"},
{file = "matplotlib-3.7.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1f9c6c16597af660433ab330b59ee2934b832ee1fabcaf5cbde7b2add840f31e"},
{file = "matplotlib-3.7.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7240259b4b9cbc62381f6378cff4d57af539162a18e832c1e48042fabc40b6b"},
{file = "matplotlib-3.7.3-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:747c6191d2e88ae854809e69aa358dbf852ff1a5738401b85c1cc9012309897a"},
{file = "matplotlib-3.7.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec726b08a5275d827aa91bb951e68234a4423adb91cf65bc0fcdc0f2777663f7"},
{file = "matplotlib-3.7.3-cp39-cp39-win32.whl", hash = "sha256:40e3b9b450c6534f07278310c4e34caff41c2a42377e4b9d47b0f8d3ac1083a2"},
{file = "matplotlib-3.7.3-cp39-cp39-win_amd64.whl", hash = "sha256:dfc118642903a23e309b1da32886bb39a4314147d013e820c86b5fb4cb2e36d0"},
{file = "matplotlib-3.7.3-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:165c8082bf8fc0360c24aa4724a22eaadbfd8c28bf1ccf7e94d685cad48261e4"},
{file = "matplotlib-3.7.3-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ebd8470cc2a3594746ff0513aecbfa2c55ff6f58e6cef2efb1a54eb87c88ffa2"},
{file = "matplotlib-3.7.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7153453669c9672b52095119fd21dd032d19225d48413a2871519b17db4b0fde"},
{file = "matplotlib-3.7.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:498a08267dc69dd8f24c4b5d7423fa584d7ce0027ba71f7881df05fc09b89bb7"},
{file = "matplotlib-3.7.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:d48999c4b19b5a0c058c9cd828ff6fc7748390679f6cf9a2ad653a3e802c87d3"},
{file = "matplotlib-3.7.3-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22d65d18b4ee8070a5fea5761d59293f1f9e2fac37ec9ce090463b0e629432fd"},
{file = "matplotlib-3.7.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c40cde976c36693cc0767e27cf5f443f91c23520060bd9496678364adfafe9c"},
{file = "matplotlib-3.7.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:39018a2b17592448fbfdf4b8352955e6c3905359939791d4ff429296494d1a0c"},
{file = "matplotlib-3.7.3.tar.gz", hash = "sha256:f09b3dd6bdeb588de91f853bbb2d6f0ff8ab693485b0c49035eaa510cb4f142e"},
]
[package.dependencies]
contourpy = ">=1.0.1"
cycler = ">=0.10"
fonttools = ">=4.22.0"
importlib-resources = {version = ">=3.2.0", markers = "python_version < \"3.10\""}
kiwisolver = ">=1.0.1"
numpy = ">=1.20,<2"
packaging = ">=20.0"
pillow = ">=6.2.0"
pyparsing = ">=2.3.1"
python-dateutil = ">=2.7"
setuptools_scm = ">=7"
[[package]]
name = "mccabe"
version = "0.7.0"
description = "McCabe checker, plugin for flake8"
optional = false
python-versions = ">=3.6"
files = [
{file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"},
{file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"},
]
[[package]]
name = "mpmath"
version = "1.3.0"
description = "Python library for arbitrary-precision floating-point arithmetic"
optional = false
python-versions = "*"
files = [
{file = "mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c"},
{file = "mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f"},
]
[package.extras]
develop = ["codecov", "pycodestyle", "pytest (>=4.6)", "pytest-cov", "wheel"]
docs = ["sphinx"]
gmpy = ["gmpy2 (>=2.1.0a4)"]
tests = ["pytest (>=4.6)"]
[[package]]
name = "nodeenv"
version = "1.8.0"
@@ -149,13 +631,13 @@ files = [
[[package]]
name = "packaging"
version = "23.1"
version = "23.2"
description = "Core utilities for Python packages"
optional = false
python-versions = ">=3.7"
files = [
{file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"},
{file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"},
{file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"},
{file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"},
]
[[package]]
@@ -232,15 +714,94 @@ files = [
{file = "pefile-2023.2.7.tar.gz", hash = "sha256:82e6114004b3d6911c77c3953e3838654b04511b8b66e8583db70c65998017dc"},
]
[[package]]
name = "pillow"
version = "9.5.0"
description = "Python Imaging Library (Fork)"
optional = false
python-versions = ">=3.7"
files = [
{file = "Pillow-9.5.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:ace6ca218308447b9077c14ea4ef381ba0b67ee78d64046b3f19cf4e1139ad16"},
{file = "Pillow-9.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d3d403753c9d5adc04d4694d35cf0391f0f3d57c8e0030aac09d7678fa8030aa"},
{file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ba1b81ee69573fe7124881762bb4cd2e4b6ed9dd28c9c60a632902fe8db8b38"},
{file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe7e1c262d3392afcf5071df9afa574544f28eac825284596ac6db56e6d11062"},
{file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f36397bf3f7d7c6a3abdea815ecf6fd14e7fcd4418ab24bae01008d8d8ca15e"},
{file = "Pillow-9.5.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:252a03f1bdddce077eff2354c3861bf437c892fb1832f75ce813ee94347aa9b5"},
{file = "Pillow-9.5.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:85ec677246533e27770b0de5cf0f9d6e4ec0c212a1f89dfc941b64b21226009d"},
{file = "Pillow-9.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b416f03d37d27290cb93597335a2f85ed446731200705b22bb927405320de903"},
{file = "Pillow-9.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1781a624c229cb35a2ac31cc4a77e28cafc8900733a864870c49bfeedacd106a"},
{file = "Pillow-9.5.0-cp310-cp310-win32.whl", hash = "sha256:8507eda3cd0608a1f94f58c64817e83ec12fa93a9436938b191b80d9e4c0fc44"},
{file = "Pillow-9.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:d3c6b54e304c60c4181da1c9dadf83e4a54fd266a99c70ba646a9baa626819eb"},
{file = "Pillow-9.5.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:7ec6f6ce99dab90b52da21cf0dc519e21095e332ff3b399a357c187b1a5eee32"},
{file = "Pillow-9.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:560737e70cb9c6255d6dcba3de6578a9e2ec4b573659943a5e7e4af13f298f5c"},
{file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96e88745a55b88a7c64fa49bceff363a1a27d9a64e04019c2281049444a571e3"},
{file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d9c206c29b46cfd343ea7cdfe1232443072bbb270d6a46f59c259460db76779a"},
{file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cfcc2c53c06f2ccb8976fb5c71d448bdd0a07d26d8e07e321c103416444c7ad1"},
{file = "Pillow-9.5.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:a0f9bb6c80e6efcde93ffc51256d5cfb2155ff8f78292f074f60f9e70b942d99"},
{file = "Pillow-9.5.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:8d935f924bbab8f0a9a28404422da8af4904e36d5c33fc6f677e4c4485515625"},
{file = "Pillow-9.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fed1e1cf6a42577953abbe8e6cf2fe2f566daebde7c34724ec8803c4c0cda579"},
{file = "Pillow-9.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c1170d6b195555644f0616fd6ed929dfcf6333b8675fcca044ae5ab110ded296"},
{file = "Pillow-9.5.0-cp311-cp311-win32.whl", hash = "sha256:54f7102ad31a3de5666827526e248c3530b3a33539dbda27c6843d19d72644ec"},
{file = "Pillow-9.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:cfa4561277f677ecf651e2b22dc43e8f5368b74a25a8f7d1d4a3a243e573f2d4"},
{file = "Pillow-9.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:965e4a05ef364e7b973dd17fc765f42233415974d773e82144c9bbaaaea5d089"},
{file = "Pillow-9.5.0-cp312-cp312-win32.whl", hash = "sha256:22baf0c3cf0c7f26e82d6e1adf118027afb325e703922c8dfc1d5d0156bb2eeb"},
{file = "Pillow-9.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:432b975c009cf649420615388561c0ce7cc31ce9b2e374db659ee4f7d57a1f8b"},
{file = "Pillow-9.5.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:5d4ebf8e1db4441a55c509c4baa7a0587a0210f7cd25fcfe74dbbce7a4bd1906"},
{file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:375f6e5ee9620a271acb6820b3d1e94ffa8e741c0601db4c0c4d3cb0a9c224bf"},
{file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99eb6cafb6ba90e436684e08dad8be1637efb71c4f2180ee6b8f940739406e78"},
{file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dfaaf10b6172697b9bceb9a3bd7b951819d1ca339a5ef294d1f1ac6d7f63270"},
{file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:763782b2e03e45e2c77d7779875f4432e25121ef002a41829d8868700d119392"},
{file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:35f6e77122a0c0762268216315bf239cf52b88865bba522999dc38f1c52b9b47"},
{file = "Pillow-9.5.0-cp37-cp37m-win32.whl", hash = "sha256:aca1c196f407ec7cf04dcbb15d19a43c507a81f7ffc45b690899d6a76ac9fda7"},
{file = "Pillow-9.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322724c0032af6692456cd6ed554bb85f8149214d97398bb80613b04e33769f6"},
{file = "Pillow-9.5.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:a0aa9417994d91301056f3d0038af1199eb7adc86e646a36b9e050b06f526597"},
{file = "Pillow-9.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f8286396b351785801a976b1e85ea88e937712ee2c3ac653710a4a57a8da5d9c"},
{file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c830a02caeb789633863b466b9de10c015bded434deb3ec87c768e53752ad22a"},
{file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fbd359831c1657d69bb81f0db962905ee05e5e9451913b18b831febfe0519082"},
{file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8fc330c3370a81bbf3f88557097d1ea26cd8b019d6433aa59f71195f5ddebbf"},
{file = "Pillow-9.5.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:7002d0797a3e4193c7cdee3198d7c14f92c0836d6b4a3f3046a64bd1ce8df2bf"},
{file = "Pillow-9.5.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:229e2c79c00e85989a34b5981a2b67aa079fd08c903f0aaead522a1d68d79e51"},
{file = "Pillow-9.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9adf58f5d64e474bed00d69bcd86ec4bcaa4123bfa70a65ce72e424bfb88ed96"},
{file = "Pillow-9.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:662da1f3f89a302cc22faa9f14a262c2e3951f9dbc9617609a47521c69dd9f8f"},
{file = "Pillow-9.5.0-cp38-cp38-win32.whl", hash = "sha256:6608ff3bf781eee0cd14d0901a2b9cc3d3834516532e3bd673a0a204dc8615fc"},
{file = "Pillow-9.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:e49eb4e95ff6fd7c0c402508894b1ef0e01b99a44320ba7d8ecbabefddcc5569"},
{file = "Pillow-9.5.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:482877592e927fd263028c105b36272398e3e1be3269efda09f6ba21fd83ec66"},
{file = "Pillow-9.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3ded42b9ad70e5f1754fb7c2e2d6465a9c842e41d178f262e08b8c85ed8a1d8e"},
{file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c446d2245ba29820d405315083d55299a796695d747efceb5717a8b450324115"},
{file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8aca1152d93dcc27dc55395604dcfc55bed5f25ef4c98716a928bacba90d33a3"},
{file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:608488bdcbdb4ba7837461442b90ea6f3079397ddc968c31265c1e056964f1ef"},
{file = "Pillow-9.5.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:60037a8db8750e474af7ffc9faa9b5859e6c6d0a50e55c45576bf28be7419705"},
{file = "Pillow-9.5.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:07999f5834bdc404c442146942a2ecadd1cb6292f5229f4ed3b31e0a108746b1"},
{file = "Pillow-9.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a127ae76092974abfbfa38ca2d12cbeddcdeac0fb71f9627cc1135bedaf9d51a"},
{file = "Pillow-9.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:489f8389261e5ed43ac8ff7b453162af39c3e8abd730af8363587ba64bb2e865"},
{file = "Pillow-9.5.0-cp39-cp39-win32.whl", hash = "sha256:9b1af95c3a967bf1da94f253e56b6286b50af23392a886720f563c547e48e964"},
{file = "Pillow-9.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:77165c4a5e7d5a284f10a6efaa39a0ae8ba839da344f20b111d62cc932fa4e5d"},
{file = "Pillow-9.5.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:833b86a98e0ede388fa29363159c9b1a294b0905b5128baf01db683672f230f5"},
{file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aaf305d6d40bd9632198c766fb64f0c1a83ca5b667f16c1e79e1661ab5060140"},
{file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0852ddb76d85f127c135b6dd1f0bb88dbb9ee990d2cd9aa9e28526c93e794fba"},
{file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:91ec6fe47b5eb5a9968c79ad9ed78c342b1f97a091677ba0e012701add857829"},
{file = "Pillow-9.5.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cb841572862f629b99725ebaec3287fc6d275be9b14443ea746c1dd325053cbd"},
{file = "Pillow-9.5.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:c380b27d041209b849ed246b111b7c166ba36d7933ec6e41175fd15ab9eb1572"},
{file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c9af5a3b406a50e313467e3565fc99929717f780164fe6fbb7704edba0cebbe"},
{file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5671583eab84af046a397d6d0ba25343c00cd50bce03787948e0fff01d4fd9b1"},
{file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:84a6f19ce086c1bf894644b43cd129702f781ba5751ca8572f08aa40ef0ab7b7"},
{file = "Pillow-9.5.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1e7723bd90ef94eda669a3c2c19d549874dd5badaeefabefd26053304abe5799"},
{file = "Pillow-9.5.0.tar.gz", hash = "sha256:bf548479d336726d7a0eceb6e767e179fbde37833ae42794602631a070d630f1"},
]
[package.extras]
docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"]
tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"]
[[package]]
name = "platformdirs"
version = "3.10.0"
version = "3.11.0"
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
optional = false
python-versions = ">=3.7"
files = [
{file = "platformdirs-3.10.0-py3-none-any.whl", hash = "sha256:d7c24979f292f916dc9cbf8648319032f551ea8c49a4c9bf2fb556a02070ec1d"},
{file = "platformdirs-3.10.0.tar.gz", hash = "sha256:b45696dab2d7cc691a3226759c0d3b00c47c8b6e293d96f6436f733303f77f6d"},
{file = "platformdirs-3.11.0-py3-none-any.whl", hash = "sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e"},
{file = "platformdirs-3.11.0.tar.gz", hash = "sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3"},
]
[package.extras]
@@ -249,13 +810,13 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-co
[[package]]
name = "pre-commit"
version = "3.4.0"
version = "3.5.0"
description = "A framework for managing and maintaining multi-language pre-commit hooks."
optional = false
python-versions = ">=3.8"
files = [
{file = "pre_commit-3.4.0-py2.py3-none-any.whl", hash = "sha256:96d529a951f8b677f730a7212442027e8ba53f9b04d217c4c67dc56c393ad945"},
{file = "pre_commit-3.4.0.tar.gz", hash = "sha256:6bbd5129a64cad4c0dfaeeb12cd8f7ea7e15b77028d985341478c8af3c759522"},
{file = "pre_commit-3.5.0-py2.py3-none-any.whl", hash = "sha256:841dc9aef25daba9a0238cd27984041fa0467b4199fc4852e27950664919f660"},
{file = "pre_commit-3.5.0.tar.gz", hash = "sha256:5804465c675b659b0862f07907f96295d490822a450c4c40e747d0b1c6ebcb32"},
]
[package.dependencies]
@@ -267,23 +828,23 @@ virtualenv = ">=20.10.0"
[[package]]
name = "pyinstaller"
version = "6.0.0"
version = "6.1.0"
description = "PyInstaller bundles a Python application and all its dependencies into a single package."
optional = false
python-versions = "<3.13,>=3.8"
files = [
{file = "pyinstaller-6.0.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:d84b06fb9002109bfc542e76860b81459a8585af0bbdabcfc5dcf272ef230de7"},
{file = "pyinstaller-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:aa922d1d73881d0820a341d2c406a571cc94630bdcdc275427c844a12e6e376e"},
{file = "pyinstaller-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:52e5b3a2371d7231de17515c7c78d8d4a39d70c8c095e71d55b3b83434a193a8"},
{file = "pyinstaller-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:4a75bde5cda259bb31f2294960d75b9d5c148001b2b0bd20a91f9c2116675a6c"},
{file = "pyinstaller-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:5314f6f08d2bcbc031778618ba97d9098d106119c2e616b3b081171fe42f5415"},
{file = "pyinstaller-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:0ad7cc3776ca17d0bededcc352cba2b1c89eb4817bfabaf05972b9da8c424935"},
{file = "pyinstaller-6.0.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:cccdad6cfe7a5db7d7eb8df2e5678f8375268739d5933214e180da300aa54e37"},
{file = "pyinstaller-6.0.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:fb6af82989dac7c58bd25ed9ba3323bc443f8c1f03804f69c9f5e363bf4a021c"},
{file = "pyinstaller-6.0.0-py3-none-win32.whl", hash = "sha256:68769f5e6722474bb1038e35560444659db8b951388bfe0c669bb52a640cd0eb"},
{file = "pyinstaller-6.0.0-py3-none-win_amd64.whl", hash = "sha256:438a9e0d72a57d5bba4f112d256e39ea4033c76c65414c0693d8311faa14b090"},
{file = "pyinstaller-6.0.0-py3-none-win_arm64.whl", hash = "sha256:16a473065291dd7879bf596fa20e65bd9d1e8aafc2cef1bffa3e42e707e2e68e"},
{file = "pyinstaller-6.0.0.tar.gz", hash = "sha256:d702cff041f30e7a53500b630e07b081e5328d4655023319253d73935e75ade2"},
{file = "pyinstaller-6.1.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:da78942d31c1911ea4abcd3ca3bd0c062af7f163a5e227fd18a359b61deda4ca"},
{file = "pyinstaller-6.1.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:f63d2353537bac7bfeeaedbe5ac99f3be35daa290dd1ad1be90768acbf77e3d5"},
{file = "pyinstaller-6.1.0-py3-none-manylinux2014_i686.whl", hash = "sha256:6e71d9f6f5a1e0f7523e8ebee1b76bb29538f64d863e3711c2b21033f499e2b9"},
{file = "pyinstaller-6.1.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:bebf6f442bbe6343acaec873803510ee1930d026846a018f727da4e0690081f8"},
{file = "pyinstaller-6.1.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:3c04963637481a3edf1eec64ab4c3fce098908f02fc472c11e73be7eedc08b95"},
{file = "pyinstaller-6.1.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:4368e4eb9999ce32e3280330b3c26f175e0fa7fa13efb4d2dc4ade488ff6d7c2"},
{file = "pyinstaller-6.1.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:041ab9311d08162356829bf47293a613c44dc9ace28846fb63098889c7383c5d"},
{file = "pyinstaller-6.1.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:331f050e8f9e923bb6b50454acfc0547fd52092585c61eb5f2fc93de60703f13"},
{file = "pyinstaller-6.1.0-py3-none-win32.whl", hash = "sha256:9e8b5bbc1bdf554ade1360e62e4959091430c3cc15ebfff3c28c8894fd1f312a"},
{file = "pyinstaller-6.1.0-py3-none-win_amd64.whl", hash = "sha256:f9f5bcaef6122d93c54ee7a9ecb07eab5b81a7ebfb5cb99af2b2a6ff49eff62f"},
{file = "pyinstaller-6.1.0-py3-none-win_arm64.whl", hash = "sha256:dd438afd2abb643f5399c0cb254a11c217c06782cb274a2911dd785f9f67fa9e"},
{file = "pyinstaller-6.1.0.tar.gz", hash = "sha256:8f3d49c60f3344bf3d4a6d4258bda665dad185ab2b097341d3af2a6387c838ef"},
]
[package.dependencies]
@@ -301,15 +862,55 @@ hook-testing = ["execnet (>=1.5.0)", "psutil", "pytest (>=2.7.3)"]
[[package]]
name = "pyinstaller-hooks-contrib"
version = "2023.9"
version = "2023.10"
description = "Community maintained hooks for PyInstaller"
optional = false
python-versions = ">=3.7"
files = [
{file = "pyinstaller-hooks-contrib-2023.9.tar.gz", hash = "sha256:76084b5988e3957a9df169d2a935d65500136967e710ddebf57263f1a909cd80"},
{file = "pyinstaller_hooks_contrib-2023.9-py2.py3-none-any.whl", hash = "sha256:f34f4c6807210025c8073ebe665f422a3aa2ac5f4c7ebf4c2a26cc77bebf63b5"},
{file = "pyinstaller-hooks-contrib-2023.10.tar.gz", hash = "sha256:4b4a998036abb713774cb26534ca06b7e6e09e4c628196017a10deb11a48747f"},
{file = "pyinstaller_hooks_contrib-2023.10-py2.py3-none-any.whl", hash = "sha256:6dc1786a8f452941245d5bb85893e2a33632ebdcbc4c23eea41f2ee08281b0c0"},
]
[[package]]
name = "pylint"
version = "2.17.7"
description = "python code static checker"
optional = false
python-versions = ">=3.7.2"
files = [
{file = "pylint-2.17.7-py3-none-any.whl", hash = "sha256:27a8d4c7ddc8c2f8c18aa0050148f89ffc09838142193fdbe98f172781a3ff87"},
{file = "pylint-2.17.7.tar.gz", hash = "sha256:f4fcac7ae74cfe36bc8451e931d8438e4a476c20314b1101c458ad0f05191fad"},
]
[package.dependencies]
astroid = ">=2.15.8,<=2.17.0-dev0"
colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""}
dill = {version = ">=0.2", markers = "python_version < \"3.11\""}
isort = ">=4.2.5,<6"
mccabe = ">=0.6,<0.8"
platformdirs = ">=2.2.0"
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
tomlkit = ">=0.10.1"
typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""}
[package.extras]
spelling = ["pyenchant (>=3.2,<4.0)"]
testutils = ["gitpython (>3)"]
[[package]]
name = "pyparsing"
version = "3.1.1"
description = "pyparsing module - Classes and methods to define and execute parsing grammars"
optional = false
python-versions = ">=3.6.8"
files = [
{file = "pyparsing-3.1.1-py3-none-any.whl", hash = "sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb"},
{file = "pyparsing-3.1.1.tar.gz", hash = "sha256:ede28a1a32462f5a9705e07aea48001a08f7cf81a021585011deba701581a0db"},
]
[package.extras]
diagrams = ["jinja2", "railroad-diagrams"]
[[package]]
name = "pyside2"
version = "5.15.2.1"
@@ -439,6 +1040,28 @@ docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments
testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
[[package]]
name = "setuptools-scm"
version = "8.0.4"
description = "the blessed package to manage your versions by scm tags"
optional = false
python-versions = ">=3.8"
files = [
{file = "setuptools-scm-8.0.4.tar.gz", hash = "sha256:b5f43ff6800669595193fd09891564ee9d1d7dcb196cab4b2506d53a2e1c95c7"},
{file = "setuptools_scm-8.0.4-py3-none-any.whl", hash = "sha256:b47844cd2a84b83b3187a5782c71128c28b4c94cad8bfb871da2784a5cb54c4f"},
]
[package.dependencies]
packaging = ">=20"
setuptools = "*"
tomli = {version = ">=1", markers = "python_version < \"3.11\""}
typing-extensions = "*"
[package.extras]
docs = ["entangled-cli[rich]", "mkdocs", "mkdocs-entangled-plugin", "mkdocs-material", "mkdocstrings[python]", "pygments"]
rich = ["rich"]
test = ["build", "pytest", "rich", "wheel"]
[[package]]
name = "shiboken2"
version = "5.15.2.1"
@@ -465,6 +1088,53 @@ files = [
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
]
[[package]]
name = "sympy"
version = "1.12"
description = "Computer algebra system (CAS) in Python"
optional = false
python-versions = ">=3.8"
files = [
{file = "sympy-1.12-py3-none-any.whl", hash = "sha256:c3588cd4295d0c0f603d0f2ae780587e64e2efeedb3521e46b9bb1d08d184fa5"},
{file = "sympy-1.12.tar.gz", hash = "sha256:ebf595c8dac3e0fdc4152c51878b498396ec7f30e7a914d6071e674d49420fb8"},
]
[package.dependencies]
mpmath = ">=0.19"
[[package]]
name = "tomli"
version = "2.0.1"
description = "A lil' TOML parser"
optional = false
python-versions = ">=3.7"
files = [
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
]
[[package]]
name = "tomlkit"
version = "0.12.1"
description = "Style preserving TOML library"
optional = false
python-versions = ">=3.7"
files = [
{file = "tomlkit-0.12.1-py3-none-any.whl", hash = "sha256:712cbd236609acc6a3e2e97253dfc52d4c2082982a88f61b640ecf0817eab899"},
{file = "tomlkit-0.12.1.tar.gz", hash = "sha256:38e1ff8edb991273ec9f6181244a6a391ac30e9f5098e7535640ea6be97a7c86"},
]
[[package]]
name = "typing-extensions"
version = "4.8.0"
description = "Backported and Experimental Type Hints for Python 3.8+"
optional = false
python-versions = ">=3.8"
files = [
{file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"},
{file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"},
]
[[package]]
name = "tzdata"
version = "2023.3"
@@ -496,6 +1166,90 @@ platformdirs = ">=3.9.1,<4"
docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"]
test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"]
[[package]]
name = "wrapt"
version = "1.15.0"
description = "Module for decorators, wrappers and monkey patching."
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
files = [
{file = "wrapt-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ca1cccf838cd28d5a0883b342474c630ac48cac5df0ee6eacc9c7290f76b11c1"},
{file = "wrapt-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e826aadda3cae59295b95343db8f3d965fb31059da7de01ee8d1c40a60398b29"},
{file = "wrapt-1.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5fc8e02f5984a55d2c653f5fea93531e9836abbd84342c1d1e17abc4a15084c2"},
{file = "wrapt-1.15.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:96e25c8603a155559231c19c0349245eeb4ac0096fe3c1d0be5c47e075bd4f46"},
{file = "wrapt-1.15.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:40737a081d7497efea35ab9304b829b857f21558acfc7b3272f908d33b0d9d4c"},
{file = "wrapt-1.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:f87ec75864c37c4c6cb908d282e1969e79763e0d9becdfe9fe5473b7bb1e5f09"},
{file = "wrapt-1.15.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:1286eb30261894e4c70d124d44b7fd07825340869945c79d05bda53a40caa079"},
{file = "wrapt-1.15.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:493d389a2b63c88ad56cdc35d0fa5752daac56ca755805b1b0c530f785767d5e"},
{file = "wrapt-1.15.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:58d7a75d731e8c63614222bcb21dd992b4ab01a399f1f09dd82af17bbfc2368a"},
{file = "wrapt-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:21f6d9a0d5b3a207cdf7acf8e58d7d13d463e639f0c7e01d82cdb671e6cb7923"},
{file = "wrapt-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ce42618f67741d4697684e501ef02f29e758a123aa2d669e2d964ff734ee00ee"},
{file = "wrapt-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41d07d029dd4157ae27beab04d22b8e261eddfc6ecd64ff7000b10dc8b3a5727"},
{file = "wrapt-1.15.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54accd4b8bc202966bafafd16e69da9d5640ff92389d33d28555c5fd4f25ccb7"},
{file = "wrapt-1.15.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fbfbca668dd15b744418265a9607baa970c347eefd0db6a518aaf0cfbd153c0"},
{file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:76e9c727a874b4856d11a32fb0b389afc61ce8aaf281ada613713ddeadd1cfec"},
{file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e20076a211cd6f9b44a6be58f7eeafa7ab5720eb796975d0c03f05b47d89eb90"},
{file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a74d56552ddbde46c246b5b89199cb3fd182f9c346c784e1a93e4dc3f5ec9975"},
{file = "wrapt-1.15.0-cp310-cp310-win32.whl", hash = "sha256:26458da5653aa5b3d8dc8b24192f574a58984c749401f98fff994d41d3f08da1"},
{file = "wrapt-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:75760a47c06b5974aa5e01949bf7e66d2af4d08cb8c1d6516af5e39595397f5e"},
{file = "wrapt-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ba1711cda2d30634a7e452fc79eabcadaffedf241ff206db2ee93dd2c89a60e7"},
{file = "wrapt-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:56374914b132c702aa9aa9959c550004b8847148f95e1b824772d453ac204a72"},
{file = "wrapt-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a89ce3fd220ff144bd9d54da333ec0de0399b52c9ac3d2ce34b569cf1a5748fb"},
{file = "wrapt-1.15.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bbe623731d03b186b3d6b0d6f51865bf598587c38d6f7b0be2e27414f7f214e"},
{file = "wrapt-1.15.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3abbe948c3cbde2689370a262a8d04e32ec2dd4f27103669a45c6929bcdbfe7c"},
{file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b67b819628e3b748fd3c2192c15fb951f549d0f47c0449af0764d7647302fda3"},
{file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7eebcdbe3677e58dd4c0e03b4f2cfa346ed4049687d839adad68cc38bb559c92"},
{file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:74934ebd71950e3db69960a7da29204f89624dde411afbfb3b4858c1409b1e98"},
{file = "wrapt-1.15.0-cp311-cp311-win32.whl", hash = "sha256:bd84395aab8e4d36263cd1b9308cd504f6cf713b7d6d3ce25ea55670baec5416"},
{file = "wrapt-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:a487f72a25904e2b4bbc0817ce7a8de94363bd7e79890510174da9d901c38705"},
{file = "wrapt-1.15.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:4ff0d20f2e670800d3ed2b220d40984162089a6e2c9646fdb09b85e6f9a8fc29"},
{file = "wrapt-1.15.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9ed6aa0726b9b60911f4aed8ec5b8dd7bf3491476015819f56473ffaef8959bd"},
{file = "wrapt-1.15.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:896689fddba4f23ef7c718279e42f8834041a21342d95e56922e1c10c0cc7afb"},
{file = "wrapt-1.15.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:75669d77bb2c071333417617a235324a1618dba66f82a750362eccbe5b61d248"},
{file = "wrapt-1.15.0-cp35-cp35m-win32.whl", hash = "sha256:fbec11614dba0424ca72f4e8ba3c420dba07b4a7c206c8c8e4e73f2e98f4c559"},
{file = "wrapt-1.15.0-cp35-cp35m-win_amd64.whl", hash = "sha256:fd69666217b62fa5d7c6aa88e507493a34dec4fa20c5bd925e4bc12fce586639"},
{file = "wrapt-1.15.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b0724f05c396b0a4c36a3226c31648385deb6a65d8992644c12a4963c70326ba"},
{file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbeccb1aa40ab88cd29e6c7d8585582c99548f55f9b2581dfc5ba68c59a85752"},
{file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38adf7198f8f154502883242f9fe7333ab05a5b02de7d83aa2d88ea621f13364"},
{file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:578383d740457fa790fdf85e6d346fda1416a40549fe8db08e5e9bd281c6a475"},
{file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:a4cbb9ff5795cd66f0066bdf5947f170f5d63a9274f99bdbca02fd973adcf2a8"},
{file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:af5bd9ccb188f6a5fdda9f1f09d9f4c86cc8a539bd48a0bfdc97723970348418"},
{file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b56d5519e470d3f2fe4aa7585f0632b060d532d0696c5bdfb5e8319e1d0f69a2"},
{file = "wrapt-1.15.0-cp36-cp36m-win32.whl", hash = "sha256:77d4c1b881076c3ba173484dfa53d3582c1c8ff1f914c6461ab70c8428b796c1"},
{file = "wrapt-1.15.0-cp36-cp36m-win_amd64.whl", hash = "sha256:077ff0d1f9d9e4ce6476c1a924a3332452c1406e59d90a2cf24aeb29eeac9420"},
{file = "wrapt-1.15.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5c5aa28df055697d7c37d2099a7bc09f559d5053c3349b1ad0c39000e611d317"},
{file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a8564f283394634a7a7054b7983e47dbf39c07712d7b177b37e03f2467a024e"},
{file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780c82a41dc493b62fc5884fb1d3a3b81106642c5c5c78d6a0d4cbe96d62ba7e"},
{file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e169e957c33576f47e21864cf3fc9ff47c223a4ebca8960079b8bd36cb014fd0"},
{file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b02f21c1e2074943312d03d243ac4388319f2456576b2c6023041c4d57cd7019"},
{file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f2e69b3ed24544b0d3dbe2c5c0ba5153ce50dcebb576fdc4696d52aa22db6034"},
{file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d787272ed958a05b2c86311d3a4135d3c2aeea4fc655705f074130aa57d71653"},
{file = "wrapt-1.15.0-cp37-cp37m-win32.whl", hash = "sha256:02fce1852f755f44f95af51f69d22e45080102e9d00258053b79367d07af39c0"},
{file = "wrapt-1.15.0-cp37-cp37m-win_amd64.whl", hash = "sha256:abd52a09d03adf9c763d706df707c343293d5d106aea53483e0ec8d9e310ad5e"},
{file = "wrapt-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdb4f085756c96a3af04e6eca7f08b1345e94b53af8921b25c72f096e704e145"},
{file = "wrapt-1.15.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:230ae493696a371f1dbffaad3dafbb742a4d27a0afd2b1aecebe52b740167e7f"},
{file = "wrapt-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63424c681923b9f3bfbc5e3205aafe790904053d42ddcc08542181a30a7a51bd"},
{file = "wrapt-1.15.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6bcbfc99f55655c3d93feb7ef3800bd5bbe963a755687cbf1f490a71fb7794b"},
{file = "wrapt-1.15.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c99f4309f5145b93eca6e35ac1a988f0dc0a7ccf9ccdcd78d3c0adf57224e62f"},
{file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b130fe77361d6771ecf5a219d8e0817d61b236b7d8b37cc045172e574ed219e6"},
{file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:96177eb5645b1c6985f5c11d03fc2dbda9ad24ec0f3a46dcce91445747e15094"},
{file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5fe3e099cf07d0fb5a1e23d399e5d4d1ca3e6dfcbe5c8570ccff3e9208274f7"},
{file = "wrapt-1.15.0-cp38-cp38-win32.whl", hash = "sha256:abd8f36c99512755b8456047b7be10372fca271bf1467a1caa88db991e7c421b"},
{file = "wrapt-1.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:b06fa97478a5f478fb05e1980980a7cdf2712015493b44d0c87606c1513ed5b1"},
{file = "wrapt-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2e51de54d4fb8fb50d6ee8327f9828306a959ae394d3e01a1ba8b2f937747d86"},
{file = "wrapt-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0970ddb69bba00670e58955f8019bec4a42d1785db3faa043c33d81de2bf843c"},
{file = "wrapt-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76407ab327158c510f44ded207e2f76b657303e17cb7a572ffe2f5a8a48aa04d"},
{file = "wrapt-1.15.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd525e0e52a5ff16653a3fc9e3dd827981917d34996600bbc34c05d048ca35cc"},
{file = "wrapt-1.15.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d37ac69edc5614b90516807de32d08cb8e7b12260a285ee330955604ed9dd29"},
{file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:078e2a1a86544e644a68422f881c48b84fef6d18f8c7a957ffd3f2e0a74a0d4a"},
{file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2cf56d0e237280baed46f0b5316661da892565ff58309d4d2ed7dba763d984b8"},
{file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7dc0713bf81287a00516ef43137273b23ee414fe41a3c14be10dd95ed98a2df9"},
{file = "wrapt-1.15.0-cp39-cp39-win32.whl", hash = "sha256:46ed616d5fb42f98630ed70c3529541408166c22cdfd4540b88d5f21006b0eff"},
{file = "wrapt-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:eef4d64c650f33347c1f9266fa5ae001440b232ad9b98f1f43dfe7a79435c0a6"},
{file = "wrapt-1.15.0-py3-none-any.whl", hash = "sha256:64b1df0f83706b4ef4cfb4fb0e4c2669100fd7ecacfb59e091fad300d4e04640"},
{file = "wrapt-1.15.0.tar.gz", hash = "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a"},
]
[[package]]
name = "zipp"
version = "3.17.0"
@@ -514,4 +1268,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p
[metadata]
lock-version = "2.0"
python-versions = ">=3.8,<3.9"
content-hash = "2ee72912250a8c96f04624c665fd1f86b222ac6561ae4f20bedb77160a8d4756"
content-hash = "e8ca19934d2ae7c8fbe0238a777e8d7b8882c86d38a700bdd0495b175f1458fe"

View File

@@ -1,6 +1,6 @@
[tool.poetry]
name = "statapp"
version = "0.4.1"
version = "0.10.0"
description = ""
authors = [
"Maxim Slipenko <statapp@maks1ms.addy.io>"
@@ -12,8 +12,14 @@ readme = "README.md"
python = ">=3.8,<3.9"
pre-commit = "^3.4.0"
pyinstaller = "^6.0.0"
pandas = "^2.0"
pyside2 = "^5.15.2.1"
pandas = { version = "^2", markers = "python_version < '3.9'" }
pylint = { version = "^2", markers = "python_version < '3.9'" }
# scipy = { version = "^1", markers = "python_version < '3.9'" }
# openpyxl = "^3.1.2"
sympy = "^1.12"
matplotlib = "^3.7.0"
pillow = "9.5"
[build-system]

View File

@@ -1,59 +0,0 @@
# -*- mode: python ; coding: utf-8 -*-
import sys
import typing
from pprint import pprint
if typing.TYPE_CHECKING:
from PyInstaller.building.api import COLLECT, EXE, MERGE, PYZ # noqa: F401
from PyInstaller.building.build_main import Analysis # noqa: F401
from PyInstaller.building.datastruct import TOC, Target, Tree # noqa: F401
from PyInstaller.building.osx import BUNDLE # noqa: F401
from PyInstaller.building.splash import Splash # noqa: F401
from PyInstaller.utils.hooks import copy_metadata
datas = [('statapp/ui/images/*', 'ui/images')]
datas += copy_metadata('statapp')
a = Analysis(
['statapp/__main__.py'],
pathex=[],
binaries=[],
datas=datas,
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
)
prev_binaries = set(a.binaries)
if sys.platform in ('linux', 'darwin'):
a.exclude_system_libraries(list_of_exceptions=[]) # glob expression
print('\n\nSTRIPPED SYSTEM LIBS')
pprint(sorted(set(prev_binaries) - set(a.binaries)))
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='statapp',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon='statapp/ui/images/logo.ico',
)

View File

@@ -1,4 +1,5 @@
# -*- mode: python ; coding: utf-8 -*-
import argparse
import sys
import typing
from pprint import pprint
@@ -12,6 +13,10 @@ if typing.TYPE_CHECKING:
from PyInstaller.utils.hooks import copy_metadata
parser = argparse.ArgumentParser()
parser.add_argument("--one-file", action="store_true")
options = parser.parse_args()
datas = [('statapp/ui/images/*', 'ui/images')]
datas += copy_metadata('statapp')
@@ -35,32 +40,69 @@ if sys.platform in ('linux', 'darwin'):
print('\n\nSTRIPPED SYSTEM LIBS')
pprint(sorted(set(prev_binaries) - set(a.binaries)))
LOCALES = ['ru', 'en']
def remove_unused_translation(item):
dest = str(item[0])
if not dest.startswith('PySide2/Qt/translations'):
return True
for l in LOCALES:
if l in dest:
return True
return False
a.datas = list(filter(remove_unused_translation, a.datas))
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=True,
name='statapp',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon='statapp/ui/images/logo.ico',
)
coll = COLLECT(
exe,
a.binaries,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='statapp',
)
if options.one_file:
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='statapp',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon='statapp/ui/images/logo.ico',
)
else:
exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=True,
name='statapp',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon='statapp/ui/images/logo.ico',
)
coll = COLLECT(
exe,
a.binaries,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='statapp',
)

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
# Copyright (c) 2024 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).
@@ -31,7 +31,8 @@ def main():
translator = QtCore.QTranslator(app)
locale = QtCore.QLocale.system().name()
path = QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.TranslationsPath)
translator.load('qt_%s' % locale, path)
translator.load(f'qt_{locale}', path)
translator.load(f'qtbase_{locale}', path)
app.installTranslator(translator)
window = MainWindow()

View File

@@ -0,0 +1,124 @@
# Copyright (c) 2023 Matthew Rocklin
# All rights reserved.
# This source code is distributed under the terms of the BSD license,
# which allows you to use, modify, and distribute it
# as long as you comply with the license terms.
# In addition, this code has been modified by Maxim Slipenko and
# is now also licensed under the GPL-3.0.
# See the GPL-3.0 license for details.
import itertools
from numpy import linalg, zeros, ones, hstack, asarray
from sympy import symbols, Mul, Add, S
def basisVector(n, i):
""" Return an array like [0, 0, ..., 1, ..., 0, 0]
>>> from statapp._vendor.multipolyfit import basisVector
>>> basis_vector(3, 1)
array([0, 1, 0])
>>> basisVector(5, 4)
array([0, 0, 0, 0, 1])
"""
x = zeros(n, dtype=int)
x[i] = 1
return x
def asTall(x):
""" Turns a row vector into a column vector """
return x.reshape(x.shape + (1,))
def multipolyfit(xs, y, deg, full=False, modelOut=False, powersOut=False):
# pylint: disable-msg=too-many-locals
"""
Least squares multivariate polynomial fit
Fit a polynomial like ``y = a**2 + 3a - 2ab + 4b**2 - 1``
with many covariates a, b, c, ...
Parameters
----------
xs : array_like, shape (M, k)
x-coordinates of the k covariates over the M sample points
y : array_like, shape(M,)
y-coordinates of the sample points.
deg : int
Degree o fthe fitting polynomial
modelOut : bool (defaults to True)
If True return a callable function
If False return an array of coefficients
powersOut : bool (defaults to False)
Returns the meaning of each of the coefficients in the form of an
iterator that gives the powers over the inputs and 1
For example if xs corresponds to the covariates a,b,c then the array
[1, 2, 1, 0] corresponds to 1**1 * a**2 * b**1 * c**0
See Also
--------
numpy.polyfit
"""
# pylin
y = asarray(y).squeeze()
# rows = y.shape[0]
xs = asarray(xs)
numCovariates = xs.shape[1]
xs = hstack((ones((xs.shape[0], 1), dtype=xs.dtype) , xs))
generators = [basisVector(numCovariates + 1, i)
for i in range(numCovariates+1)]
# All combinations of degrees
powers = [sum(x) for x in itertools.combinations_with_replacement(generators, deg)]
# Raise data to specified degree pattern, stack in order
a = hstack(asarray([asTall((xs ** p).prod(1)) for p in powers]))
result = linalg.lstsq(a, y, rcond=None)
beta = result[0]
if modelOut:
return mkModel(beta, powers)
if powersOut:
return beta, powers
if full:
return result, powers, a
return beta
def mkModel(beta, powers):
""" Create a callable python function out of beta/powers from multipolyfit
This function is callable from within multipolyfit using the model_out flag
"""
# Create a function that takes in many x values
# and returns an approximate y value
def model(*args):
numCovariates = len(powers[0]) - 1
if len(args) != numCovariates:
raise ValueError(f"Expected {numCovariates} inputs")
xs = asarray((1,) + args)
return sum(coeff * (xs**p).prod()
for p, coeff in zip(powers, beta))
return model
def mkSympyFunction(beta, powers):
terms = getTerms(powers)
return Add(*[coeff * term for term, coeff in zip(terms, beta)])
def getTerms(powers):
numCovariates = len(powers[0])
xs = (S.One,) + symbols(f'x1:{numCovariates}')
terms = [Mul(*[x ** deg for x, deg in zip(xs, power)]) for power in powers]
return terms

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
# Copyright (c) 2024 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).
@@ -18,11 +18,12 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import sys
from PySide2.QtGui import QMovie
from PySide2.QtWidgets import QMainWindow
from statapp.ui.ui_about_window import Ui_AboutWindow
from statapp.utils import resource_path
from statapp.utils import resourcePath, addIcon
if sys.version_info < (3, 8):
import importlib_metadata
@@ -38,8 +39,8 @@ class AboutWindow(QMainWindow):
self.ui = Ui_AboutWindow()
self.ui.setupUi(self)
image_path = resource_path('ui/images/sticker.gif')
movie = QMovie(image_path)
gifPath = resourcePath('ui/images/sticker.gif')
movie = QMovie(gifPath)
self.ui.labelgif.setMovie(movie)
movie.start()
self.movie = movie
@@ -47,3 +48,5 @@ class AboutWindow(QMainWindow):
version = importlib_metadata.version(__package__ or __name__)
self.ui.versionLabel.setText(f"Версия: {version}")
addIcon(self)

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
# Copyright (c) 2024 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).
@@ -17,35 +17,158 @@
# 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 dataclasses import dataclass
import numpy as np
import pandas as pd
import sympy as sp
from statapp._vendor.multipolyfit import multipolyfit, getTerms
DIRECT_LINK = 0
INDIRECT_LINK = 1
def generate_x_values(mean, std, typeConnection, y):
yMean = np.mean(y)
def generateYValues(mean, std, count):
return np.random.normal(mean, std, size=(count, 1))
def generateXValues(mean, std, typeConnection, yColumn):
yMean = np.mean(yColumn)
values = []
for cur_y in y:
for y in yColumn:
raz = np.abs(mean - np.random.normal(mean, std))
if typeConnection == INDIRECT_LINK:
raz *= -1
if cur_y > yMean:
if y > yMean:
x = mean + raz
elif cur_y < yMean:
elif y < yMean:
x = mean - raz
else:
x = mean
values.append(x)
return np.array(values)
res = np.array(values)
return res.reshape(len(res), 1)
def variance_analysis(data):
def varianceAnalysis(data):
return np.array([
[np.mean(col), np.std(col), np.min(col), np.max(col)] for col in data.T
])
def correlation_analysis(data):
def correlationAnalysis(data):
return pd.DataFrame(data).corr().to_numpy()
@dataclass()
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 commonPolynom(inputData, deg) -> RegressionResult:
x = inputData[:, 1:]
y = inputData[:, 0]
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
# 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 out, mse[0], scaledResidualVariance, rSquared, fStatistic
def prediction(inputData, result: RegressionResult):
inputs = inputData[:, 1:]
outputs = inputData[:, 0]
params = result.paramsAndImportance[:, 0]
expr = sp.sympify(' '.join(
[
f'{param}' if m == 'c' else f' + ({param}) * {m}'
for param, m in zip(params, result.monomials)
]
))
results = []
for y, xValues in zip(outputs, inputs):
subsDict = dict(zip(expr.free_symbols, xValues))
predictedResult = expr.subs(subsDict)
difference = predictedResult - y
results.append([y, predictedResult, difference, 0.0])
results = np.array(results, dtype=np.float32)
# Расчет среднего значения и стандартного отклонения разностей
meanDifference = np.mean(results[:, 2])
stdDifference = np.std(results[:, 2])
# Установка флага 1.0, если разность выходит за пределы 3 стандартных отклонений
for row in results:
if abs(row[2] - meanDifference) > 3 * stdDifference:
row[3] = 1.0
return results

63
statapp/combo_delegate.py Normal file
View File

@@ -0,0 +1,63 @@
#
# Copyright (c) 2024 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 PySide2 import QtCore
from PySide2.QtWidgets import QComboBox, QItemDelegate
class ComboDelegate(QItemDelegate):
commitData = QtCore.Signal(object)
"""
A delegate that places a fully functioning QComboBox in every
cell of the column to which it's applied
"""
def __init__(self, parent, objects, objectNames):
"""
Constructoe
:param parent: QTableView parent object
:param objects: List of objects to set. i.e. [True, False]
:param objectNames: List of Object names to display. i.e. ['True', 'False']
"""
QItemDelegate.__init__(self, parent)
# objects to sent to the model associated to the combobox. i.e. [True, False]
self.objects = objects
# object description to display in the combobox. i.e. ['True', 'False']
self.objectNames = objectNames
@QtCore.Slot()
def currentIndexChanged(self):
self.commitData.emit(self.sender())
def createEditor(self, parent, option, index):
combo = QComboBox(parent)
combo.addItems(self.objectNames)
combo.currentIndexChanged.connect(self.currentIndexChanged)
return combo
def setEditorData(self, editor, index):
editor.blockSignals(True)
val = index.model().data(index, role=QtCore.Qt.DisplayRole)
idx = self.objects.index(val)
editor.setCurrentIndex(idx)
editor.blockSignals(False)
def setModelData(self, editor, model, index):
model.setData(index, self.objects[editor.currentIndex()], QtCore.Qt.EditRole)

20
statapp/constants.py Normal file
View File

@@ -0,0 +1,20 @@
#
# Copyright (c) 2024 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

@@ -1,5 +1,5 @@
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
# Copyright (c) 2024 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).
@@ -17,21 +17,37 @@
# 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 import QtCore
from PySide2.QtCore import QSize
from PySide2.QtGui import QIcon
from PySide2.QtWidgets import QDialog, QHeaderView
from statapp.calculations import correlation_analysis
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
from statapp.utils import resourcePath
class СorrelationAnalysisWindow(QDialog):
class CorrelationAnalysisWindow(QDialog):
def __init__(self, data):
super().__init__()
self.ui = Ui_CorrelationAnalysisWindow()
self.ui.setupUi(self)
res = correlation_analysis(data)
self.model = CorrelationAnalysisModel(res.round(2))
res = correlationAnalysis(data)
self.model = CorrelationAnalysisModel(res.round(NUMBERS_PRECISION))
self.ui.tableView.setModel(self.model)
self.ui.tableView.setVerticalHeader(
MathTexHeaderView(self.ui.tableView)
)
self.ui.tableView.setHorizontalHeader(
MathTexHeaderView(self.ui.tableView,orientation=QtCore.Qt.Horizontal)
)
header = self.ui.tableView.horizontalHeader()
header.setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
icon = QIcon()
icon.addFile(resourcePath("ui/images/logo.ico"), QSize(), QIcon.Normal, QIcon.Off)
self.setWindowIcon(icon)

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
# Copyright (c) 2024 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).
@@ -22,7 +22,7 @@ from PySide2.QtWidgets import QDialog
from statapp.ui.ui_generate_factor_window import Ui_GenerateFactorWindow
from statapp.models.combobox_model import ComboBoxModel
from statapp.utils import addIcon
DIRECT_LINK = 0
INDIRECT_LINK = 1
@@ -43,6 +43,8 @@ class GenerateFactorWindow(QDialog):
self.ui.setupUi(self)
self.ui.typeComboBox.setModel(self._typeComboBox)
addIcon(self)
@Slot()
def on_generatePushButton_clicked(self):
self.typeConnection = self._typeComboBox.rawData(self.ui.typeComboBox.currentIndex())[0]

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
# Copyright (c) 2024 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).
@@ -21,6 +21,7 @@ from PySide2.QtCore import Slot
from PySide2.QtWidgets import QDialog
from statapp.ui.ui_generate_window import Ui_GenerateWindow
from statapp.utils import addIcon
class GenerateWindow(QDialog):
@@ -32,6 +33,9 @@ class GenerateWindow(QDialog):
self.ui = Ui_GenerateWindow()
self.ui.setupUi(self)
addIcon(self)
@Slot()
def on_generatePushButton_clicked(self):

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
# Copyright (c) 2024 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).
@@ -18,20 +18,25 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import numpy as np
from PySide2.QtCore import Slot, QSize
from PySide2.QtGui import QIcon
from PySide2.QtWidgets import QMainWindow, QMessageBox, QAction
from PySide2 import QtCore
from PySide2.QtCore import Slot
from PySide2.QtWidgets import QMainWindow, QMessageBox
from statapp.calculations import generate_x_values
from statapp.calculations import generateXValues, generateYValues
from statapp.constants import NUMBERS_PRECISION
from statapp.generate_factor_window import GenerateFactorWindow
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.polynoms.squared_polynom_window import SquaredPolynomWindow
from statapp.ui.ui_main_window import Ui_MainWindow
from statapp.utils import resource_path, buildMessageBox
from statapp.utils import buildMessageBox, addIcon, FloatDelegate
from statapp.variance_analysis import VarianceAnalysisWindow
from statapp.correlation_analysis import СorrelationAnalysisWindow
from statapp.correlation_analysis import CorrelationAnalysisWindow
from statapp.polynoms.transform_polynom_window import TransformPolynomWindow
class MainWindow(QMainWindow):
@@ -41,26 +46,69 @@ class MainWindow(QMainWindow):
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
icon = QIcon()
icon.addFile(resource_path("ui/images/logo.ico"), QSize(), QIcon.Normal, QIcon.Off)
addIcon(self)
self.ui.generateXaction.setEnabled(False)
self.ui.varianceAnalysisAction.setEnabled(False)
self.ui.correlationAnalisisAction.setEnabled(False)
self.mainActions = [
self.ui.varianceAnalysisAction,
self.ui.correlationAnalisisAction,
self.ui.linearPolynomAction,
self.ui.squaredPolynomAction,
self.ui.transformPolynomAction,
]
self.aboutWindow = None
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)
)
self.model.layoutChanged.connect(self.updateActionsEnabled)
self.updateActionsEnabled()
#
# Для быстрой отладки
# n = 10
# y = generateYValues(100, 5, n)
# x1 = generateXValues(20, 2, 0, y)
# x2 = generateXValues(10, 1, 0, y)
# self.model.updateAllData(np.concatenate([y, x1, x2], axis=1))
def updateActionsEnabled(self):
data = self.model.getData()
# есть только отклик
if data.shape[1] == 1:
self.ui.generateXaction.setEnabled(True)
self.setEnabledMainActions(False)
# есть отклик и фактор(ы)
elif data.shape[1] > 1:
self.ui.generateXaction.setEnabled(True)
self.setEnabledMainActions(True)
else:
self.ui.generateXaction.setEnabled(False)
self.setEnabledMainActions(False)
def setEnabledMainActions(self, enabled):
for action in self.mainActions:
action.setEnabled(enabled)
@Slot()
def on_openfileaction_triggered(self):
current_data = self.model.getData()
currentData = self.model.getData()
data = np.array([])
if current_data.size > 1:
if currentData.size > 1:
file = ''
if self.fileModel.file_name:
file = '\nФайл сохранения: ' + self.fileModel.file_name
if self.fileModel.fileName:
file = '\nФайл сохранения: ' + self.fileModel.fileName
msgBox = buildMessageBox \
('Сохранение данных',
@@ -72,6 +120,11 @@ class MainWindow(QMainWindow):
reply = msgBox.exec_()
if reply == QMessageBox.StandardButton.Yes:
self.fileModel.saveFile(self.model.getData())
data = self.fileModel.loadFile()
if data is not None and data.shape[0] > 0:
self.model.updateAllData(data)
self.isDataChanged = False
elif reply == QMessageBox.StandardButton.Cancel:
return
else:
@@ -85,18 +138,6 @@ class MainWindow(QMainWindow):
self.model.updateAllData(data)
self.isDataChanged = False
if data.shape[1] == 1:
self.ui.generateXaction.setEnabled(True)
self.ui.varianceAnalysisAction.setEnabled(False)
self.ui.correlationAnalisisAction.setEnabled(False)
elif data.shape[1] > 1:
self.ui.generateXaction.setEnabled(True)
self.ui.varianceAnalysisAction.setEnabled(True)
self.ui.correlationAnalisisAction.setEnabled(True)
else:
self.ui.generateXaction.setEnabled(False)
self.ui.varianceAnalysisAction.setEnabled(False)
self.ui.correlationAnalisisAction.setEnabled(False)
@Slot()
def on_savefileaction_triggered(self):
@@ -110,11 +151,11 @@ class MainWindow(QMainWindow):
@Slot()
def on_generateYaction_triggered(self):
gw = GenerateWindow()
if gw.exec():
y = np.random.normal(gw.mat, gw.deviation, size=(gw.count, 1))
self.model.updateAllData(y.round(2))
y = generateYValues(gw.mat, gw.deviation, gw.count)
self.model.updateAllData(y.round(NUMBERS_PRECISION))
self.isDataChanged = True
self.ui.generateXaction.setEnabled(True)
@Slot()
def on_generateXaction_triggered(self):
@@ -123,25 +164,15 @@ class MainWindow(QMainWindow):
if gfw.exec():
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)
xValues = generateXValues(gfw.mat, gfw.deviation, gfw.typeConnection, y)
data = np.concatenate((data, xValues.round(NUMBERS_PRECISION)), axis=1)
self.model.updateAllData(data)
self.ui.varianceAnalysisAction.setEnabled(True)
self.ui.correlationAnalisisAction.setEnabled(True)
self.isDataChanged = True
@Slot()
def on_aboutmenuaction_triggered(self):
global about_window
about_window = AboutWindow()
icon = QIcon()
icon.addFile(resource_path("ui/images/logo.ico"), QSize(), QIcon.Normal, QIcon.Off)
about_window.setWindowIcon(icon)
about_window.show()
self.aboutWindow = AboutWindow()
self.aboutWindow.show()
@Slot()
def on_varianceAnalysisAction_triggered(self):
@@ -150,14 +181,29 @@ class MainWindow(QMainWindow):
@Slot()
def on_correlationAnalisisAction_triggered(self):
dw = СorrelationAnalysisWindow(self.model.getData())
dw = CorrelationAnalysisWindow(self.model.getData())
dw.exec()
@Slot()
def on_linearPolynomAction_triggered(self):
dw = LinearPolynomWindow(self.model.getData())
dw.exec()
@Slot()
def on_squaredPolynomAction_triggered(self):
dw = SquaredPolynomWindow(self.model.getData())
dw.exec()
@Slot()
def on_transformPolynomAction_triggered(self):
dw = TransformPolynomWindow(self.model.getData())
dw.exec()
def closeEvent(self, event):
if self.isDataChanged:
file = ''
if self.fileModel.file_name:
file = '\nФайл сохранения: ' + self.fileModel.file_name
if self.fileModel.fileName:
file = '\nФайл сохранения: ' + self.fileModel.fileName
msgBox = buildMessageBox \
('Завершение работы',

View File

@@ -0,0 +1,107 @@
#
# Copyright (c) 2024 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/>.
#
import matplotlib.pyplot as plt
import matplotlib as mpl
import sympy
from PySide2 import QtCore, QtGui
from PySide2.QtCore import Qt
from PySide2.QtWidgets import QHeaderView, QStyleOptionHeader, QStyle
from matplotlib.backends.backend_agg import FigureCanvasAgg
# Основано на https://stackoverflow.com/questions/32035251/
plt.rc('mathtext', fontset='cm')
def mathTexToQPixMap(mathTex, fs):
# ---- set up a mpl figure instance ----
fig = mpl.figure.Figure()
fig.patch.set_facecolor('none')
fig.set_canvas(FigureCanvasAgg(fig))
renderer = fig.canvas.get_renderer()
# ---- plot the mathTex expression ----
ax = fig.add_axes([0, 0, 1, 1])
ax.axis('off')
ax.patch.set_facecolor('none')
t = ax.text(0, 0, f'${mathTex}$', ha='left', va='bottom', fontsize=fs)
# ---- fit figure size to text artist ----
fWidth, fHeight = fig.get_size_inches()
figBBox = fig.get_window_extent(renderer)
textBBox = t.get_window_extent(renderer)
tightFWidth = textBBox.width * fWidth / figBBox.width
tightFHeight = textBBox.height * fHeight / figBBox.height
fig.set_size_inches(tightFWidth, tightFHeight)
# ---- convert mpl figure to QPixmap ----
buf, size = fig.canvas.print_to_buffer()
return QtGui.QPixmap(
QtGui.QImage.rgbSwapped(
QtGui.QImage(
buf, size[0], size[1], QtGui.QImage.Format_ARGB32
)
)
)
class CacheQPixMap(dict):
def get(self, __key):
v = super().get(__key)
if v is None:
v = mathTexToQPixMap(sympy.latex(sympy.sympify(__key)), 14)
super().__setitem__(__key, v)
return v
class MathTexHeaderView(QHeaderView):
def __init__(self, view, orientation=QtCore.Qt.Vertical):
super().__init__(orientation, view)
if orientation == QtCore.Qt.Vertical:
self.setStyleSheet(
"QHeaderView::section { padding-left: 15px; padding-right: 15px }"
)
self.converter = CacheQPixMap()
def paintSection(self, painter, rect, logicalIndex):
opt = QStyleOptionHeader()
self.initStyleOption(opt)
opt.rect = rect
opt.section = logicalIndex
opt.text = ""
mousePos = self.mapFromGlobal(QtGui.QCursor.pos())
if rect.contains(mousePos):
opt.state |= QStyle.State_MouseOver
painter.save()
self.style().drawControl(QStyle.CE_Header, opt, painter, self)
painter.restore()
data = self.model().headerData(logicalIndex, self.orientation(), Qt.DisplayRole)
if data:
qPixMap = self.converter.get(data)
xPix = (rect.width() - qPixMap.size().width()) / 2. + rect.x()
yPix = (rect.height() - qPixMap.size().height()) / 2. + rect.y()
rect = QtCore.QRect(xPix, yPix, qPixMap.size().width(),
qPixMap.size().height())
painter.drawPixmap(rect, qPixMap)

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
# Copyright (c) 2024 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
# Copyright (c) 2024 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).
@@ -20,7 +20,7 @@
from PySide2.QtCore import QModelIndex, Qt
from statapp.models.ro_table_model import ROTableModel
from statapp.models.utils import yx_header
from statapp.models.utils import yxHeader
class CorrelationAnalysisModel(ROTableModel):
@@ -28,15 +28,12 @@ class CorrelationAnalysisModel(ROTableModel):
super().__init__(data)
def getHorizontalHeader(self):
return yx_header(self.columnCount(QModelIndex()))
return yxHeader(self.columnCount(QModelIndex()))
def getVerticalHeader(self):
return yx_header(self.rowCount(QModelIndex()))
return yxHeader(self.rowCount(QModelIndex()))
def data(self, index, role):
if role == Qt.DisplayRole:
if (index.column() <= index.row()):
return float(self._data[index.row(), index.column()])
else:
None
if role == Qt.DisplayRole and index.column() <= index.row():
return super().data(index, role)
return None

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
# Copyright (c) 2024 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).
@@ -43,7 +43,7 @@ class EditableTableModel(ROTableModel):
return False
def data(self, index, role):
if role == Qt.DisplayRole or role == Qt.EditRole:
return float(self._data[index.row(), index.column()])
if role in (Qt.DisplayRole, Qt.EditRole):
return super().data(index, Qt.DisplayRole)
return None

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
# Copyright (c) 2024 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).
@@ -20,34 +20,66 @@
import numpy as np
from PySide2.QtWidgets import QFileDialog, QMessageBox
from statapp.constants import NUMBERS_PRECISION
from statapp.utils import buildMessageBox
class FileSLCModel:
def __init__(self):
super().__init__()
self.file_name = None
self.fileName = None
def saveFile(self, data):
if not self.file_name:
self.file_name, _ = QFileDialog.getSaveFileName(None, "Сохранить файл", "", "Text Files (*.txt);;CSV Files (*.csv)")
if self.file_name:
np.savetxt(self.file_name, data, delimiter=",")
return True
# pylint: disable=duplicate-code
if self.fileName:
file = '\nФайл сохранения: ' + self.fileName
msgBox = buildMessageBox \
('Сохранение данных',
"Сохранить данные в текущий файл?" + file,
QMessageBox.Question,
QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel,
QMessageBox.Cancel)
reply = msgBox.exec_()
if reply == QMessageBox.StandardButton.Yes:
np.savetxt(self.fileName, data, delimiter=",", fmt='%10.5f')
return True
if reply == QMessageBox.StandardButton.No:
self.fileName, _ = QFileDialog.getSaveFileName(
None, "Сохранить файл", "", "Text Files (*.txt);;CSV Files (*.csv)"
)
if self.fileName:
np.savetxt(self.fileName, data, delimiter=",", fmt='%10.5f')
return True
else:
self.fileName, _ = QFileDialog.getSaveFileName(
None, "Сохранить файл", "", "Text Files (*.txt);;CSV Files (*.csv)"
)
if self.fileName:
np.savetxt(self.fileName, data, delimiter=",", fmt=f"%.{NUMBERS_PRECISION}f")
return True
return False
def loadFile(self):
self.file_name, _ = QFileDialog.getOpenFileName(None, "Загрузить файл", "", "Files (*.txt *.csv)")
if self.file_name:
self.fileName, _ = QFileDialog.getOpenFileName(
None, "Загрузить файл", "", "Files (*.txt *.csv)"
)
if self.fileName:
try:
content = np.genfromtxt(self.file_name, delimiter=',', invalid_raise=True, ndmin=2)
except ValueError as e:
content = np.genfromtxt(self.fileName, delimiter=',', invalid_raise=True, ndmin=2)
except ValueError:
QMessageBox.warning \
(None,
'Ошибка',
"Ошибка чтения файла!\nФайл нельзя открыть или файл неверного формата")
self.file_name = None
self.fileName = None
return None
return content
return None
def closeFile(self):
self.file_name = None
pass
self.fileName = None

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
# Copyright (c) 2024 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).
@@ -18,10 +18,10 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import numpy as np
from PySide2.QtCore import Qt, QModelIndex
from PySide2.QtCore import QModelIndex
from statapp.models.editable_table_model import EditableTableModel
from statapp.models.utils import yx_header
from statapp.models.utils import yxHeader
class InputValuesModel(EditableTableModel):
@@ -29,7 +29,7 @@ class InputValuesModel(EditableTableModel):
super().__init__(data)
def getHorizontalHeader(self):
return yx_header(self.columnCount(QModelIndex()))
return yxHeader(self.columnCount(QModelIndex()))
def getY(self):
return self._data[:, 0]

View File

@@ -0,0 +1,33 @@
#
# Copyright (c) 2024 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 PySide2.QtCore import Qt
from statapp.models.ro_table_model import ROTableModel
class PreditionTableModel(ROTableModel):
def getHorizontalHeader(self):
return ['Отклик', 'Прогноз', 'Отклонение', '1-3 сигмовые зоны']
def data(self, index, role):
if role == Qt.DisplayRole and index.column() == 3:
value = super().data(index, role)
return 'x' if value == 1 else ''
return super().data(index, role)

View File

@@ -0,0 +1,34 @@
#
# Copyright (c) 2024 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 RegressionResult
from statapp.models.ro_table_model import ROTableModel
class RegressionResultModel(ROTableModel):
def __init__(self, result: RegressionResult):
data = result.paramsAndImportance
super().__init__(data)
self._monomials = result.monomials
def getHorizontalHeader(self):
return ['Коэффициент регрессии', 'Коэффициент значимости']
def getVerticalHeader(self):
return self._monomials

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
# Copyright (c) 2024 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).
@@ -17,12 +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/>.
#
import PySide2
import numpy as np
from PySide2 import QtCore
from PySide2.QtCore import Qt
from statapp.utils import safe_list_get
from statapp.utils import safeListGet
class ROTableModel(QtCore.QAbstractTableModel):
@@ -55,7 +54,7 @@ class ROTableModel(QtCore.QAbstractTableModel):
def headerData(self, section: int, orientation: Qt.Orientation, role: int = ...):
if role == Qt.DisplayRole:
return safe_list_get(self._headers[orientation](), section, None)
return safeListGet(self._headers[orientation](), section, None)
return None

View File

@@ -0,0 +1,74 @@
#
# Copyright (c) 2024 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/>.
#
import numpy as np
from PySide2.QtCore import Qt
from statapp.models.editable_table_model import EditableTableModel
from statapp.models.regression_result_model import RegressionResultModel
def defaultX(x):
return x
TRANSFORMS = {
'-': defaultX,
'sin(x)': np.sin,
'cos(x)': np.cos,
'log(x)': np.log,
'exp(x)': np.exp,
}
class TransformPolynomModel(RegressionResultModel, EditableTableModel):
def __init__(self, result):
self._monomials = None
super().__init__(result)
n = result.paramsAndImportance.shape[0]
self._transforms = ['-'] * n
def columnCount(self, index):
return 3
def updateAllData(self, data):
d = data.paramsAndImportance
self._monomials = data.monomials
super().updateAllData(d)
def flags(self, index):
if index.column() == 0 and index.row() != 0:
return EditableTableModel.flags(self, index)
return RegressionResultModel.flags(self, index)
def data(self, index, role):
if role == Qt.DisplayRole and index.column() == 0:
return self._transforms[index.row()]
return super().data(index, role)
def setData(self, index, value, role):
if role == Qt.EditRole and index.column() == 0:
self._transforms[index.row()] = value
topLeftIndex = self.createIndex(index.row(), 0)
bottomRightIndex = self.createIndex(index.row(), 0)
self.dataChanged.emit(topLeftIndex, bottomRightIndex)
return True
return super().setData(index, value, role)
def getHorizontalHeader(self):
return ['Преобразования'] + super().getHorizontalHeader()

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
# Copyright (c) 2024 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).
@@ -17,5 +17,5 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
def yx_header(count):
return ['Y'] + [f'X{i}' for i in range(1, count)]
def yxHeader(count):
return ['y'] + [f'x{i}' for i in range(1, count)]

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
# Copyright (c) 2024 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).
@@ -20,7 +20,7 @@
from PySide2.QtCore import QModelIndex
from statapp.models.ro_table_model import ROTableModel
from statapp.models.utils import yx_header
from statapp.models.utils import yxHeader
class VarianceAnalysisModel(ROTableModel):
@@ -31,4 +31,4 @@ class VarianceAnalysisModel(ROTableModel):
return ['Мат. ожидание', 'Среднекв. отклонение', 'Минимум', 'Максимум']
def getVerticalHeader(self):
return yx_header(self.rowCount(QModelIndex()))
return yxHeader(self.rowCount(QModelIndex()))

View File

@@ -0,0 +1,27 @@
#
# Copyright (c) 2024 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__(data, result, "Линейный полином")

View File

@@ -0,0 +1,89 @@
#
# Copyright (c) 2024 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/>.
#
import numpy as np
from PySide2.QtWidgets import QDialog, QHeaderView
import matplotlib
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg
from matplotlib.figure import Figure
from statapp.calculations import prediction
from statapp.mathtex_header_view import MathTexHeaderView
from statapp.models.prediction_table_model import PreditionTableModel
from statapp.models.regression_result_model import RegressionResultModel
from statapp.ui.ui_polynom_window import Ui_PolynomWindow
from statapp.utils import addIcon, FloatDelegate
matplotlib.use('Qt5Agg')
class MplCanvas(FigureCanvasQTAgg):
def __init__(self, parent=None, width=5, height=4, dpi=100):
fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = fig.add_subplot()
super().__init__(fig)
class PolynomWindow(QDialog):
def __init__(self, data, result, windowTitle):
super().__init__()
self.ui = Ui_PolynomWindow()
self.ui.setupUi(self)
addIcon(self)
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))
predictionResult = prediction(data, result)
self.predictionModel = PreditionTableModel(predictionResult)
self.ui.predictionTableView.setModel(self.predictionModel)
header = self.ui.predictionTableView.horizontalHeader()
header.setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
sc = MplCanvas(self, width=5, height=4, dpi=100)
xAxes = np.array(range(len(data[:, 0])))
realY = predictionResult[:, 0]
calculatedY = predictionResult[:, 1]
print(xAxes)
print(realY)
print(calculatedY)
sc.axes.scatter(xAxes, realY)
# xnew = np.linspace(xAxes.min(), xAxes.max(), 300)
# gfg = scipy.interpolate.make_interp_spline(xAxes, y, k=3)
# y_new = gfg(xnew)
sc.axes.plot(xAxes, calculatedY)
self.ui.plotContainer.addWidget(sc)

View File

@@ -0,0 +1,27 @@
#
# Copyright (c) 2024 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 squaredPolynom
from statapp.polynoms.polynom_window import PolynomWindow
class SquaredPolynomWindow(PolynomWindow):
def __init__(self, data):
result = squaredPolynom(data)
super().__init__(data, result, "Квадратичный полином")

View File

@@ -0,0 +1,114 @@
#
# Copyright (c) 2024 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/>.
#
import numpy as np
from PySide2.QtCore import Qt
from PySide2.QtWidgets import QDialog, QHeaderView
from statapp.calculations import linearPolynom, prediction
from statapp.combo_delegate import ComboDelegate
from statapp.mathtex_header_view import MathTexHeaderView
from statapp.models.prediction_table_model import PreditionTableModel
from statapp.models.transform_polynom_model import TransformPolynomModel, TRANSFORMS
from statapp.polynoms.polynom_window import MplCanvas
from statapp.ui.ui_polynom_window import Ui_PolynomWindow
from statapp.utils import addIcon
class TransformPolynomWindow(QDialog):
def __init__(self, data):
super().__init__()
self.ui = Ui_PolynomWindow()
self.ui.setupUi(self)
addIcon(self)
self.setWindowTitle("Преобразования")
self.data = data
result = linearPolynom(data)
predictionResult = prediction(data, result)
self.predictionModel = PreditionTableModel(predictionResult)
self.ui.predictionTableView.setModel(self.predictionModel)
header = self.ui.predictionTableView.horizontalHeader()
header.setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
self.sc = MplCanvas(self, width=5, height=4, dpi=100)
xAxes = np.array(range(len(data[:, 0])))
realY = predictionResult[:, 0]
calculatedY = predictionResult[:, 1]
self.sc.axes.scatter(xAxes, realY)
self.sc.axes.plot(xAxes, calculatedY)
self.ui.plotContainer.addWidget(self.sc)
# Создание столбца из нулей
zeroCol = np.zeros((result.paramsAndImportance.shape[0], 1))
# Добавление столбца к исходному массиву
result.paramsAndImportance = np.column_stack((zeroCol, result.paramsAndImportance))
# self.ui.tableView.setItemDelegate(FloatDelegate())
self.ui.tableView.setItemDelegate(
ComboDelegate(
self.ui.tableView,
list(TRANSFORMS.keys()),
list(TRANSFORMS.keys()),
)
)
self.model = TransformPolynomModel(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))
self.ui.scaledResidualVarianceValueLabel.setText(str(result.scaledResidualVariance))
self.ui.fStatisticValueLabel.setText(str(result.fStatistic))
self.ui.rSquaredValueLabel.setText(str(result.scaledResidualVariance))
self.model.dataChanged.connect(self.on_data_changed)
def on_data_changed(self):
data = np.copy(self.data)
print(len(data[0:]))
for i in range(len(data[0:])):
for j in range(1, len(data[i])):
tr = self.model.data(self.model.createIndex(j, 0), Qt.DisplayRole)
data[i][j] = TRANSFORMS[tr](data[i][j])
self.rebuildData(data)
def rebuildData(self, data):
result = linearPolynom(data)
predictionResult = prediction(data, result)
self.predictionModel.updateAllData(predictionResult)
self.ui.plotContainer.removeWidget(self.sc)
self.sc = MplCanvas(self, width=5, height=4, dpi=100)
xAxes = np.array(range(len(data[:, 0])))
realY = predictionResult[:, 0]
calculatedY = predictionResult[:, 1]
self.sc.axes.scatter(xAxes, realY)
self.sc.axes.plot(xAxes, calculatedY)
self.ui.plotContainer.addWidget(self.sc)
zeroCol = np.zeros((result.paramsAndImportance.shape[0], 1))
result.paramsAndImportance = np.column_stack((zeroCol, result.paramsAndImportance))
self.model.updateAllData(result)
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

@@ -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

@@ -69,6 +69,9 @@
<property name="title">
<string>Моделирование</string>
</property>
<addaction name="linearPolynomAction"/>
<addaction name="squaredPolynomAction"/>
<addaction name="transformPolynomAction"/>
</widget>
<widget class="QMenu" name="helpmenu">
<property name="title">
@@ -123,6 +126,21 @@
<string>Корреляционный анализ</string>
</property>
</action>
<action name="linearPolynomAction">
<property name="text">
<string>Линейный полином</string>
</property>
</action>
<action name="squaredPolynomAction">
<property name="text">
<string>Квадратичный полином</string>
</property>
</action>
<action name="transformPolynomAction">
<property name="text">
<string>Преобразования</string>
</property>
</action>
</widget>
<resources/>
<connections/>

View File

@@ -0,0 +1,139 @@
<?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>537</width>
<height>444</height>
</rect>
</property>
<property name="windowTitle">
<string>Полином</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="6">
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="model">
<attribute name="title">
<string>Модель</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="3">
<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="2" column="3">
<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>
<widget class="QWidget" name="prediction">
<attribute name="title">
<string>Прогноз</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QTableView" name="predictionTableView">
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>График</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
<layout class="QGridLayout" name="plotContainer"/>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
# Copyright (c) 2024 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
# Copyright (c) 2024 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
# Copyright (c) 2024 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).
@@ -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

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
# Copyright (c) 2024 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).
@@ -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,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
# Copyright (c) 2024 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).
@@ -54,6 +54,12 @@ class Ui_MainWindow(object):
self.varianceAnalysisAction.setObjectName(u"varianceAnalysisAction")
self.correlationAnalisisAction = QAction(MainWindow)
self.correlationAnalisisAction.setObjectName(u"correlationAnalisisAction")
self.linearPolynomAction = QAction(MainWindow)
self.linearPolynomAction.setObjectName(u"linearPolynomAction")
self.squaredPolynomAction = QAction(MainWindow)
self.squaredPolynomAction.setObjectName(u"squaredPolynomAction")
self.transformPolynomAction = QAction(MainWindow)
self.transformPolynomAction.setObjectName(u"transformPolynomAction")
self.centralwidget = QWidget(MainWindow)
self.centralwidget.setObjectName(u"centralwidget")
self.gridLayout = QGridLayout(self.centralwidget)
@@ -101,6 +107,9 @@ class Ui_MainWindow(object):
self.generatemenu.addAction(self.generateXaction)
self.analyzemenu.addAction(self.varianceAnalysisAction)
self.analyzemenu.addAction(self.correlationAnalisisAction)
self.modelmenu.addAction(self.linearPolynomAction)
self.modelmenu.addAction(self.squaredPolynomAction)
self.modelmenu.addAction(self.transformPolynomAction)
self.helpmenu.addAction(self.aboutmenuaction)
self.retranslateUi(MainWindow)
@@ -118,6 +127,9 @@ class Ui_MainWindow(object):
self.closefileaction.setText(QCoreApplication.translate("MainWindow", u"\u0417\u0430\u043a\u0440\u044b\u0442\u044c", None))
self.varianceAnalysisAction.setText(QCoreApplication.translate("MainWindow", u"\u0414\u0438\u0441\u043f\u0435\u0440\u0441\u0438\u043e\u043d\u043d\u044b\u0439 \u0430\u043d\u0430\u043b\u0438\u0437", None))
self.correlationAnalisisAction.setText(QCoreApplication.translate("MainWindow", u"\u041a\u043e\u0440\u0440\u0435\u043b\u044f\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0430\u043d\u0430\u043b\u0438\u0437", None))
self.linearPolynomAction.setText(QCoreApplication.translate("MainWindow", u"\u041b\u0438\u043d\u0435\u0439\u043d\u044b\u0439 \u043f\u043e\u043b\u0438\u043d\u043e\u043c", None))
self.squaredPolynomAction.setText(QCoreApplication.translate("MainWindow", u"\u041a\u0432\u0430\u0434\u0440\u0430\u0442\u0438\u0447\u043d\u044b\u0439 \u043f\u043e\u043b\u0438\u043d\u043e\u043c", None))
self.transformPolynomAction.setText(QCoreApplication.translate("MainWindow", u"\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f", None))
self.label.setText(QCoreApplication.translate("MainWindow", u"\u0421\u0422\u0410\u0422\u0418\u0421\u0422\u0418\u0427\u0415\u0421\u041a\u0418\u0415 \u0414\u0410\u041d\u041d\u042b\u0415", None))
self.filemenu.setTitle(QCoreApplication.translate("MainWindow", u"\u0424\u0430\u0439\u043b", None))
self.generatemenu.setTitle(QCoreApplication.translate("MainWindow", u"\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439", None))

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

@@ -0,0 +1,155 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2024 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(537, 444)
self.gridLayout_2 = QGridLayout(PolynomWindow)
self.gridLayout_2.setObjectName(u"gridLayout_2")
self.tabWidget = QTabWidget(PolynomWindow)
self.tabWidget.setObjectName(u"tabWidget")
self.model = QWidget()
self.model.setObjectName(u"model")
self.gridLayout_3 = QGridLayout(self.model)
self.gridLayout_3.setObjectName(u"gridLayout_3")
self.gridLayout = QGridLayout()
self.gridLayout.setObjectName(u"gridLayout")
self.tableView = QTableView(self.model)
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, 1, 3, 1, 1)
self.polynomResult = QGridLayout()
self.polynomResult.setObjectName(u"polynomResult")
self.polynomResult.setContentsMargins(-1, 10, -1, -1)
self.residualVarianceValueLabel = QLabel(self.model)
self.residualVarianceValueLabel.setObjectName(u"residualVarianceValueLabel")
self.polynomResult.addWidget(self.residualVarianceValueLabel, 0, 1, 1, 1)
self.scaledResidualVarianceValueLabel = QLabel(self.model)
self.scaledResidualVarianceValueLabel.setObjectName(u"scaledResidualVarianceValueLabel")
self.polynomResult.addWidget(self.scaledResidualVarianceValueLabel, 1, 1, 1, 1)
self.fStatisticLabel = QLabel(self.model)
self.fStatisticLabel.setObjectName(u"fStatisticLabel")
self.polynomResult.addWidget(self.fStatisticLabel, 2, 0, 1, 1)
self.residualVarianceLabel = QLabel(self.model)
self.residualVarianceLabel.setObjectName(u"residualVarianceLabel")
self.polynomResult.addWidget(self.residualVarianceLabel, 0, 0, 1, 1)
self.scaledResidualVarianceLabel = QLabel(self.model)
self.scaledResidualVarianceLabel.setObjectName(u"scaledResidualVarianceLabel")
self.polynomResult.addWidget(self.scaledResidualVarianceLabel, 1, 0, 1, 1)
self.rSquaredLabel = QLabel(self.model)
self.rSquaredLabel.setObjectName(u"rSquaredLabel")
self.polynomResult.addWidget(self.rSquaredLabel, 3, 0, 1, 1)
self.fStatisticValueLabel = QLabel(self.model)
self.fStatisticValueLabel.setObjectName(u"fStatisticValueLabel")
self.polynomResult.addWidget(self.fStatisticValueLabel, 2, 1, 1, 1)
self.rSquaredValueLabel = QLabel(self.model)
self.rSquaredValueLabel.setObjectName(u"rSquaredValueLabel")
self.polynomResult.addWidget(self.rSquaredValueLabel, 3, 1, 1, 1)
self.gridLayout.addLayout(self.polynomResult, 2, 3, 1, 1)
self.gridLayout_3.addLayout(self.gridLayout, 0, 0, 1, 1)
self.tabWidget.addTab(self.model, "")
self.prediction = QWidget()
self.prediction.setObjectName(u"prediction")
self.gridLayout_4 = QGridLayout(self.prediction)
self.gridLayout_4.setObjectName(u"gridLayout_4")
self.predictionTableView = QTableView(self.prediction)
self.predictionTableView.setObjectName(u"predictionTableView")
self.predictionTableView.verticalHeader().setVisible(False)
self.gridLayout_4.addWidget(self.predictionTableView, 0, 0, 1, 1)
self.tabWidget.addTab(self.prediction, "")
self.tab = QWidget()
self.tab.setObjectName(u"tab")
self.gridLayout_5 = QGridLayout(self.tab)
self.gridLayout_5.setObjectName(u"gridLayout_5")
self.plotContainer = QGridLayout()
self.plotContainer.setObjectName(u"plotContainer")
self.gridLayout_5.addLayout(self.plotContainer, 0, 0, 1, 1)
self.tabWidget.addTab(self.tab, "")
self.gridLayout_2.addWidget(self.tabWidget, 0, 6, 1, 1)
self.retranslateUi(PolynomWindow)
self.tabWidget.setCurrentIndex(0)
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))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.model), QCoreApplication.translate("PolynomWindow", u"\u041c\u043e\u0434\u0435\u043b\u044c", None))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.prediction), QCoreApplication.translate("PolynomWindow", u"\u041f\u0440\u043e\u0433\u043d\u043e\u0437", None))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), QCoreApplication.translate("PolynomWindow", u"\u0413\u0440\u0430\u0444\u0438\u043a", None))
# retranslateUi

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
# Copyright (c) 2024 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
# Copyright (c) 2024 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).
@@ -20,21 +20,32 @@
import os
import sys
from PySide2.QtWidgets import QMessageBox
from PySide2.QtCore import QSize
from PySide2.QtGui import QIcon
from PySide2.QtWidgets import QMessageBox, QDoubleSpinBox, QStyledItemDelegate
from statapp.constants import NUMBERS_PRECISION
def resource_path(relative):
def resourcePath(relative):
if getattr(sys, 'frozen', False):
bundle_dir = sys._MEIPASS
# pylint: disable=protected-access
bundleDir = sys._MEIPASS
else:
# we are running in a normal Python environment
bundle_dir = os.path.dirname(os.path.abspath(__file__))
return os.path.join(bundle_dir, relative)
bundleDir = os.path.dirname(os.path.abspath(__file__))
return os.path.join(bundleDir, relative)
def safe_list_get(l, idx, default):
def addIcon(windowOrDialog):
icon = QIcon()
icon.addFile(resourcePath("ui/images/logo.ico"), QSize(), QIcon.Normal, QIcon.Off)
windowOrDialog.setWindowIcon(icon)
def safeListGet(lst, idx, default):
try:
return l[idx]
return lst[idx]
except IndexError:
return default
@@ -49,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

@@ -1,5 +1,5 @@
#
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
# Copyright (c) 2024 Maxim Slipenko, Eugene Lazurenko.
#
# This file is part of Statapp
# (see https://github.com/shizand/statapp).
@@ -19,9 +19,12 @@
#
from PySide2.QtWidgets import QDialog, QHeaderView
from statapp.calculations import variance_analysis
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, FloatDelegate
class VarianceAnalysisWindow(QDialog):
@@ -30,8 +33,14 @@ class VarianceAnalysisWindow(QDialog):
self.ui = Ui_VarianceAnalysisWindow()
self.ui.setupUi(self)
res = variance_analysis(data)
self.model = VarianceAnalysisModel(res.round(2))
res = varianceAnalysis(data)
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)
)
header = self.ui.tableView.horizontalHeader()
header.setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
addIcon(self)