Compare commits
No commits in common. "ac1217f29d452319e0a48e910250f6fa320c17cb" and "ab7a31d6bf6d9dfa4cf12e05537b7d353abbba20" have entirely different histories.
ac1217f29d
...
ab7a31d6bf
45
main.py
45
main.py
@ -1,6 +1,5 @@
|
|||||||
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
|
||||||
|
|
||||||
@ -37,48 +36,14 @@ def main():
|
|||||||
|
|
||||||
while True:
|
while True:
|
||||||
state: StateT = storage.fetch_last_state()
|
state: StateT = storage.fetch_last_state()
|
||||||
state.do_tournament(names, _rerank)
|
state.do_tournament(names, _ask)
|
||||||
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)}
|
|
||||||
|
|
||||||
while len(remaining) > 1:
|
def _ask(item0: ItemT, item1: ItemT) -> Optional[ItemT]:
|
||||||
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}")
|
||||||
@ -87,11 +52,11 @@ def _ask(item0: ItemT, item1: ItemT) -> int:
|
|||||||
while True:
|
while True:
|
||||||
i = input("0/1/2> ")
|
i = input("0/1/2> ")
|
||||||
if i == "0":
|
if i == "0":
|
||||||
return -1
|
return item0
|
||||||
elif i == "1":
|
elif i == "1":
|
||||||
return 1
|
return item1
|
||||||
elif i == "2":
|
elif i == "2":
|
||||||
return 0
|
return None
|
||||||
print(f"unexpected input: {i}")
|
print(f"unexpected input: {i}")
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
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, Field
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from massranker.elo import expected, elo
|
from massranker.elo import expected, elo
|
||||||
|
|
||||||
@ -10,7 +11,6 @@ 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[[list[ItemT]], list[ItemT]]):
|
def do_tournament(self, names: list[str], callback: Callable[[ItemT, ItemT], Optional[ItemT]]):
|
||||||
# bring up to date
|
# bring up to date
|
||||||
self._bring_up_to_date(names)
|
self._bring_up_to_date(names)
|
||||||
|
|
||||||
@ -46,37 +46,29 @@ 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")
|
||||||
|
|
||||||
# build a sample
|
entrants = random.sample(possible_entrants, k=2)
|
||||||
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
|
|
||||||
|
|
||||||
expected_score = [0.0] * len(entrants)
|
# ask for a winner
|
||||||
score = [0.0] * len(entrants)
|
winner = callback(entrants[0], entrants[1])
|
||||||
|
|
||||||
reranked = callback(list(entrants))
|
# update elo
|
||||||
|
score_0 = 0.0
|
||||||
|
score_1 = 0.0
|
||||||
|
|
||||||
for e, entrant in enumerate(entrants):
|
if winner is None:
|
||||||
for e2, other in enumerate(entrants):
|
score_0 += 0.5
|
||||||
if e2 == e:
|
score_1 += 0.5
|
||||||
continue
|
elif winner == entrants[0]:
|
||||||
expected_score[e] += expected(entrant.elo, other.elo)
|
score_0 += 1.0
|
||||||
score[e] += float(reranked.index(entrant) < reranked.index(other))
|
elif winner == entrants[1]:
|
||||||
|
score_1 += 1.0
|
||||||
|
|
||||||
for e, entrant in enumerate(entrants):
|
expected_score_0 = expected(entrants[0].elo, entrants[1].elo)
|
||||||
entrant.elo = elo(entrant.elo, expected_score[e], score[e])
|
expected_score_1 = expected(entrants[1].elo, entrants[0].elo)
|
||||||
entrant.times_seen += 1
|
# assert expected_score_0 == 1 - expected_score_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 [
|
||||||
|
@ -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 10);
|
(SELECT id FROM states ORDER BY id DESC LIMIT 100);
|
||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
c.execute("COMMIT;")
|
c.execute("COMMIT;")
|
||||||
|
@ -1,174 +1,2 @@
|
|||||||
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
|
|
Loading…
Reference in New Issue
Block a user