Skip to content

Instantly share code, notes, and snippets.

@elibroftw
Last active April 7, 2026 00:41
Show Gist options
  • Select an option

  • Save elibroftw/50c0a82da1ce9fd7982d3c85699a81c4 to your computer and use it in GitHub Desktop.

Select an option

Save elibroftw/50c0a82da1ce9fd7982d3c85699a81c4 to your computer and use it in GitHub Desktop.
An easy way to rank items of your choosing, such as movies, tv shows, food/dishes.
import os
import itertools
import csv
MOVIES = '/media/elijah/Big Dipper/Videos/Movies'
TV_SHOWS = '/media/elijah/Big Dipper/Videos/TV Shows'
SELECTION = MOVIES
def get_dir_items(directory):
"""Return all top-level file names (without extension) and folder names in a directory."""
items = []
try:
for entry in os.listdir(directory):
full_path = os.path.join(directory, entry)
if entry.startswith('.'):
continue
if os.path.isdir(full_path):
items.append(entry)
else:
name, _ = os.path.splitext(entry)
items.append(name)
except FileNotFoundError:
print(f"Error: Directory '{directory}' not found.")
except PermissionError:
print(f"Error: Permission denied for '{directory}'.")
return items
def get_items():
items = get_dir_items(SELECTION)
if items:
print(f"\nFound {len(items)} item(s) in '{os.path.dirname(SELECTION)}':")
for i, item in enumerate(items, 1):
print(f" {i}. {item}")
else:
print("No items found.")
return items
def _elo_update(winner_rating, loser_rating, k=32):
"""Return updated (winner_rating, loser_rating) after one match."""
expected_winner = 1 / (1 + 10 ** ((loser_rating - winner_rating) / 400))
expected_loser = 1 - expected_winner
new_winner = winner_rating + k * (1 - expected_winner)
new_loser = loser_rating + k * (0 - expected_loser)
return new_winner, new_loser
def top_10(arr):
"""
Compare every pair from arr via user input, rank using Elo, and print the top 10.
Returns the full ranked list as [(item, elo_score), ...].
"""
if len(arr) < 2:
print("Need at least 2 items to compare.")
return []
# Initialise Elo ratings and loss counters
ratings = {item: 1000.0 for item in arr}
losses = {item: 0 for item in arr}
results = [] # store (winner, loser) tuples
AUTO_LOSS_THRESHOLD = 10
pairs = list(itertools.combinations(arr, 2))
total = len(pairs)
print(f"\nYou will be asked to choose the winner of {total} pair(s).\n")
for idx, (a, b) in enumerate(pairs, 1):
a_eliminated = losses[a] >= AUTO_LOSS_THRESHOLD
b_eliminated = losses[b] >= AUTO_LOSS_THRESHOLD
if a_eliminated and b_eliminated:
# Both are eliminated — award win to whoever has fewer losses (arbitrary tiebreak)
winner, loser = (a, b) if losses[a] <= losses[b] else (b, a)
print(f"[{idx}/{total}] Auto-loss (both eliminated): {loser} loses to {winner}")
elif a_eliminated:
winner, loser = b, a
print(f"[{idx}/{total}] Auto-loss ({a} has {losses[a]} losses): {winner} wins over {loser}")
elif b_eliminated:
winner, loser = a, b
print(f"[{idx}/{total}] Auto-loss ({b} has {losses[b]} losses): {winner} wins over {loser}")
else:
print(f"[{idx}/{total}] Which is better?")
print(f" 1. {a}")
print(f" 2. {b}")
while True:
choice = input("Enter 1 or 2: ").strip()
if choice == "1":
winner, loser = a, b
break
elif choice == "2":
winner, loser = b, a
break
else:
print(" Please enter 1 or 2.")
losses[loser] += 1
results.append((winner, loser))
ratings[winner], ratings[loser] = _elo_update(ratings[winner], ratings[loser])
print()
# Sort by Elo descending
ranked = sorted(ratings.items(), key=lambda x: x[1], reverse=True)
print("=" * 40)
print(" TOP 10 RESULTS")
print("=" * 40)
for rank, (item, score) in enumerate(ranked[:10], 1):
print(f" {rank:>2}. {item} (Elo: {score:.1f})")
print("=" * 40)
# Save full ranking to results.csv
with open(f"results-{os.path.dirname(SELECTION)}.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(["Rank", "Item", "Elo"])
for rank, (item, score) in enumerate(ranked, 1):
writer.writerow([rank, item, f"{score:.1f}"])
print("Results saved to results.csv")
return ranked
if __name__ == "__main__":
items = get_items()
if items:
top_10(items)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment