Compare commits

...

3 Commits

Author SHA1 Message Date
5ca9a5aaa3
chore: bump version 0.3.0a0.dev0 2024-10-02 00:46:24 +08:00
2377d233b1
chore: code reformatting 2024-10-01 22:57:19 +08:00
3b9609ee82
fix!: ruff lint errors
* Refactor KanaeDayNight enum
2024-10-01 22:51:40 +08:00
11 changed files with 54 additions and 57 deletions

View File

@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "arcaea-offline"
version = "0.2.2"
version = "0.3.0a0.dev0"
authors = [{ name = "283375", email = "log_283375@163.com" }]
description = "Manage your local Arcaea score database."
readme = "README.md"

View File

@ -5,6 +5,13 @@ from ._common import StepBooster
class LegacyMapStepBooster(StepBooster):
__fragment_boost_multipliers = {
None: Decimal("1.0"),
100: Decimal("1.1"),
250: Decimal("1.25"),
500: Decimal("1.5"),
}
def __init__(
self,
stamina: Literal[2, 4, 6],
@ -35,11 +42,5 @@ class LegacyMapStepBooster(StepBooster):
def final_value(self) -> Decimal:
stamina_multiplier = Decimal(self.stamina)
fragments_multiplier = Decimal(1)
if self.fragments == 100:
fragments_multiplier = Decimal("1.1")
elif self.fragments == 250:
fragments_multiplier = Decimal("1.25")
elif self.fragments == 500:
fragments_multiplier = Decimal("1.5")
fragments_multiplier = self.__fragment_boost_multipliers[self.fragments]
return stamina_multiplier * fragments_multiplier

View File

@ -52,6 +52,4 @@ class WorldMainMapCalculators:
play_rating_sqrt = (
Decimal(50) * step - Decimal("2.5") * partner_step_value
) / (Decimal("2.45") * partner_step_value)
return (
play_rating_sqrt**2 if play_rating_sqrt >= 0 else -(play_rating_sqrt**2)
)
return play_rating_sqrt**2 if play_rating_sqrt >= 0 else -(play_rating_sqrt**2)

View File

@ -75,7 +75,7 @@ class Database(metaclass=Singleton):
# region init
def init(self, checkfirst: bool = True):
def init(self, *, checkfirst: bool = True):
# create tables & views
if checkfirst:
# > https://github.com/kvesteri/sqlalchemy-utils/issues/396
@ -320,7 +320,7 @@ class Database(metaclass=Singleton):
for constant in range(base_constant - 20, base_constant + 1):
# from Pure Memory(EX+) to AA
score_modifier = (play_result * 10 - constant) / 10
if score_modifier >= 2.0:
if score_modifier >= 2.0: # noqa: PLR2004
min_score = 10000000
elif score_modifier >= 1.0:
min_score = 200000 * (score_modifier - 1) + 9800000
@ -383,7 +383,7 @@ class Database(metaclass=Singleton):
stmt = (
select(func.count())
.select_from(ChartInfo)
.where((ChartInfo.constant != None) & (ChartInfo.notes != None))
.where((ChartInfo.constant != None) & (ChartInfo.notes != None)) # noqa: E711
)
with self.sessionmaker() as session:
result = session.scalar(stmt)

View File

@ -105,9 +105,9 @@ class ScoreCalculated(ScoresViewBase):
Score.modifier,
Score.clear_type,
case(
(Score.score >= 10000000, ChartInfo.constant / 10.0 + 2),
(Score.score >= 10000000, ChartInfo.constant / 10.0 + 2), # noqa: PLR2004
(
Score.score >= 9800000,
Score.score >= 9800000, # noqa: PLR2004
ChartInfo.constant / 10.0 + 1 + (Score.score - 9800000) / 200000.0,
),
else_=func.max(

View File

@ -1,4 +1,4 @@
from typing import Any, Literal, overload
from typing import Any, Dict, Literal, overload
from arcaea_offline.constants.enums import (
ArcaeaPlayResultClearType,
@ -10,8 +10,8 @@ from arcaea_offline.constants.play_result import ScoreLowerLimits
class PlayResultFormatter:
SCORE_GRADE_FORMAT_RESULTS = Literal["EX+", "EX", "AA", "A", "B", "C", "D"]
@staticmethod
def score_grade(score: int) -> SCORE_GRADE_FORMAT_RESULTS:
@classmethod
def score_grade(cls, score: int) -> SCORE_GRADE_FORMAT_RESULTS:
"""
Returns the score grade, e.g. EX+.
@ -20,23 +20,21 @@ class PlayResultFormatter:
if not isinstance(score, int):
raise TypeError(f"Unsupported type {type(score)}, cannot format")
if score >= ScoreLowerLimits.EX_PLUS:
return "EX+"
elif score >= ScoreLowerLimits.EX:
return "EX"
elif score >= ScoreLowerLimits.AA:
return "AA"
elif score >= ScoreLowerLimits.A:
return "A"
elif score >= ScoreLowerLimits.B:
return "B"
elif score >= ScoreLowerLimits.C:
return "C"
elif score >= ScoreLowerLimits.D:
return "D"
else:
if score < 0:
raise ValueError("score cannot be negative")
score_grades: Dict[int, Literal["EX+", "EX", "AA", "A", "B", "C", "D"]] = {
ScoreLowerLimits.EX_PLUS: "EX+",
ScoreLowerLimits.EX: "EX",
ScoreLowerLimits.AA: "AA",
ScoreLowerLimits.A: "A",
ScoreLowerLimits.B: "B",
ScoreLowerLimits.C: "C",
ScoreLowerLimits.D: "D",
}
return next(value for limit, value in score_grades.items() if score >= limit)
CLEAR_TYPE_FORMAT_RESULTS = Literal[
"TRACK LOST",
"NORMAL CLEAR",
@ -56,7 +54,6 @@ class PlayResultFormatter:
"""
Returns the uppercased clear type name, e.g. NORMAL CLEAR.
"""
...
@overload
@classmethod
@ -69,7 +66,6 @@ class PlayResultFormatter:
Raises `ValueError` if the integer is negative.
"""
...
@overload
@classmethod
@ -77,7 +73,6 @@ class PlayResultFormatter:
"""
Returns "None"
"""
...
@classmethod
def clear_type(cls, clear_type: Any) -> CLEAR_TYPE_FORMAT_RESULTS:
@ -103,7 +98,6 @@ class PlayResultFormatter:
"""
Returns the uppercased clear type name, e.g. NORMAL CLEAR.
"""
...
@overload
@classmethod
@ -116,7 +110,6 @@ class PlayResultFormatter:
Raises `ValueError` if the integer is negative.
"""
...
@overload
@classmethod
@ -124,7 +117,6 @@ class PlayResultFormatter:
"""
Returns "None"
"""
...
@classmethod
def modifier(cls, modifier: Any) -> MODIFIER_FORMAT_RESULTS:

View File

@ -3,13 +3,9 @@ from enum import IntEnum
class KanaeDayNight(IntEnum):
Day = 0
Night = 1
DAY = 0
NIGHT = 1
def kanae_day_night(timestamp: int) -> KanaeDayNight:
"""
:param timestamp: POSIX timestamp, which is passed to `datetime.fromtimestamp(timestamp)`.
"""
dt = datetime.fromtimestamp(timestamp)
return KanaeDayNight.Day if 6 <= dt.hour <= 19 else KanaeDayNight.Night
@staticmethod
def from_datetime(dt: datetime) -> "KanaeDayNight":
return KanaeDayNight.DAY if 6 <= dt.hour <= 19 else KanaeDayNight.NIGHT # noqa: PLR2004

View File

@ -21,7 +21,8 @@ class TestPlayResultCalculators:
Decimal("-0.00")
) == Decimal("-31.67")
pytest.raises(ValueError, PlayResultCalculators.score_modifier, -1)
with pytest.raises(ValueError, match="negative"):
PlayResultCalculators.score_modifier(-1)
pytest.raises(TypeError, PlayResultCalculators.score_modifier, "9800000")
pytest.raises(TypeError, PlayResultCalculators.score_modifier, None)
@ -38,5 +39,8 @@ class TestPlayResultCalculators:
pytest.raises(TypeError, PlayResultCalculators.play_rating, 10002221, None)
pytest.raises(ValueError, PlayResultCalculators.play_rating, -1, 120)
pytest.raises(ValueError, PlayResultCalculators.play_rating, 10002221, -1)
with pytest.raises(ValueError, match="negative"):
PlayResultCalculators.play_rating(-1, 120)
with pytest.raises(ValueError, match="negative"):
PlayResultCalculators.play_rating(10002221, -1)

View File

@ -14,7 +14,7 @@ def db_conn():
conn.close()
@pytest.fixture()
@pytest.fixture
def db_session(db_conn):
session = Session(bind=db_conn)
yield session

View File

@ -21,7 +21,7 @@ def _difficulty(**kw):
return Difficulty(**defaults)
class Test_Chart:
class TestChart:
def init_db(self, session):
SongsBase.metadata.create_all(session.bind, checkfirst=False)
SongsViewBase.metadata.create_all(session.bind, checkfirst=False)

View File

@ -73,7 +73,9 @@ class TestPlayResultFormatter:
assert PlayResultFormatter.score_grade(5500000) == "D"
assert PlayResultFormatter.score_grade(0) == "D"
pytest.raises(ValueError, PlayResultFormatter.score_grade, -1)
with pytest.raises(ValueError, match="negative"):
PlayResultFormatter.score_grade(-1)
pytest.raises(TypeError, PlayResultFormatter.score_grade, "10001284")
pytest.raises(TypeError, PlayResultFormatter.score_grade, [])
pytest.raises(TypeError, PlayResultFormatter.score_grade, None)
@ -108,7 +110,9 @@ class TestPlayResultFormatter:
assert PlayResultFormatter.clear_type(1) == "NORMAL CLEAR"
assert PlayResultFormatter.clear_type(6) == "UNKNOWN"
pytest.raises(ValueError, PlayResultFormatter.clear_type, -1)
with pytest.raises(ValueError, match="negative"):
PlayResultFormatter.clear_type(-1)
pytest.raises(TypeError, PlayResultFormatter.clear_type, "1")
pytest.raises(TypeError, PlayResultFormatter.clear_type, [])
@ -121,6 +125,8 @@ class TestPlayResultFormatter:
assert PlayResultFormatter.modifier(1) == "EASY"
assert PlayResultFormatter.modifier(6) == "UNKNOWN"
pytest.raises(ValueError, PlayResultFormatter.modifier, -1)
with pytest.raises(ValueError, match="negative"):
PlayResultFormatter.modifier(-1)
pytest.raises(TypeError, PlayResultFormatter.modifier, "1")
pytest.raises(TypeError, PlayResultFormatter.modifier, [])