Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions app/api/v1/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import app.usecases.performance
from app.constants import regexes
from app.constants.gamemodes import GameMode
from app.constants.level import get_level
from app.constants.level import get_level_precise
from app.constants.mods import Mods
from app.objects.beatmap import Beatmap
from app.objects.beatmap import ensure_osu_file_is_available
Expand Down Expand Up @@ -263,6 +265,14 @@ async def api_get_player_info(
# extra fields are added to the api response
"rank": rank + 1 if rank is not None else 0,
"country_rank": country_rank + 1 if country_rank is not None else 0,
"level": get_level(int(mode_stats["tscore"])),
"level_progress": int(
(
get_level_precise(mode_stats["tscore"])
- get_level(mode_stats["tscore"])
)
* 100,
),
}

return ORJSONResponse({"status": "success", "player": api_data})
Expand Down
2 changes: 2 additions & 0 deletions app/api/v2/models/players.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,5 @@ class PlayerStats(BaseModel):
sh_count: int
s_count: int
a_count: int
level: int
level_progress: int
9 changes: 9 additions & 0 deletions app/api/v2/players.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
from app.api.v2.models.players import Player
from app.api.v2.models.players import PlayerStats
from app.api.v2.models.players import PlayerStatus
from app.constants.level import get_level
from app.constants.level import get_level_precise
from app.repositories import stats as stats_repo
from app.repositories import users as users_repo

Expand Down Expand Up @@ -108,6 +110,13 @@ async def get_player_mode_stats(
)

response = PlayerStats.from_mapping(data)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add level and level_progress to data instead. this will cause issues when instantiated otherwise as pydantic will not be happy about these values missing


# NOTE: kinda cursed, but that should do it
response.level = get_level(int(data["tscore"]))
response.level_progress = int(
(get_level_precise(data["tscore"]) - get_level(data["tscore"])) * 100,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this specific pattern seems to repeat itself quite a lot. could we have a function that returns a tuple of level and level_progress instead and use that where needed?

)

return responses.success(response)


Expand Down
141 changes: 141 additions & 0 deletions app/constants/level.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
from __future__ import annotations

import math

LEVEL_GRAPH = [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
LEVEL_GRAPH = [
LEVEL_GRAPH: list[int] = [

0,
30000,
130000,
340000,
700000,
1250000,
2030000,
3080000,
4440000,
6150000,
8250000,
10780000,
13780000,
17290000,
21350000,
26000000,
31280000,
37230000,
43890000,
51300000,
59500000,
68530000,
78430000,
89240000,
101000000,
113750000,
127530000,
142380000,
158340000,
175450000,
193750000,
213280000,
234080000,
256190000,
279650000,
304500000,
330780000,
358530000,
387790000,
418600000,
451000000,
485030000,
520730000,
558140000,
597300000,
638250000,
681030000,
725680000,
772240000,
820750000,
871250000,
923780000,
978380000,
1035090000,
1093950000,
1155000000,
1218280000,
1283830000,
1351690001,
1421900001,
1494500002,
1569530004,
1647030007,
1727040013,
1809600024,
1894750043,
1982530077,
2072980138,
2166140248,
2262050446,
2360750803,
2462281446,
2566682603,
2673994685,
2784258433,
2897515180,
3013807324,
3133179183,
3255678529,
3381359353,
3510286835,
3642546304,
3778259346,
3917612824,
4060911082,
4208669948,
4361785907,
4521840633,
4691649139,
4876246450,
5084663609,
5333124496,
5650800094,
6090166168,
6745647103,
7787174786,
9520594614,
12496396305,
17705429349,
26931190829,
]


def get_required_score_for_level(level: int) -> int:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i am ..not sure how i feel about functions living in constants?

if level <= 0:
return 0
if level <= 100:
return LEVEL_GRAPH[level - 1]
return LEVEL_GRAPH[99] + 100000000000 * int(level - 100)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return LEVEL_GRAPH[99] + 100000000000 * int(level - 100)
return LEVEL_GRAPH[99] + 100_000_000_000 * int(level - 100)



def get_level(score: int) -> int:
if score <= 0:
return 1

if score >= LEVEL_GRAPH[99]:
return 100 + int((score - LEVEL_GRAPH[99]) / 100000000000)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return 100 + int((score - LEVEL_GRAPH[99]) / 100000000000)
return 100 + int((score - LEVEL_GRAPH[99]) / 100_000_000_000)


for idx, v in enumerate(LEVEL_GRAPH, start=0):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you probably want bisect.bisect_left(LEVEL_GRAPH, score) instead

https://docs.python.org/3/library/bisect.html

if v > score:
return idx

return 1


def get_level_precise(score: int) -> float:
baseLevel = get_level(score)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
baseLevel = get_level(score)
base_level = get_level(score)

etc, use pep8 naming please

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should lint/autofix this if possible, maybe there's a pre-commit hook for it

baseLevelScore = get_required_score_for_level(baseLevel)
scoreProgress = score - baseLevelScore
scoreLevelDifference = get_required_score_for_level(baseLevel + 1) - baseLevelScore

res = float(scoreProgress) / float(scoreLevelDifference) + float(baseLevel)
if math.isinf(res) or math.isnan(res):
return 0

return res
Loading