distinct / tests /test_comparators.py
User1342's picture
Measure GPU and CPU energy from hardware counters and sum them; drop the modelled fallback
26a7c18
Raw History Blame Contribute Delete
4.07 kB
"""The comparison under a figure has to be right, or it undoes the figure.
A wrong comparator is worse than none: the number above it is measured, and a
reader who catches the comparison being wrong has no reason to trust the
measurement either.
"""
from __future__ import annotations
import math
import pytest
from distinct_server.comparators import (
COMPARATORS,
KETTLE_EFFICIENCY,
KWH,
WATER_SPECIFIC_HEAT,
basis,
choose,
describe,
)
def test_there_are_about_a_hundred_of_them() -> None:
assert len(COMPARATORS) >= 100
def test_every_entry_states_its_working() -> None:
for entry in COMPARATORS:
assert entry.note.strip(), entry.label
assert entry.joules > 0, entry.label
assert math.isfinite(entry.joules), entry.label
def test_labels_are_unique() -> None:
labels = [entry.label for entry in COMPARATORS]
assert len(labels) == len(set(labels))
def test_the_physics_is_the_physics() -> None:
"""Spot-check the derived entries against the formula in the docstring."""
by_label = {entry.label: entry.joules for entry in COMPARATORS}
# 0.25 l from 20 C to 100 C, in a kettle at 80%.
expected = 0.25 * WATER_SPECIFIC_HEAT * 80 / KETTLE_EFFICIENCY
assert by_label["mug of tea boiled"] == pytest.approx(expected, rel=0.01)
# 0.568 l (a pint) over the same rise.
expected = 0.568 * WATER_SPECIFIC_HEAT * 80 / KETTLE_EFFICIENCY
assert by_label["pint of water boiled"] == pytest.approx(expected, rel=0.01)
# 1 kg of water, 1 degree.
assert by_label["litre of water warmed by 1 C"] == pytest.approx(WATER_SPECIFIC_HEAT, rel=0.001)
# A 100 g apple lifted a metre.
assert by_label["apple lifted one metre"] == pytest.approx(0.1 * 9.81, rel=0.01)
# Rated appliances are watts times seconds.
assert by_label["minute in a microwave"] == pytest.approx(1000 * 60)
assert by_label["hour of a laptop"] == pytest.approx(50 * 3600)
assert by_label["load of washing"] == pytest.approx(0.7 * KWH, rel=0.001)
assert by_label["day of a UK home"] == pytest.approx(7.5 * KWH, rel=0.001)
def test_a_figure_always_finds_a_comparison_it_can_carry() -> None:
"""Across nine decades, the count in front of the label stays picturable."""
value = 1.0
while value <= 1e10:
chosen = choose(value)
assert chosen is not None, value
_, count = chosen
assert 0.05 <= count <= 20, (value, count)
value *= 3.0
def test_the_chosen_comparison_is_the_closest_one() -> None:
entry, count = choose(104_650.0)
assert entry.label == "mug of tea boiled"
assert count == pytest.approx(1.0, rel=0.01)
def test_singular_only_when_it_reads_as_one() -> None:
""""about 0.98 minute" reads as a mistake, so the rule follows the printed
number rather than a tolerance around 1.0."""
entry = next(e for e in COMPARATORS if e.label == "mug of tea boiled")
assert entry.name(1.0) == "mug of tea boiled"
assert entry.name(1.04) == "mug of tea boiled"
assert entry.name(0.98) == "mugs of tea boiled"
assert entry.name(2.0) == "mugs of tea boiled"
assert entry.name(0.4) == "mugs of tea boiled"
assert describe(104_650.0) == "about 1 mug of tea boiled"
def test_nothing_sensible_to_say_says_nothing() -> None:
for bad in (0, -1, None, float("nan"), float("inf"), True, "12"):
assert describe(bad) == "" # type: ignore[arg-type]
assert choose(bad) is None # type: ignore[arg-type]
def test_the_working_travels_with_the_comparison() -> None:
assert "4186" in basis(4186.0) or "kg" in basis(4186.0)
assert basis(104_650.0)
def test_no_conversion_this_project_refuses_to_make() -> None:
"""No CO2, water, land or money: those need assumptions a joule does not."""
forbidden = ("co2", "carbon", "gco2", "water footprint", "litres of water used", "£", "$")
for entry in COMPARATORS:
blob = f"{entry.label} {entry.note}".lower()
for word in forbidden:
assert word not in blob, (entry.label, word)