Compare commits

..

2 Commits

4 changed files with 244 additions and 29 deletions

45
main.py
View File

@ -1,5 +1,6 @@
import sys import sys
from datetime import datetime, UTC from datetime import datetime, UTC
from functools import cmp_to_key
from typing import Optional from typing import Optional
import os.path import os.path
@ -36,14 +37,48 @@ def main():
while True: while True:
state: StateT = storage.fetch_last_state() state: StateT = storage.fetch_last_state()
state.do_tournament(names, _ask) state.do_tournament(names, _rerank)
storage.store_state(state) storage.store_state(state)
_write_rankings(state) _write_rankings(state)
def _rerank(items: list[ItemT]) -> list[ItemT]:
results = []
remaining = {ix: value for ix, value in enumerate(items, 1)}
def _ask(item0: ItemT, item1: ItemT) -> Optional[ItemT]: while len(remaining) > 1:
print("Pick your favorite(s): ")
for ix, i in remaining.items():
print(f"{ix: >4}. {i.name}")
while True:
choices = input("> ")
for choice in choices:
try:
choice_ix = int(choice)
except ValueError:
print(f"not a number: {choice}")
continue
if choice_ix not in remaining:
print(f"not a valid index: {choice_ix}")
continue
results.append(remaining.pop(choice_ix))
if len(choices) > 0:
break
assert len(remaining) <= 1
if remaining:
results.append(next(iter(remaining.values())))
return results
def _ask(item0: ItemT, item1: ItemT) -> int:
print("Which do you prefer?") print("Which do you prefer?")
print(f" 0: {item0.name}") print(f" 0: {item0.name}")
print(f" 1: {item1.name}") print(f" 1: {item1.name}")
@ -52,11 +87,11 @@ def _ask(item0: ItemT, item1: ItemT) -> Optional[ItemT]:
while True: while True:
i = input("0/1/2> ") i = input("0/1/2> ")
if i == "0": if i == "0":
return item0 return -1
elif i == "1": elif i == "1":
return item1 return 1
elif i == "2": elif i == "2":
return None return 0
print(f"unexpected input: {i}") print(f"unexpected input: {i}")

View File

@ -1,9 +1,8 @@
import math
import random import random
from collections.abc import Callable from collections.abc import Callable
from datetime import datetime, UTC, timedelta
from typing import Optional
from pydantic import BaseModel from pydantic import BaseModel, Field
from massranker.elo import expected, elo from massranker.elo import expected, elo
@ -11,6 +10,7 @@ class ItemT(BaseModel):
name: str name: str
elo: float elo: float
enabled: bool enabled: bool
times_seen: int = Field(default=0)
class StateT(BaseModel): class StateT(BaseModel):
@ -37,7 +37,7 @@ class StateT(BaseModel):
enabled=True, enabled=True,
)) ))
def do_tournament(self, names: list[str], callback: Callable[[ItemT, ItemT], Optional[ItemT]]): def do_tournament(self, names: list[str], callback: Callable[[list[ItemT]], list[ItemT]]):
# bring up to date # bring up to date
self._bring_up_to_date(names) self._bring_up_to_date(names)
@ -46,29 +46,37 @@ class StateT(BaseModel):
if len(possible_entrants) < 2: if len(possible_entrants) < 2:
raise ValueError("need at least two things to compare") raise ValueError("need at least two things to compare")
entrants = random.sample(possible_entrants, k=2) # build a sample
sample_size = min(len(possible_entrants), 8)
if sample_size == len(possible_entrants):
entrants = random.sample(possible_entrants, k=sample_size)
else:
# this is a messy way to take a weighted random sample
picked = []
while len(picked) < sample_size:
remaining_possible_entrants = [i for i in possible_entrants if i not in picked]
weights = [1/(e.times_seen + 1) for e in remaining_possible_entrants]
for i in random.choices(remaining_possible_entrants, weights=weights, k=sample_size - len(picked)):
if i not in picked:
picked.append(i)
random.shuffle(picked)
entrants = picked
# ask for a winner expected_score = [0.0] * len(entrants)
winner = callback(entrants[0], entrants[1]) score = [0.0] * len(entrants)
# update elo reranked = callback(list(entrants))
score_0 = 0.0
score_1 = 0.0
if winner is None: for e, entrant in enumerate(entrants):
score_0 += 0.5 for e2, other in enumerate(entrants):
score_1 += 0.5 if e2 == e:
elif winner == entrants[0]: continue
score_0 += 1.0 expected_score[e] += expected(entrant.elo, other.elo)
elif winner == entrants[1]: score[e] += float(reranked.index(entrant) < reranked.index(other))
score_1 += 1.0
expected_score_0 = expected(entrants[0].elo, entrants[1].elo) for e, entrant in enumerate(entrants):
expected_score_1 = expected(entrants[1].elo, entrants[0].elo) entrant.elo = elo(entrant.elo, expected_score[e], score[e])
# assert expected_score_0 == 1 - expected_score_1 entrant.times_seen += 1
entrants[0].elo = elo(entrants[0].elo, expected_score_0, score_0)
entrants[1].elo = elo(entrants[1].elo, expected_score_1, score_1)
def dump_rankings(self) -> list[tuple[str, int]]: def dump_rankings(self) -> list[tuple[str, int]]:
return [ return [

View File

@ -50,7 +50,7 @@ class Storage(object):
""" """
DELETE FROM states DELETE FROM states
WHERE id NOT IN WHERE id NOT IN
(SELECT id FROM states ORDER BY id DESC LIMIT 100); (SELECT id FROM states ORDER BY id DESC LIMIT 10);
""", """,
) )
c.execute("COMMIT;") c.execute("COMMIT;")

View File

@ -1,2 +1,174 @@
Saturday - Childish Gambino Saturday - Childish Gambino
Alice - Moby (Noisia Remix) Alice - Moby (Noisia Remix)
103 Degrees - Spor
Good Luck - Basement Jaxx
Rendez-Vu - Basement Jaxx
Mermaid of Salinas - Basement Jaxx
Do You Know Squarepusher - Squarepusher
A Soft Seduction - David Byrne
Army Dreamers - Kate Bush
The Long Honeymoon - Elvis Costello
Just Like Heaven - The Cure
Blood Red - Feed Me
It's Working - MGMT
Your Woman - White Town
Shimmy Shimmy Ya - Old Dirty Bastard
Ancient Voices - Russell Landau
Parade - Susumu Hirasawa
Casino Royale - Herb Alpert
Instant Crush - Daft Punk
Crazy - Gnarls Barkley
Alone Again Or - Love
Stars - Nina Simone
Alright - Kendrick Lamar
Hayloft - Mother Mother
Lola - The Kinks
Mandalay Song - Kurt Weill
Dance Anthem of the 80s - Regina Spektor
Cannibal Holocaust - Riz Ortolani
Kiss From A Rose - Seal
Shemokmedura - Basiani Ensemble
Not Like Us - Kendrick Lamar
It's Alright - Jack Stauber
Barracuda - John Cale
My Party - Kero Kero Bonito (bo en remix)
The Lovecats - The Cure
PREMIERE - AQUASINE
See Emily Play - Pink FLoyd
Little Wing - Jimi Hendrix
Girlfriend Is Better - Talking Heads
SNUFFY - Metaroom
KEYWING #001 - AQUASINE
Balatro Main Theme - ???
People Who Died - The Jim Carroll Band
Live (Big Brother Theme) - ???
Classical Gas - Mason Williams
Misirlou - Dick Dale
Alfonso Muskedunder - Todd Terje
Hey Kids - Molina
Scared - Mzekezeke
classic j dies and goes to hell part 1 - glass beach
Everything's Alright - Ginger Root
Red Dress - Sarah Brand
Unfunky UFO - Parliament
Babooshka - Kate Bush
Mr. Greives [sic] - TV on the Radio
Ready For The Floor - Hot Chip
Since I Left You - The Avalanches
She Said She Said - Beatles
Omen - The Prodigy
Eli Eli - Misun (Maduk Remix)
Blac - Qntal
Self-Aware Wolf - Loden (feat. Busdriver)
Goodbye - Paul McCartney
Ffunny Ffrends - Unknown Mortal Orchestra
Multi-Love - Unknown Mortal Orchestra
The Parasite - Eugene McDaniels
Here Comes The Sun - Bill Wurtz
Song For Dan Treacy - MGMT
Eyesore - Women
Paris 1919 - John Cale
Baby Hotline - Jack Stauber
Condition Boy - Susumu Hirasawa
Shutterbugg - Big Boi
Good King Moggle Mog - ???
Superman - Goldfinger
The Chase - Giorgio Moroder
Oh Klahoma - Jack Stauber
I'm The President - KNOWER
Elephant Gun - Beirut
Atomic Dog - George Clinton
Oh Ana - Mother Mother
The Chain - Fleetwood Mac
Dreams - Fleetwood Mac
Spanish Stroll - Mink DeVille
Under Pressure - Queen & David Bowie
Dr. Mabuse - Propaganda
Paranoid Android - Radiohead
Idioteque - Radiohead
There Is a Light That Never Goes Out - The Smiths
A Rush and a Push and the Land Is Ours - The Smiths
This Charming Man - The Smiths
Youkali - Teresa Stratas & Kurt Weill
Killing Me Softly With His Song - Fugees
Shallow - Lady Gaga & Bradley Cooper
Notjustmoreidlechatter - Paul Lansky
Fantasy Is Reality - Parliament
All I Do - Stevie Wonder
Alabama Song - Kurt Weill
Drain You - Nirvana
Swirls - Alex Seropian
Werewolf - CocoRosie
Beautiful Boyz - CocoRosie
Teen Pregnancy - Blank Banshee
Death of Samantha - Yoko Ono
Bonnie And Clyde - Brigitte Bardot & Serge Gainsbourg
Ella, elle l'a - France Gall
Marcia Baila - Les Rita Mitsouko
Your Way - Netsky
I Wish - Skee-Lo
Hey Ya! - Outkast
Roses - Outkast
Ms. Jackson - Outkast
Bombs Over Baghdad - Outkast
Waters of March - Antonio Carlos Jobim
Gotta Get Up - Harry Nilsson
Life During Wartime - Talking Heads
Computer Age - Newcleus
Popcorn - Gershon Kingsley
Doctor Worm - They Might Be Giants
Mermaid Sashimi - Juan Son
Rock Lobster - The B-52s
Electric To Me Turn - Bruce Haack
Ana Ng - They Might Be Giants
The Alcoholic - Royksopp
Senior Living - Royksopp
Smack My Bitch Up - The Prodigy
Fill Your Heart - David Bowie
Oh! You Pretty Things - David Bowie
Little Dark Age - MGMT
Drain You - Nirvana
Jugband Blues - Pink Floyd
Hotel California - Eagles
Angela - Bob James
Les Fleurs - Minnie Riperton
Fare Thee Well, Miss Carousel - Townes Van Zandt
Randy - Justice
DANCE - Justice
Canon - Justice
Eid Ma Clack Shaw - Bill Callahan
Das Modell - Kraftwerk
Zum Projekt - Paniq
Rattengift - Paniq
Talkin' Like You - Connie Converse
Playboy of the Western World - Connie Converse
Laura - Bat For Lashes
Breathe - Prodigy
Didn't You Hear? - Mort Garson
Girl, You'll Be a Woman Soon - Urge Overkill
The Chain - Fleetwood Mac
Dear Angie - Badfinger
Vincent - Don McLean
American Pie - Don McLean
Rhiannon - Fleetwood Mac
Big Kitten - Feed Me
Komm, Susser Tod - Arianne
Misty - Erroll Garner
Couldn't Call It Unexpected No. 4 - Elvis Costello
Radio Radio - Elvis Costello
Long Road Home - Oneohtrix Point Never
Sexy Sadie - The Beatles
Money Don't Matter 2 Night - Prince
Fanfare for naran ratan - naran ratan
Plantasia - Mort Garson
Lay Down (Candles In The Rain) - Melanie & The Edwin Hawkins Singers
Promises I've Made - Emitt Rhodes
Harakiri - Serj Tankian
Ordinary Joe - Terry Callier
Red Alert - Basement Jaxx
Rock 'n' Roll Suicide - David Bowie
Where's Your Head At? - Basement Jaxx
Strangers - The Kinks
High On A Rocky Ledge - Moondog
Starman - David Bowie
Born Slippy - Underworld