top500albums/AGENTS.md
2026-01-22 10:25:07 +01:00

5 KiB

AGENTS.md

This file provides guidance for AI coding agents working in this repository.

Project Overview

Top 500 Albums analysis with data from Rolling Stone (2020) and Wikipedia (2023). Includes Python data processing scripts, an interactive web interface (vanilla HTML/CSS/JS), and album cover artwork from the iTunes API.

Build/Lint/Test Commands

No formal build system. All Python scripts use only the standard library.

# Run Python scripts directly
python scripts/download_all_covers.py
python scripts/compare_top500_albums.py

# Local dev server (required for CORS)
python -m http.server 8000

No tests or linting configured. Manual testing only - run scripts and verify output, open website and check functionality.

Code Style Guidelines

Python

#!/usr/bin/env python3
"""Module docstring explaining the script's purpose."""

import csv
import json
import os
import re
from typing import Dict, List, Optional, Tuple

# Constants: UPPER_SNAKE_CASE
MAX_RETRIES = 3

# Functions/variables: snake_case
def normalize_text(text: str) -> str:
    """Normalize text for comparison."""
    pass

albums_2020 = {}

Key patterns:

  • Always use shebang: #!/usr/bin/env python3
  • Include module-level docstring
  • Standard library only - no external dependencies
  • Type hints for function signatures
  • Use encoding='utf-8' and newline='' for CSV operations

Error handling:

try:
    with urllib.request.urlopen(url, timeout=15) as response:
        data = json.loads(response.read().decode())
except Exception as e:
    print(f"Error: {e}")
    return None

JavaScript

// Global variables at top
let albumsData = [];
const itemsPerPage = 50;

// DOM refs cached on load
const albumsGrid = document.getElementById('albumsGrid');

// Initialize on DOMContentLoaded
document.addEventListener('DOMContentLoaded', function() {
    loadData();
});

// Async/await for fetch
async function loadAlbumsData() {
    try {
        const response = await fetch('data.csv');
        if (!response.ok) throw new Error('Failed');
        // ...
    } catch (err) {
        console.error('Error:', err);
    }
}

Key patterns:

  • Variables/functions: camelCase
  • Use console.warn() for non-critical failures
  • Vanilla JS only - no frameworks

HTML/CSS

  • Semantic HTML5 elements
  • CSS custom properties for theming
  • Responsive design with Grid/Flexbox

Accessibility Requirements

All UI changes must follow WCAG 2.1 AA guidelines:

Keyboard Navigation:

  • All interactive elements must be keyboard accessible
  • Use tabindex appropriately (0 for focusable, -1 for programmatic focus)
  • Implement visible focus indicators (:focus-visible with outline)
  • Support skip links for main content

Screen Readers:

  • Use semantic HTML (<button>, <nav>, <main>, <article>)
  • Add ARIA labels for icon-only buttons: aria-label="Share album"
  • Use .sr-only class for screen-reader-only text
  • Ensure proper heading hierarchy (h1 > h2 > h3)

Color & Contrast:

  • Minimum 4.5:1 contrast ratio for normal text
  • Minimum 3:1 for large text and UI components
  • Never use color alone to convey information

Motion & Animations:

  • Respect prefers-reduced-motion media query
  • Avoid layout shifts on hover (no transform: translateY() on cards)

Focus Management:

  • Trap focus in modals/dialogs
  • Return focus to trigger element when closing overlays

Existing Patterns:

/* Screen reader only */
.sr-only { position: absolute; width: 1px; height: 1px; ... }

/* Focus indicators */
button:focus-visible { outline: 2px solid var(--primary-color); outline-offset: 2px; }

/* Reduced motion */
@media (prefers-reduced-motion: reduce) { ... }

Project Structure

top500albums/
├── index.html, script.js, styles.css  # Website
├── *.csv, *.json                       # Data files
├── covers/                             # Album artwork (500 images)
└── scripts/                            # Python utilities (36 scripts)

Data Files

File Notes
rolling_stone_top_500_albums_2020.csv Title case columns, ranks in reverse order
wikipedia_top_500_albums.csv Lowercase columns (rank, artist, album)
top_500_albums_2023.csv Combined comparison file

Key Patterns

CSV column naming:

  • Rolling Stone/Combined: Title case (Rank, Artist, Album)
  • Wikipedia: lowercase (rank, artist, album)

Album matching: Uses difflib for fuzzy matching variations like "The Beatles" vs "Beatles"

API rate limiting: time.sleep(1.2) between requests

Common Tasks

New Python script:

  1. Create in scripts/, add shebang + docstring
  2. Standard library only
  3. Include if __name__ == "__main__": block

Working with album data:

import csv
with open('top_500_albums_2023.csv', 'r', encoding='utf-8') as f:
    for row in csv.DictReader(f):
        rank, artist, album = int(row['Rank']), row['Artist'], row['Album']
        status = row['Status']  # "New in 2023", "+10", "-5", "No change"