def run_experiment(
    py_versions: list[PyVersion],
    cov_versions: list[Coverage],
    projects: list[ProjectToTest],
    rows: list[str],
    column: str,
    ratios: Iterable[tuple[str, str, str]] = (),
    num_runs: int = int(sys.argv[1]),
    load: bool = False,
) -> None:
    """
    Run a benchmarking experiment and print a table of results.

    Arguments:

        py_versions: The Python versions to test.
        cov_versions: The coverage versions to test.
        projects: The projects to run.
        rows: A list of strings chosen from `"pyver"`, `"cov"`, and `"proj"`.
        column: The remaining dimension not used in `rows`.
        ratios: A list of triples: (title, slug1, slug2).
        num_runs: The number of times to run each matrix element.

    """
    slugs = [v.slug for v in py_versions + cov_versions + projects]
    if len(set(slugs)) != len(slugs):
        raise Exception(f"Slugs must be unique: {slugs}")
    if any(" " in slug for slug in slugs):
        raise Exception(f"No spaces in slugs please: {slugs}")
    ratio_slugs = [rslug for ratio in ratios for rslug in ratio[1:]]
    if any(rslug not in slugs for rslug in ratio_slugs):
        raise Exception(f"Ratio slug doesn't match a slug: {ratio_slugs}, {slugs}")
    if set(rows + [column]) != set(DIMENSION_NAMES):
        raise Exception(
            f"All of these must be in rows or column: {', '.join(DIMENSION_NAMES)}"
        )

    print(f"Removing and re-making {PERF_DIR}")
    remake(PERF_DIR)

    results_file = Path("results.json").resolve()
    with change_dir(PERF_DIR):
        exp = Experiment(
            py_versions=py_versions,
            cov_versions=cov_versions,
            projects=projects,
            results_file=results_file,
            load=load,
        )
        exp.run(num_runs=int(num_runs))
        exp.show_results(rows=rows, column=column, ratios=ratios)

    Run a benchmarking experiment and print a table of results.

    Arguments:

        py_versions: The Python versions to test.
        cov_versions: The coverage versions to test.
        projects: The projects to run.
        rows: A list of strings chosen from `"pyver"`, `"cov"`, and `"proj"`.
        column: The remaining dimension not used in `rows`.
        ratios: A list of triples: (title, slug1, slug2).
        num_runs: The number of times to run each matrix element.

    
benchmark/benchmark.py