Nano Banana Pro
Agent skill for nano-banana-pro
This document provides guidelines for AI agents working on this algorithms repository.
Sign in to like and favorite skills
This document provides guidelines for AI agents working on this algorithms repository.
All Python scripts should use nix shebangs for dependency management:
#! /usr/bin/env nix-shell #! nix-shell -i python3 -p python313 -p python313Packages.loguru -p python313Packages.pytest -p python313Packages.pyvis -p python313Packages.more-itertools -p python313Packages.click
Benefits:
Standard dependencies for most scripts:
python313 - Python 3.13 interpreterpython313Packages.loguru - Enhanced loggingpython313Packages.pytest - Testing frameworkpython313Packages.click - CLI frameworkpython313Packages.pyvis - Network visualization (when needed)python313Packages.more-itertools - Additional iterator toolsAll executable scripts should use Click for command-line interfaces:
cli = click.Group() @cli.command() @click.option("--param", "-p", default=value, help="Description") def example(param: type): """Command description.""" # Implementation if __name__ == "__main__": cli()
Benefits:
Tests should be defined inline within the same file:
@pytest.mark.parametrize( "input, expected", [ (test_case_1, expected_1), (test_case_2, expected_2), ], ) def test_function(input, expected): result = function(input) assert result == expected @cli.command("test") def run_tests(): pytest.main([__file__])
Benefits:
python script.py testAlways include a
if __name__ == "__main__": block:
if __name__ == "__main__": cli() # or main() function
Use abstract types from
collections.abc:
from collections.abc import Mapping, Sequence, MutableSequence def function(data: Sequence[float]) -> Mapping[str, int]: # Implementation
Prefer immutable types when possible:
Sequence over MutableSequence for read-only dataMapping over dict for read-only mappingsMutableSequence when actually modifying collectionsUse modern Python 3.10+ union syntax:
def function(param: str | Path) -> tuple[Sequence[float], Mapping[str, int]]: # Implementation
Functions should return immutable interfaces (
Sequence, Mapping, etc.) whenever possible. Only return mutable collections when callers need to mutate the result later.
Prefer the
thing_to_other pattern for mappings (e.g. node_to_index) and plural nouns for sequences (e.g. nodes) unless a different name significantly improves clarity.
After each round of changes, run the specific pre-commit hook that applies to your edits using
pre-commit run <hook-id> --files <paths> so only the touched files are linted. For example, after modifying Python files run pre-commit run lint-py --files path/to/file.py; use other language-specific hooks when they exist and skip this step when no hook covers that file type.
Annotate pytest
test_* functions with an explicit -> None return type.
Before running scripts, make them executable:
chmod +x path/to/script.py ./path/to/script.py
CRITICAL: Always run scripts directly to trigger the nix shebang:
# Make executable first chmod +x script.py # Run directly (this triggers the nix shebang) ./script.py command # NEVER use python directly - this bypasses nix dependencies # ❌ python script.py command # WRONG! # ❌ python -m module_name # WRONG!
Run tests using the built-in test command:
# Make executable first chmod +x script.py # Run tests via the script (triggers nix shebang) ./script.py test # NEVER use pytest directly - this bypasses nix dependencies # ❌ pytest script.py # WRONG!
For graph/network visualizations, use the shared
viz.py module:
from viz import visualise_graph visualise_graph( graphs=graphs, output_filename="output.html", graph_titles=titles )
Features:
Include
--open flags for generated visualizations:
@click.option("--open", is_flag=True, default=False, help="Open in browser") def example(open: bool): # Generate visualization if open: webbrowser.open(output)
floyd-warshall.py, matrix-method.py)graph.py, viz.py)import sys from pathlib import Path sys.path.append(str(Path(__file__).parent)) from local_module import function
#! /usr/bin/env nix-shell #! nix-shell -i python3 -p python313 -p python313Packages.loguru -p python313Packages.pytest -p python313Packages.click from __future__ import annotations import sys from collections.abc import Sequence from pathlib import Path import click import pytest sys.path.append(str(Path(__file__).parent)) from local_module import LocalClass def algorithm(input_data: Sequence[float]) -> Sequence[float]: # Implementation return result @pytest.mark.parametrize("input, expected", [(test_cases)]) def test_algorithm(input, expected): assert algorithm(input) == expected cli = click.Group() @cli.command() @click.option("--param", default=5, help="Parameter description") def example(param: int): result = algorithm(range(param)) click.echo(f"Result: {result}") @cli.command("test") def run_tests(): pytest.main([__file__]) if __name__ == "__main__": cli()
Usage:
# Make executable chmod +x script.py # Run commands (triggers nix shebang) ./script.py example --param 10 ./script.py test
This template provides a solid foundation for new algorithms while maintaining consistency with the existing codebase.