Skip to main content

Elote 🏆

PyPI version Python Versions License: MIT

Elote is a powerful Python library for implementing and comparing rating systems. Whether you're ranking chess players, sports teams, or prioritizing features in your product backlog, Elote provides a simple, elegant API for all your competitive ranking needs.

Table of Contents

Overview

Rating systems allow you to rank competitors based on their performance in head-to-head matchups. The most famous example is the Elo rating system used in chess, but these systems have applications far beyond sports:

  • Ranking products based on A/B comparisons
  • Prioritizing features through pairwise voting
  • Creating recommendation systems
  • Matchmaking in games and competitions
  • Collaborative filtering and ranking

Elote makes implementing these systems simple and intuitive, with a clean API that handles all the mathematical complexity for you.

Features

Currently implemented rating systems:

  • Elo - The classic chess rating system
  • Glicko-1 - An improvement on Elo that accounts for rating reliability
  • Glicko-2 - A further improvement on Glicko that adds volatility tracking
  • TrueSkill - Microsoft's Bayesian skill rating system for multiplayer games
  • ECF - The English Chess Federation rating system
  • DWZ - The Deutsche Wertungszahl (German evaluation number) system
  • Colley Matrix - A least-squares method that ranks competitors by solving a linear system
  • Bradley-Terry - A maximum-likelihood paired-comparison model on an Elo-compatible scale

You can also combine several systems into a single Ensemble (blended) competitor.

Installation

For Users

# Basic installation (core rating systems)
pip install elote

# With optional dataset support
pip install "elote[datasets]"

Optional Dependencies

Elote has optional dependencies for specific datasets:

  • Chess Dataset: Requires python-chess and pyzstd

    pip install python-chess pyzstd
    
  • College Football Dataset: Requires sportsdataverse

    pip install "sportsdataverse[all]"
    
  • All Datasets: Install all optional dependencies

    pip install "elote[datasets]"
    

For Developers

We use a modern Python packaging approach with pyproject.toml. Most things you need are in the Makefile:

# Using Make (recommended)
make install-dev

# Or using pip
pip install -e ".[dev]"

# Or using uv
uv pip install -e ".[dev]"

Requirements

  • Python 3.10 or higher

Quick Start

from elote import EloCompetitor

# Create two competitors with different initial ratings
player1 = EloCompetitor(initial_rating=1500)
player2 = EloCompetitor(initial_rating=1600)

# Get win probability
print(f"Player 2 win probability: {player2.expected_score(player1):.2%}")

# Record a match result
player1.beat(player2)  # Player 1 won!

# Ratings are automatically updated
print(f"Player 1 new rating: {player1.rating}")
print(f"Player 2 new rating: {player2.rating}")

Check Available Features

from elote import list_available_datasets, list_missing_datasets

# See which datasets are available
print("Available datasets:", list_available_datasets())

# See which datasets require additional dependencies
missing = list_missing_datasets()
for dataset in missing:
    print(f"Missing: {dataset['name']}")
    print(f"Install with: {dataset['error']}")

Usage Examples

Elote is built around two main concepts: Competitors and Arenas.

Competitors

Competitors represent the entities you're rating. Here's how to use them:

from elote import EloCompetitor

good = EloCompetitor(initial_rating=400)
better = EloCompetitor(initial_rating=500)

# Check win probabilities
print(f"Probability of better beating good: {better.expected_score(good):.2%}")
print(f"Probability of good beating better: {good.expected_score(better):.2%}")

Output:

Probability of better beating good: 64.01%
Probability of good beating better: 35.99%

If a match occurs, updating ratings is simple:

# If good wins (an upset!)
good.beat(better)
# OR
better.lost_to(good)

# Check updated probabilities
print(f"Probability of better beating good: {better.expected_score(good):.2%}")
print(f"Probability of good beating better: {good.expected_score(better):.2%}")

Output:

Probability of better beating good: 61.25%
Probability of good beating better: 38.75%

Arenas

Arenas handle large numbers of matchups automatically. The LambdaArena takes a comparison function and manages all competitors for you:

from elote import LambdaArena
import json
import random

# Define a comparison function (returns True if a beats b)
def comparison(a, b):
    return a > b

# Generate 1000 random matchups between numbers 1-10
matchups = [(random.randint(1, 10), random.randint(1, 10)) for _ in range(1000)]

# Create arena and run tournament
arena = LambdaArena(comparison)
arena.tournament(matchups)

# Display final rankings
print("Arena results:")
print(json.dumps(arena.leaderboard(), indent=4))

This example effectively implements a sorting algorithm using a rating system - not efficient, but demonstrates how Elote works with any comparable objects!

Development

The project includes a Makefile that simplifies common development tasks:

# Run tests
make test

# Run tests with coverage
make test-cov

# Lint code
make lint

# Auto-fix linting issues
make lint-fix

# Format code
make format

# Build package
make build

# Build documentation
make docs

Contributing

Contributions are welcome! If you'd like to help improve Elote:

  1. Check the issues for open tasks
  2. Fork the repository
  3. Create a feature branch
  4. Add your changes
  5. Submit a pull request

For major changes, please open an issue first to discuss what you'd like to change.

Blog Posts

Here are some blog posts about Elote:

References

  1. Glicko Rating System
  2. Glicko-2 Rating System
  3. Massey Ratings
  4. Elo, Arpad (1978). The Rating of Chessplayers, Past and Present. Arco. ISBN 0-668-04721-6.
  5. ECF Grading System
  6. Deutsche Wertungszahl
  7. TrueSkill: A Bayesian Skill Rating System

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

elote-1.2.0.tar.gz (98.7 kB view details)

Uploaded Source

File details

Details for the file elote-1.2.0.tar.gz.

File metadata

  • Download URL: elote-1.2.0.tar.gz
  • Upload date:
  • Size: 98.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for elote-1.2.0.tar.gz
Algorithm Hash digest
SHA256 b75805095a4d9d707e18678f80c59f94fe31abf0e466386f9404e05a21179308
MD5 8530e96b803be941367bb60d906c7950
BLAKE2b-256 7d7e85a1b527050d9344f052b75364925597e333716ec345bc2a725372a11cf8

See more details on using hashes here.

Provenance

The following attestation bundles were made for elote-1.2.0.tar.gz:

Publisher: pypi-publish.yml on wdm0006/elote

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

1.2.1

1 file

This release

1.2.0 This release

1 file

1.1.0

1 file

1.0.0

1 file

0.1.0

2 files

0.0.5

2 files

0.0.1

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page