update
This commit is contained in:
75
backend/app/punkte.py
Normal file
75
backend/app/punkte.py
Normal file
@@ -0,0 +1,75 @@
|
||||
"""Erfahrung und Level — berechnet, nicht gebucht.
|
||||
|
||||
Punkte sind eine Formel über dem, was gerade in der Datenbank steht:
|
||||
wer dabei war, bewertet, kommentiert, geantwortet und ein Herz gegeben
|
||||
hat. Nimmt jemand seine Wertung zurück, sind die Punkte weg. Es gibt
|
||||
kein Konto, das man pflegen oder austricksen könnte.
|
||||
|
||||
Je Film zählt jede Art nur einmal. Level nach Dreieckszahlen: Level L
|
||||
ist erreicht, sobald L·(L−1)/2 Punkte da sind — anfangs schnell, dann
|
||||
stetig langsamer, aber immer in Reichweite.
|
||||
"""
|
||||
|
||||
from math import isqrt
|
||||
|
||||
from .db import connect
|
||||
|
||||
SCHAUEN = 10
|
||||
BEWERTEN = 3
|
||||
KOMMENTAR = 5
|
||||
ANTWORT = 2
|
||||
HERZ = 1
|
||||
|
||||
ZAEHLUNGEN = (
|
||||
(SCHAUEN, "SELECT user_id, COUNT(*) AS n FROM watched_dabei GROUP BY user_id"),
|
||||
(
|
||||
BEWERTEN,
|
||||
"SELECT user_id, COUNT(DISTINCT watched_id) AS n FROM ratings "
|
||||
"WHERE user_id IS NOT NULL GROUP BY user_id",
|
||||
),
|
||||
(
|
||||
KOMMENTAR,
|
||||
"SELECT user_id, COUNT(DISTINCT watched_id) AS n FROM watched_notes "
|
||||
"WHERE user_id IS NOT NULL AND parent_id IS NULL GROUP BY user_id",
|
||||
),
|
||||
(
|
||||
ANTWORT,
|
||||
"SELECT user_id, COUNT(DISTINCT watched_id) AS n FROM watched_notes "
|
||||
"WHERE user_id IS NOT NULL AND parent_id IS NOT NULL GROUP BY user_id",
|
||||
),
|
||||
(
|
||||
HERZ,
|
||||
"SELECT h.user_id, COUNT(DISTINCT n.watched_id) AS n FROM watched_hearts h "
|
||||
"JOIN watched_notes n ON n.id = h.note_id "
|
||||
"WHERE h.user_id IS NOT NULL GROUP BY h.user_id",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def level(punkte):
|
||||
"""Größtes L mit L·(L−1)/2 ≤ Punkte. Null Punkte sind Level 1."""
|
||||
stufe = (1 + isqrt(1 + 8 * punkte)) // 2
|
||||
while stufe * (stufe - 1) // 2 > punkte:
|
||||
stufe -= 1
|
||||
return max(1, stufe)
|
||||
|
||||
|
||||
def stand(punkte):
|
||||
stufe = level(punkte)
|
||||
return {
|
||||
"punkte": punkte,
|
||||
"level": stufe,
|
||||
# Wo das aktuelle Level begann und wo das nächste anfängt — für den Balken
|
||||
"von": stufe * (stufe - 1) // 2,
|
||||
"bis": stufe * (stufe + 1) // 2,
|
||||
}
|
||||
|
||||
|
||||
def alle():
|
||||
"""Punktestand je user_id."""
|
||||
summen = {}
|
||||
with connect() as conn:
|
||||
for wert, sql in ZAEHLUNGEN:
|
||||
for row in conn.execute(sql):
|
||||
summen[row["user_id"]] = summen.get(row["user_id"], 0) + wert * row["n"]
|
||||
return {user_id: stand(p) for user_id, p in summen.items()}
|
||||
Reference in New Issue
Block a user