diff --git a/main.py b/main.py index 0a88718..9c31791 100644 --- a/main.py +++ b/main.py @@ -1,5 +1,6 @@ import sys from datetime import datetime, UTC +from functools import cmp_to_key from typing import Optional import os.path @@ -36,14 +37,48 @@ def main(): while True: state: StateT = storage.fetch_last_state() - state.do_tournament(names, _ask) + state.do_tournament(names, _rerank) storage.store_state(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(f" 0: {item0.name}") print(f" 1: {item1.name}") @@ -52,11 +87,11 @@ def _ask(item0: ItemT, item1: ItemT) -> Optional[ItemT]: while True: i = input("0/1/2> ") if i == "0": - return item0 + return -1 elif i == "1": - return item1 + return 1 elif i == "2": - return None + return 0 print(f"unexpected input: {i}") diff --git a/massranker/state.py b/massranker/state.py index 0ad2b75..1068630 100644 --- a/massranker/state.py +++ b/massranker/state.py @@ -37,7 +37,7 @@ class StateT(BaseModel): 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 self._bring_up_to_date(names) @@ -46,29 +46,21 @@ class StateT(BaseModel): if len(possible_entrants) < 2: raise ValueError("need at least two things to compare") - entrants = random.sample(possible_entrants, k=2) + entrants = random.sample(possible_entrants, k=min(len(possible_entrants), 8)) + expected_score = [0.0] * len(entrants) + score = [0.0] * len(entrants) - # ask for a winner - 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): + for e2, other in enumerate(entrants): + if e2 == e: + continue + expected_score[e] += expected(entrant.elo, other.elo) + score[e] += float(reranked.index(entrant) < reranked.index(other)) - if winner is None: - score_0 += 0.5 - score_1 += 0.5 - elif winner == entrants[0]: - score_0 += 1.0 - elif winner == entrants[1]: - score_1 += 1.0 - - expected_score_0 = expected(entrants[0].elo, entrants[1].elo) - expected_score_1 = expected(entrants[1].elo, entrants[0].elo) - # 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) + for e, entrant in enumerate(entrants): + entrant.elo = elo(entrant.elo, expected_score[e], score[e]) def dump_rankings(self) -> list[tuple[str, int]]: return [ diff --git a/ontologies/music/names.txt b/ontologies/music/names.txt index 86f3b38..b914de1 100644 --- a/ontologies/music/names.txt +++ b/ontologies/music/names.txt @@ -1,2 +1,71 @@ Saturday - Childish Gambino 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