Skip to content

Instantly share code, notes, and snippets.

@SuperSonicHub1
Created March 30, 2025 16:09
Show Gist options
  • Save SuperSonicHub1/1870b688c672fde3dddfc057e3a39b49 to your computer and use it in GitHub Desktop.
Save SuperSonicHub1/1870b688c672fde3dddfc057e3a39b49 to your computer and use it in GitHub Desktop.
Personal best progression comparison tool for TETR.IO
from datetime import datetime, timedelta
from requests import get
from requests.exceptions import HTTPError
import matplotlib.pyplot as plt
import timple
import timple.timedelta as tmpldelta
tmpl = timple.Timple()
tmpl.enable()
BASE = "https://ch.tetr.io/api"
AGENT = 'kawcco/tetr-io-plot'
def personal_records(user: str, game_mode: str = '40l', leaderboard: str = 'progression', limit: int = 100) -> dict:
url = f'{BASE}/users/{user}/records/{game_mode}/{leaderboard}'
res = get(url, params=dict(limit=limit), headers={"User-Agent": AGENT, "X-Session-ID": AGENT})
res.raise_for_status()
body: dict = res.json()
assert body['success'] == True
return body['data']
def process_record(record: dict) -> dict:
return dict(
id=record['_id'],
ts=datetime.fromisoformat(record['ts']),
time=timedelta(milliseconds=record['results']['stats']['finaltime'])
)
gamers = [
'kawcco',
'k1tsun8',
]
try:
records_by_gamer = {
gamer: [
dict(index=i, **process_record(record))
for i, record in enumerate(reversed(personal_records(gamer)['entries']))
]
for gamer in gamers
}
except HTTPError as e:
print(e.response.text)
ax = plt.subplot()
locator = tmpldelta.AutoTimedeltaLocator()
formatter = tmpldelta.TimedeltaFormatter(r"%M:%s")
ax.yaxis.set_major_locator(locator)
ax.yaxis.set_major_formatter(formatter)
ax.set_title("Personal best progression in TETR.IO 40L")
ax.set_xlabel("$n$th PB")
ax.set_ylabel("Final time (minutes:seconds)")
for gamer, records in records_by_gamer.items():
ax.plot(
[record['index'] for record in records],
[record['time'] for record in records],
label=gamer,
)
plt.legend()
plt.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment