feat: TabTools_ChartRecommend

This commit is contained in:
283375 2023-09-23 17:29:35 +08:00
parent 7679620617
commit 4b8d0d0427
Signed by: 283375
SSH Key Fingerprint: SHA256:UcX0qg6ZOSDOeieKPGokA5h7soykG61nz2uxuQgVLSk
7 changed files with 795 additions and 72 deletions

View File

@ -0,0 +1,297 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TabTools_ChartRecommend</class>
<widget class="QWidget" name="TabTools_ChartRecommend">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>668</width>
<height>546</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">TabTools_ChartRecommend</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>constantRangeFromPlayRating</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QDoubleSpinBox" name="rangeFromPlayRating_playRatingSpinBox">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="maximum">
<double>100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="2">
<widget class="QLabel" name="label_3">
<property name="text">
<string notr="true">AA</string>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_2">
<property name="text">
<string notr="true">EX</string>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string notr="true">EX+</string>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="rangeFromPlayRating_ExPlusLabel">
<property name="text">
<string notr="true">...</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="rangeFromPlayRating_ExLabel">
<property name="text">
<string notr="true">...</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="rangeFromPlayRating_AaLabel">
<property name="text">
<string notr="true">...</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>chartsByConstant</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QDoubleSpinBox" name="chartsByConstant_constantSpinBox">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="maximum">
<double>100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="chartsByConstant_numLabel">
<property name="text">
<string notr="true">...</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="chartsByConstant_refreshButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>refreshButton</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QGridLayout" name="chartsByConstant_gridLayout"/>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>chartsRecommendFromPlayRating</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QDoubleSpinBox" name="chartsRecommendFromPlayRating_playRatingSpinBox">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="maximum">
<double>100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string notr="true">±</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="chartsRecommendFromPlayRating_boundsSpinBox">
<property name="maximum">
<double>2.000000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="chartsRecommendFromPlayRating_numLabel">
<property name="text">
<string notr="true">...</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="chartsRecommendFromPlayRating_refreshButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>refreshButton</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QWidget" name="widget_2" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QGridLayout" name="chartsRecommendFromPlayRating_gridLayout"/>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,219 @@
# -*- coding: utf-8 -*-
################################################################################
## Form generated from reading UI file 'tabTools_ChartRecommend.ui'
##
## Created by: Qt User Interface Compiler version 6.5.2
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
QMetaObject, QObject, QPoint, QRect,
QSize, QTime, QUrl, Qt)
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
QFont, QFontDatabase, QGradient, QIcon,
QImage, QKeySequence, QLinearGradient, QPainter,
QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QDoubleSpinBox, QGridLayout, QGroupBox,
QHBoxLayout, QLabel, QPushButton, QSizePolicy,
QSpacerItem, QVBoxLayout, QWidget)
class Ui_TabTools_ChartRecommend(object):
def setupUi(self, TabTools_ChartRecommend):
if not TabTools_ChartRecommend.objectName():
TabTools_ChartRecommend.setObjectName(u"TabTools_ChartRecommend")
TabTools_ChartRecommend.resize(668, 546)
TabTools_ChartRecommend.setWindowTitle(u"TabTools_ChartRecommend")
self.verticalLayout = QVBoxLayout(TabTools_ChartRecommend)
self.verticalLayout.setObjectName(u"verticalLayout")
self.groupBox = QGroupBox(TabTools_ChartRecommend)
self.groupBox.setObjectName(u"groupBox")
self.verticalLayout_2 = QVBoxLayout(self.groupBox)
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
self.rangeFromPlayRating_playRatingSpinBox = QDoubleSpinBox(self.groupBox)
self.rangeFromPlayRating_playRatingSpinBox.setObjectName(u"rangeFromPlayRating_playRatingSpinBox")
self.rangeFromPlayRating_playRatingSpinBox.setMinimumSize(QSize(100, 0))
self.rangeFromPlayRating_playRatingSpinBox.setMaximumSize(QSize(100, 16777215))
self.rangeFromPlayRating_playRatingSpinBox.setDecimals(3)
self.rangeFromPlayRating_playRatingSpinBox.setMaximum(100.000000000000000)
self.rangeFromPlayRating_playRatingSpinBox.setSingleStep(0.100000000000000)
self.verticalLayout_2.addWidget(self.rangeFromPlayRating_playRatingSpinBox)
self.gridLayout_3 = QGridLayout()
self.gridLayout_3.setObjectName(u"gridLayout_3")
self.label_3 = QLabel(self.groupBox)
self.label_3.setObjectName(u"label_3")
self.label_3.setText(u"AA")
self.label_3.setAlignment(Qt.AlignBottom|Qt.AlignLeading|Qt.AlignLeft)
self.gridLayout_3.addWidget(self.label_3, 0, 2, 1, 1)
self.label_2 = QLabel(self.groupBox)
self.label_2.setObjectName(u"label_2")
self.label_2.setText(u"EX")
self.label_2.setAlignment(Qt.AlignBottom|Qt.AlignLeading|Qt.AlignLeft)
self.gridLayout_3.addWidget(self.label_2, 0, 1, 1, 1)
self.label = QLabel(self.groupBox)
self.label.setObjectName(u"label")
self.label.setText(u"EX+")
self.label.setAlignment(Qt.AlignBottom|Qt.AlignLeading|Qt.AlignLeft)
self.gridLayout_3.addWidget(self.label, 0, 0, 1, 1)
self.rangeFromPlayRating_ExPlusLabel = QLabel(self.groupBox)
self.rangeFromPlayRating_ExPlusLabel.setObjectName(u"rangeFromPlayRating_ExPlusLabel")
self.rangeFromPlayRating_ExPlusLabel.setText(u"...")
self.rangeFromPlayRating_ExPlusLabel.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignTop)
self.gridLayout_3.addWidget(self.rangeFromPlayRating_ExPlusLabel, 1, 0, 1, 1)
self.rangeFromPlayRating_ExLabel = QLabel(self.groupBox)
self.rangeFromPlayRating_ExLabel.setObjectName(u"rangeFromPlayRating_ExLabel")
self.rangeFromPlayRating_ExLabel.setText(u"...")
self.rangeFromPlayRating_ExLabel.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignTop)
self.gridLayout_3.addWidget(self.rangeFromPlayRating_ExLabel, 1, 1, 1, 1)
self.rangeFromPlayRating_AaLabel = QLabel(self.groupBox)
self.rangeFromPlayRating_AaLabel.setObjectName(u"rangeFromPlayRating_AaLabel")
self.rangeFromPlayRating_AaLabel.setText(u"...")
self.rangeFromPlayRating_AaLabel.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignTop)
self.gridLayout_3.addWidget(self.rangeFromPlayRating_AaLabel, 1, 2, 1, 1)
self.verticalLayout_2.addLayout(self.gridLayout_3)
self.verticalLayout.addWidget(self.groupBox)
self.groupBox_2 = QGroupBox(TabTools_ChartRecommend)
self.groupBox_2.setObjectName(u"groupBox_2")
self.verticalLayout_3 = QVBoxLayout(self.groupBox_2)
self.verticalLayout_3.setObjectName(u"verticalLayout_3")
self.horizontalLayout_3 = QHBoxLayout()
self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
self.chartsByConstant_constantSpinBox = QDoubleSpinBox(self.groupBox_2)
self.chartsByConstant_constantSpinBox.setObjectName(u"chartsByConstant_constantSpinBox")
self.chartsByConstant_constantSpinBox.setMinimumSize(QSize(100, 0))
self.chartsByConstant_constantSpinBox.setMaximumSize(QSize(100, 16777215))
self.chartsByConstant_constantSpinBox.setDecimals(1)
self.chartsByConstant_constantSpinBox.setMaximum(100.000000000000000)
self.chartsByConstant_constantSpinBox.setSingleStep(0.100000000000000)
self.horizontalLayout_3.addWidget(self.chartsByConstant_constantSpinBox)
self.chartsByConstant_numLabel = QLabel(self.groupBox_2)
self.chartsByConstant_numLabel.setObjectName(u"chartsByConstant_numLabel")
self.chartsByConstant_numLabel.setText(u"...")
self.horizontalLayout_3.addWidget(self.chartsByConstant_numLabel)
self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
self.horizontalLayout_3.addItem(self.horizontalSpacer)
self.chartsByConstant_refreshButton = QPushButton(self.groupBox_2)
self.chartsByConstant_refreshButton.setObjectName(u"chartsByConstant_refreshButton")
self.chartsByConstant_refreshButton.setEnabled(False)
self.horizontalLayout_3.addWidget(self.chartsByConstant_refreshButton)
self.verticalLayout_3.addLayout(self.horizontalLayout_3)
self.widget = QWidget(self.groupBox_2)
self.widget.setObjectName(u"widget")
sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.widget.sizePolicy().hasHeightForWidth())
self.widget.setSizePolicy(sizePolicy)
self.chartsByConstant_gridLayout = QGridLayout(self.widget)
self.chartsByConstant_gridLayout.setObjectName(u"chartsByConstant_gridLayout")
self.verticalLayout_3.addWidget(self.widget)
self.verticalLayout.addWidget(self.groupBox_2)
self.groupBox_3 = QGroupBox(TabTools_ChartRecommend)
self.groupBox_3.setObjectName(u"groupBox_3")
self.verticalLayout_4 = QVBoxLayout(self.groupBox_3)
self.verticalLayout_4.setObjectName(u"verticalLayout_4")
self.horizontalLayout_2 = QHBoxLayout()
self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
self.chartsRecommendFromPlayRating_playRatingSpinBox = QDoubleSpinBox(self.groupBox_3)
self.chartsRecommendFromPlayRating_playRatingSpinBox.setObjectName(u"chartsRecommendFromPlayRating_playRatingSpinBox")
self.chartsRecommendFromPlayRating_playRatingSpinBox.setMinimumSize(QSize(100, 0))
self.chartsRecommendFromPlayRating_playRatingSpinBox.setMaximumSize(QSize(100, 16777215))
self.chartsRecommendFromPlayRating_playRatingSpinBox.setDecimals(3)
self.chartsRecommendFromPlayRating_playRatingSpinBox.setMaximum(100.000000000000000)
self.chartsRecommendFromPlayRating_playRatingSpinBox.setSingleStep(0.100000000000000)
self.horizontalLayout_2.addWidget(self.chartsRecommendFromPlayRating_playRatingSpinBox)
self.label_4 = QLabel(self.groupBox_3)
self.label_4.setObjectName(u"label_4")
self.label_4.setText(u"\u00b1")
self.horizontalLayout_2.addWidget(self.label_4)
self.chartsRecommendFromPlayRating_boundsSpinBox = QDoubleSpinBox(self.groupBox_3)
self.chartsRecommendFromPlayRating_boundsSpinBox.setObjectName(u"chartsRecommendFromPlayRating_boundsSpinBox")
self.chartsRecommendFromPlayRating_boundsSpinBox.setMaximum(2.000000000000000)
self.chartsRecommendFromPlayRating_boundsSpinBox.setSingleStep(0.010000000000000)
self.chartsRecommendFromPlayRating_boundsSpinBox.setValue(0.100000000000000)
self.horizontalLayout_2.addWidget(self.chartsRecommendFromPlayRating_boundsSpinBox)
self.chartsRecommendFromPlayRating_numLabel = QLabel(self.groupBox_3)
self.chartsRecommendFromPlayRating_numLabel.setObjectName(u"chartsRecommendFromPlayRating_numLabel")
self.chartsRecommendFromPlayRating_numLabel.setText(u"...")
self.horizontalLayout_2.addWidget(self.chartsRecommendFromPlayRating_numLabel)
self.horizontalSpacer_2 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
self.horizontalLayout_2.addItem(self.horizontalSpacer_2)
self.chartsRecommendFromPlayRating_refreshButton = QPushButton(self.groupBox_3)
self.chartsRecommendFromPlayRating_refreshButton.setObjectName(u"chartsRecommendFromPlayRating_refreshButton")
self.chartsRecommendFromPlayRating_refreshButton.setEnabled(False)
self.horizontalLayout_2.addWidget(self.chartsRecommendFromPlayRating_refreshButton)
self.verticalLayout_4.addLayout(self.horizontalLayout_2)
self.widget_2 = QWidget(self.groupBox_3)
self.widget_2.setObjectName(u"widget_2")
sizePolicy.setHeightForWidth(self.widget_2.sizePolicy().hasHeightForWidth())
self.widget_2.setSizePolicy(sizePolicy)
self.chartsRecommendFromPlayRating_gridLayout = QGridLayout(self.widget_2)
self.chartsRecommendFromPlayRating_gridLayout.setObjectName(u"chartsRecommendFromPlayRating_gridLayout")
self.verticalLayout_4.addWidget(self.widget_2)
self.verticalLayout.addWidget(self.groupBox_3)
self.retranslateUi(TabTools_ChartRecommend)
QMetaObject.connectSlotsByName(TabTools_ChartRecommend)
# setupUi
def retranslateUi(self, TabTools_ChartRecommend):
self.groupBox.setTitle(QCoreApplication.translate("TabTools_ChartRecommend", u"constantRangeFromPlayRating", None))
self.groupBox_2.setTitle(QCoreApplication.translate("TabTools_ChartRecommend", u"chartsByConstant", None))
self.chartsByConstant_refreshButton.setText(QCoreApplication.translate("TabTools_ChartRecommend", u"refreshButton", None))
self.groupBox_3.setTitle(QCoreApplication.translate("TabTools_ChartRecommend", u"chartsRecommendFromPlayRating", None))
self.chartsRecommendFromPlayRating_refreshButton.setText(QCoreApplication.translate("TabTools_ChartRecommend", u"refreshButton", None))
pass
# retranslateUi

View File

@ -29,6 +29,11 @@
<string>tab.stepCalculator</string>
</attribute>
</widget>
<widget class="TabTools_ChartRecommend" name="tab_4">
<attribute name="title">
<string>tab.chartRecommend</string>
</attribute>
</widget>
<widget class="TabTools_Andreal" name="tab_3">
<attribute name="title">
<string>tab.andreal</string>
@ -57,6 +62,12 @@
<header>ui.implements.tabs.tabTools.tabTools_Andreal</header>
<container>1</container>
</customwidget>
<customwidget>
<class>TabTools_ChartRecommend</class>
<extends>QWidget</extends>
<header>ui.implements.tabs.tabTools.tabTools_ChartRecommend</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>

View File

@ -19,6 +19,7 @@ from PySide6.QtWidgets import (QApplication, QSizePolicy, QTabWidget, QVBoxLayou
QWidget)
from ui.implements.tabs.tabTools.tabTools_Andreal import TabTools_Andreal
from ui.implements.tabs.tabTools.tabTools_ChartRecommend import TabTools_ChartRecommend
from ui.implements.tabs.tabTools.tabTools_InfoLookup import TabTools_InfoLookup
from ui.implements.tabs.tabTools.tabTools_StepCalculator import TabTools_StepCalculator
@ -38,6 +39,9 @@ class Ui_TabToolsEntry(object):
self.tab_2 = TabTools_StepCalculator()
self.tab_2.setObjectName(u"tab_2")
self.tabWidget.addTab(self.tab_2, "")
self.tab_4 = TabTools_ChartRecommend()
self.tab_4.setObjectName(u"tab_4")
self.tabWidget.addTab(self.tab_4, "")
self.tab_3 = TabTools_Andreal()
self.tab_3.setObjectName(u"tab_3")
self.tabWidget.addTab(self.tab_3, "")
@ -56,6 +60,7 @@ class Ui_TabToolsEntry(object):
def retranslateUi(self, TabToolsEntry):
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), QCoreApplication.translate("TabToolsEntry", u"tab.infoLookup", None))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), QCoreApplication.translate("TabToolsEntry", u"tab.stepCalculator", None))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_4), QCoreApplication.translate("TabToolsEntry", u"tab.chartRecommend", None))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), QCoreApplication.translate("TabToolsEntry", u"tab.andreal", None))
pass
# retranslateUi

View File

@ -0,0 +1,123 @@
import logging
import random
from arcaea_offline.calculate import calculate_constants_from_play_rating
from arcaea_offline.database import Database
from arcaea_offline.models import Chart, ScoreBest
from arcaea_offline.utils.rating import rating_class_to_text
from arcaea_offline.utils.score import score_to_grade_text
from PySide6.QtCore import Slot
from PySide6.QtWidgets import QLabel, QWidget
from ui.designer.tabs.tabTools.tabTools_ChartRecommend_ui import (
Ui_TabTools_ChartRecommend,
)
logger = logging.getLogger(__name__)
def chartToText(chart: Chart):
return f"{chart.artist} - {chart.title}<br>({chart.song_id}) {rating_class_to_text(chart.rating_class)}"
def scoreBestToText(score: ScoreBest):
return f"{score_to_grade_text(score.score)} {score.score} > {score.potential:.4f}"
class TabTools_ChartRecommend(Ui_TabTools_ChartRecommend, QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self.db = Database()
self.chartsByConstant = []
self.chartsRecommendFromPlayRating = []
self.numLabelFormatString = "{} charts"
self.chartsRecommendFromPlayRating_playRatingSpinBox.valueChanged.connect(
self.updateChartsRecommendFromPlayRating
)
self.chartsRecommendFromPlayRating_boundsSpinBox.valueChanged.connect(
self.updateChartsRecommendFromPlayRating
)
self.chartsByConstant_refreshButton.clicked.connect(self.fillChartsByConstant)
self.chartsRecommendFromPlayRating_refreshButton.clicked.connect(
self.fillChartsRecommendFromPlayRating
)
@Slot(float)
def on_rangeFromPlayRating_playRatingSpinBox_valueChanged(self, value: float):
try:
result = calculate_constants_from_play_rating(value)
exPlusLower, exPlusUpper = result.EXPlus
exLower, exUpper = result.EX
aaLower, aaUpper = result.AA
self.rangeFromPlayRating_ExPlusLabel.setText(
f"{exPlusLower:.3f}~{exPlusUpper:.3f}"
)
self.rangeFromPlayRating_ExLabel.setText(f"{exLower:.3f}~{exUpper:.3f}")
self.rangeFromPlayRating_AaLabel.setText(f"{aaLower:.3f}~{aaUpper:.3f}")
except Exception:
logging.exception("cannot calculate constant from play rating")
self.rangeFromPlayRating_ExPlusLabel.setText("...")
self.rangeFromPlayRating_ExLabel.setText("...")
self.rangeFromPlayRating_AaLabel.setText("...")
def fillChartsByConstant(self):
while item := self.chartsByConstant_gridLayout.takeAt(0):
item.widget().deleteLater()
charts = random.sample(
self.chartsByConstant, k=min(len(self.chartsByConstant), 6)
)
row = 0
for i, chart in enumerate(charts):
if i % 3 == 0:
row += 1
label = QLabel(self)
label.setText(chartToText(chart))
self.chartsByConstant_gridLayout.addWidget(label, row, i % 3)
@Slot(float)
def on_chartsByConstant_constantSpinBox_valueChanged(self, value: float):
self.chartsByConstant = self.db.get_charts_by_constant(int(value * 10))
chartsNum = len(self.chartsByConstant)
self.chartsByConstant_refreshButton.setEnabled(chartsNum > 6)
self.chartsByConstant_numLabel.setText(
self.numLabelFormatString.format(chartsNum)
)
self.fillChartsByConstant()
def fillChartsRecommendFromPlayRating(self):
while item := self.chartsRecommendFromPlayRating_gridLayout.takeAt(0):
item.widget().deleteLater()
charts = random.sample(
self.chartsRecommendFromPlayRating,
k=min(len(self.chartsRecommendFromPlayRating), 6),
)
row = 0
for i, chart in enumerate(charts):
if i % 3 == 0:
row += 1
scoreBest = self.db.get_score_best(chart.song_id, chart.rating_class)
label = QLabel(self)
label.setText(f"{chartToText(chart)}<br>-<br>{scoreBestToText(scoreBest)}")
self.chartsRecommendFromPlayRating_gridLayout.addWidget(label, row, i % 3)
def updateChartsRecommendFromPlayRating(self):
playRating = self.chartsRecommendFromPlayRating_playRatingSpinBox.value()
bounds = self.chartsRecommendFromPlayRating_boundsSpinBox.value()
self.chartsRecommendFromPlayRating = self.db.recommend_charts(
playRating, bounds
)
chartsNum = len(self.chartsRecommendFromPlayRating)
self.chartsRecommendFromPlayRating_refreshButton.setEnabled(chartsNum > 6)
self.chartsRecommendFromPlayRating_numLabel.setText(
self.numLabelFormatString.format(chartsNum)
)
self.fillChartsRecommendFromPlayRating()

View File

@ -89,12 +89,12 @@
<translation>Continue</translation>
</message>
<message>
<location filename="../../startup/databaseChecker.py" line="117"/>
<location filename="../../startup/databaseChecker.py" line="115"/>
<source>dialog.tryInitExistingDatabase</source>
<translation>The existing database doesn&apos;t seem to be initialized properly, try initialize again?</translation>
</message>
<message>
<location filename="../../startup/databaseChecker.py" line="133"/>
<location filename="../../startup/databaseChecker.py" line="131"/>
<source>dialog.confirmNewDatabase</source>
<translation>Database file does not exist. Create now?</translation>
</message>
@ -283,22 +283,22 @@ validation</translation>
<context>
<name>OcrTableModel</name>
<message>
<location filename="../../extends/components/ocrQueue.py" line="341"/>
<location filename="../../extends/components/ocrQueue.py" line="347"/>
<source>horizontalHeader.title.select</source>
<translation>Select</translation>
</message>
<message>
<location filename="../../extends/components/ocrQueue.py" line="342"/>
<location filename="../../extends/components/ocrQueue.py" line="348"/>
<source>horizontalHeader.title.imagePreview</source>
<translation>Image Preview</translation>
</message>
<message>
<location filename="../../extends/components/ocrQueue.py" line="343"/>
<location filename="../../extends/components/ocrQueue.py" line="349"/>
<source>horizontalHeader.title.chart</source>
<translation>Chart</translation>
</message>
<message>
<location filename="../../extends/components/ocrQueue.py" line="344"/>
<location filename="../../extends/components/ocrQueue.py" line="350"/>
<source>horizontalHeader.title.score</source>
<translation>Score</translation>
</message>
@ -314,54 +314,54 @@ validation</translation>
<context>
<name>ScoreEditor</name>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="109"/>
<location filename="../../designer/components/scoreEditor.ui" line="119"/>
<location filename="../../designer/components/scoreEditor.ui" line="189"/>
<location filename="../../designer/components/scoreEditor.ui" line="199"/>
<location filename="../../designer/components/scoreEditor.ui" line="239"/>
<location filename="../../designer/components/scoreEditor.ui" line="272"/>
<location filename="../../designer/components/scoreEditor.ui" line="279"/>
<location filename="../../designer/components/scoreEditor.ui" line="302"/>
<location filename="../../designer/components/scoreEditor.ui" line="139"/>
<location filename="../../designer/components/scoreEditor.ui" line="178"/>
<location filename="../../designer/components/scoreEditor.ui" line="225"/>
<location filename="../../designer/components/scoreEditor.ui" line="258"/>
<location filename="../../designer/components/scoreEditor.ui" line="285"/>
<location filename="../../designer/components/scoreEditor.ui" line="292"/>
<location filename="../../designer/components/scoreEditor.ui" line="318"/>
<location filename="../../designer/components/scoreEditor.ui" line="328"/>
<source>setNone</source>
<translation>None</translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="169"/>
<location filename="../../designer/components/scoreEditor.ui" line="102"/>
<source>formLabel.date</source>
<translation>Time</translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="338"/>
<location filename="../../designer/components/scoreEditor.ui" line="268"/>
<source>formLabel.comment</source>
<translation>Comment</translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="358"/>
<location filename="../../designer/components/scoreEditor.ui" line="119"/>
<source>formLabel.preview</source>
<translation>Preview</translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="99"/>
<location filename="../../designer/components/scoreEditor.ui" line="20"/>
<source>formLabel.score</source>
<translation>Score</translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="162"/>
<location filename="../../designer/components/scoreEditor.ui" line="278"/>
<source>idAutoInsert</source>
<translation>(Auto insert)</translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="309"/>
<location filename="../../designer/components/scoreEditor.ui" line="112"/>
<source>warnIfIncomplete</source>
<translation>Warn if incomplete</translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="63"/>
<location filename="../../designer/components/scoreEditor.ui" line="218"/>
<source>commitButton</source>
<translation>Commit</translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="320"/>
<location filename="../../implements/components/scoreEditor.py" line="327"/>
<source>validate.ok</source>
<translation>OK</translation>
</message>
@ -406,57 +406,57 @@ validation</translation>
<translation>Cannot verify an incomplete score. Commit anyway?</translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="205"/>
<location filename="../../implements/components/scoreEditor.py" line="212"/>
<source>confirmDialog.chartNotSet.title</source>
<translation>Chart not set</translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="206"/>
<location filename="../../implements/components/scoreEditor.py" line="213"/>
<source>confirmDialog.chartNotSet.text</source>
<translation>Chart not set, cannot commit.</translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="214"/>
<location filename="../../implements/components/scoreEditor.py" line="221"/>
<source>confirmDialog.scoreIncomplete.title</source>
<translation>Score incomplete</translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="215"/>
<location filename="../../implements/components/scoreEditor.py" line="222"/>
<source>confirmDialog.scoreIncomplete.text</source>
<translation>Necessary score field missing, cannot commit.</translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="324"/>
<location filename="../../implements/components/scoreEditor.py" line="331"/>
<source>validate.chartNotSet</source>
<translation>Chart not set</translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="328"/>
<location filename="../../implements/components/scoreEditor.py" line="335"/>
<source>validate.chartIncomple</source>
<translation>No chart data, cannot verify</translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="332"/>
<location filename="../../implements/components/scoreEditor.py" line="339"/>
<source>validate.scoreMismatch</source>
<translation>Possible invalid score</translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="336"/>
<location filename="../../implements/components/scoreEditor.py" line="343"/>
<source>validate.scoreEmpty</source>
<translation>Empty score</translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="340"/>
<location filename="../../implements/components/scoreEditor.py" line="347"/>
<source>validate.scoreIncomplete</source>
<translation>Missing necessary score field</translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="346"/>
<location filename="../../implements/components/scoreEditor.py" line="353"/>
<source>validate.scoreIncompleteForValidate</source>
<translation>Score incomplete, cannot verify</translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="351"/>
<location filename="../../implements/components/scoreEditor.py" line="358"/>
<source>validate.unknownState</source>
<translation>Unknown</translation>
</message>
@ -581,12 +581,12 @@ validation</translation>
<translation>Manage</translation>
</message>
<message>
<location filename="../../implements/tabs/tabDbEntry.py" line="16"/>
<location filename="../../implements/tabs/tabDbEntry.py" line="20"/>
<source>tab.scoreTableViewer</source>
<translation>Table [Score]</translation>
</message>
<message>
<location filename="../../implements/tabs/tabDbEntry.py" line="20"/>
<location filename="../../implements/tabs/tabDbEntry.py" line="24"/>
<source>tab.b30TableViewer</source>
<translation>Table [B30]</translation>
</message>
@ -769,6 +769,11 @@ validation</translation>
</message>
<message>
<location filename="../../designer/tabs/tabToolsEntry.ui" line="34"/>
<source>tab.chartRecommend</source>
<translation>Chart Recommend</translation>
</message>
<message>
<location filename="../../designer/tabs/tabToolsEntry.ui" line="39"/>
<source>tab.andreal</source>
<translation>Andreal Image Generator</translation>
</message>
@ -836,11 +841,35 @@ validation</translation>
<translation>Generate</translation>
</message>
<message>
<location filename="../../implements/tabs/tabTools/tabTools_Andreal.py" line="81"/>
<location filename="../../implements/tabs/tabTools/tabTools_Andreal.py" line="82"/>
<source>imageWhatIsThisDialog.description</source>
<translation>Generate image of...&lt;ul&gt;&lt;li&gt;/a - the most recent score&lt;/li&gt;&lt;li&gt;/a b30 - best30 image&lt;/li&gt;&lt;li&gt;/a info - best score of the selected chart&lt;/li&gt;&lt;/ul&gt;</translation>
</message>
</context>
<context>
<name>TabTools_ChartRecommend</name>
<message>
<location filename="../../designer/tabs/tabTools/tabTools_ChartRecommend.ui" line="20"/>
<source>constantRangeFromPlayRating</source>
<translation>Chart Constant Range from Play Rating</translation>
</message>
<message>
<location filename="../../designer/tabs/tabTools/tabTools_ChartRecommend.ui" line="118"/>
<source>chartsByConstant</source>
<translation>Charts by Constant</translation>
</message>
<message>
<location filename="../../designer/tabs/tabTools/tabTools_ChartRecommend.ui" line="174"/>
<location filename="../../designer/tabs/tabTools/tabTools_ChartRecommend.ui" line="273"/>
<source>refreshButton</source>
<translation>Roll</translation>
</message>
<message>
<location filename="../../designer/tabs/tabTools/tabTools_ChartRecommend.ui" line="197"/>
<source>chartsRecommendFromPlayRating</source>
<translation>Chart from Play Rating Based on Best Score</translation>
</message>
</context>
<context>
<name>TabTools_InfoLookup</name>
<message>
@ -1008,6 +1037,11 @@ validation</translation>
<source>difficulty.title</source>
<translation>Title</translation>
</message>
<message>
<location filename="../../designer/tabs/tabTools/tabTools_InfoLookup.ui" line="695"/>
<source>playRatingCalculate</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>TabTools_StepCalculator</name>

View File

@ -89,12 +89,12 @@
<translation></translation>
</message>
<message>
<location filename="../../startup/databaseChecker.py" line="117"/>
<location filename="../../startup/databaseChecker.py" line="115"/>
<source>dialog.tryInitExistingDatabase</source>
<translation></translation>
</message>
<message>
<location filename="../../startup/databaseChecker.py" line="133"/>
<location filename="../../startup/databaseChecker.py" line="131"/>
<source>dialog.confirmNewDatabase</source>
<translation></translation>
</message>
@ -282,22 +282,22 @@
<context>
<name>OcrTableModel</name>
<message>
<location filename="../../extends/components/ocrQueue.py" line="341"/>
<location filename="../../extends/components/ocrQueue.py" line="347"/>
<source>horizontalHeader.title.select</source>
<translation></translation>
</message>
<message>
<location filename="../../extends/components/ocrQueue.py" line="342"/>
<location filename="../../extends/components/ocrQueue.py" line="348"/>
<source>horizontalHeader.title.imagePreview</source>
<translation></translation>
</message>
<message>
<location filename="../../extends/components/ocrQueue.py" line="343"/>
<location filename="../../extends/components/ocrQueue.py" line="349"/>
<source>horizontalHeader.title.chart</source>
<translation></translation>
</message>
<message>
<location filename="../../extends/components/ocrQueue.py" line="344"/>
<location filename="../../extends/components/ocrQueue.py" line="350"/>
<source>horizontalHeader.title.score</source>
<translation></translation>
</message>
@ -313,54 +313,54 @@
<context>
<name>ScoreEditor</name>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="109"/>
<location filename="../../designer/components/scoreEditor.ui" line="119"/>
<location filename="../../designer/components/scoreEditor.ui" line="189"/>
<location filename="../../designer/components/scoreEditor.ui" line="199"/>
<location filename="../../designer/components/scoreEditor.ui" line="239"/>
<location filename="../../designer/components/scoreEditor.ui" line="272"/>
<location filename="../../designer/components/scoreEditor.ui" line="279"/>
<location filename="../../designer/components/scoreEditor.ui" line="302"/>
<location filename="../../designer/components/scoreEditor.ui" line="139"/>
<location filename="../../designer/components/scoreEditor.ui" line="178"/>
<location filename="../../designer/components/scoreEditor.ui" line="225"/>
<location filename="../../designer/components/scoreEditor.ui" line="258"/>
<location filename="../../designer/components/scoreEditor.ui" line="285"/>
<location filename="../../designer/components/scoreEditor.ui" line="292"/>
<location filename="../../designer/components/scoreEditor.ui" line="318"/>
<location filename="../../designer/components/scoreEditor.ui" line="328"/>
<source>setNone</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="169"/>
<location filename="../../designer/components/scoreEditor.ui" line="102"/>
<source>formLabel.date</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="338"/>
<location filename="../../designer/components/scoreEditor.ui" line="268"/>
<source>formLabel.comment</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="358"/>
<location filename="../../designer/components/scoreEditor.ui" line="119"/>
<source>formLabel.preview</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="99"/>
<location filename="../../designer/components/scoreEditor.ui" line="20"/>
<source>formLabel.score</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="162"/>
<location filename="../../designer/components/scoreEditor.ui" line="278"/>
<source>idAutoInsert</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="309"/>
<location filename="../../designer/components/scoreEditor.ui" line="112"/>
<source>warnIfIncomplete</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="63"/>
<location filename="../../designer/components/scoreEditor.ui" line="218"/>
<source>commitButton</source>
<translation></translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="320"/>
<location filename="../../implements/components/scoreEditor.py" line="327"/>
<source>validate.ok</source>
<translation>OK</translation>
</message>
@ -405,57 +405,57 @@
<translation></translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="205"/>
<location filename="../../implements/components/scoreEditor.py" line="212"/>
<source>confirmDialog.chartNotSet.title</source>
<translation></translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="206"/>
<location filename="../../implements/components/scoreEditor.py" line="213"/>
<source>confirmDialog.chartNotSet.text</source>
<translation></translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="214"/>
<location filename="../../implements/components/scoreEditor.py" line="221"/>
<source>confirmDialog.scoreIncomplete.title</source>
<translation></translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="215"/>
<location filename="../../implements/components/scoreEditor.py" line="222"/>
<source>confirmDialog.scoreIncomplete.text</source>
<translation></translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="324"/>
<location filename="../../implements/components/scoreEditor.py" line="331"/>
<source>validate.chartNotSet</source>
<translation></translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="328"/>
<location filename="../../implements/components/scoreEditor.py" line="335"/>
<source>validate.chartIncomple</source>
<translation></translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="332"/>
<location filename="../../implements/components/scoreEditor.py" line="339"/>
<source>validate.scoreMismatch</source>
<translation></translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="336"/>
<location filename="../../implements/components/scoreEditor.py" line="343"/>
<source>validate.scoreEmpty</source>
<translation></translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="340"/>
<location filename="../../implements/components/scoreEditor.py" line="347"/>
<source>validate.scoreIncomplete</source>
<translation></translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="346"/>
<location filename="../../implements/components/scoreEditor.py" line="353"/>
<source>validate.scoreIncompleteForValidate</source>
<translation></translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="351"/>
<location filename="../../implements/components/scoreEditor.py" line="358"/>
<source>validate.unknownState</source>
<translation></translation>
</message>
@ -580,12 +580,12 @@
<translation></translation>
</message>
<message>
<location filename="../../implements/tabs/tabDbEntry.py" line="16"/>
<location filename="../../implements/tabs/tabDbEntry.py" line="20"/>
<source>tab.scoreTableViewer</source>
<translation> []</translation>
</message>
<message>
<location filename="../../implements/tabs/tabDbEntry.py" line="20"/>
<location filename="../../implements/tabs/tabDbEntry.py" line="24"/>
<source>tab.b30TableViewer</source>
<translation> [B30]</translation>
</message>
@ -768,6 +768,11 @@
</message>
<message>
<location filename="../../designer/tabs/tabToolsEntry.ui" line="34"/>
<source>tab.chartRecommend</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/tabs/tabToolsEntry.ui" line="39"/>
<source>tab.andreal</source>
<translation>Andreal </translation>
</message>
@ -835,11 +840,35 @@
<translation></translation>
</message>
<message>
<location filename="../../implements/tabs/tabTools/tabTools_Andreal.py" line="81"/>
<location filename="../../implements/tabs/tabTools/tabTools_Andreal.py" line="82"/>
<source>imageWhatIsThisDialog.description</source>
<translation>&lt;ul&gt;&lt;li&gt;/a - &lt;/li&gt;&lt;li&gt;/a b30 - /a b30&lt;/li&gt;&lt;li&gt;/a info - &lt;/li&gt;&lt;/ul&gt;</translation>
</message>
</context>
<context>
<name>TabTools_ChartRecommend</name>
<message>
<location filename="../../designer/tabs/tabTools/tabTools_ChartRecommend.ui" line="20"/>
<source>constantRangeFromPlayRating</source>
<translation> PTT </translation>
</message>
<message>
<location filename="../../designer/tabs/tabTools/tabTools_ChartRecommend.ui" line="118"/>
<source>chartsByConstant</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/tabs/tabTools/tabTools_ChartRecommend.ui" line="174"/>
<location filename="../../designer/tabs/tabTools/tabTools_ChartRecommend.ui" line="273"/>
<source>refreshButton</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/tabs/tabTools/tabTools_ChartRecommend.ui" line="197"/>
<source>chartsRecommendFromPlayRating</source>
<translation> PTT </translation>
</message>
</context>
<context>
<name>TabTools_InfoLookup</name>
<message>
@ -1007,6 +1036,11 @@
<source>difficulty.title</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/tabs/tabTools/tabTools_InfoLookup.ui" line="695"/>
<source>playRatingCalculate</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>TabTools_StepCalculator</name>