From 28ea2f7f277dd37d38d826ac0f434697628081e5 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 5 Jul 2026 11:12:52 +0000 Subject: [PATCH 1/3] phase 1 of issue #99 --- mortie/tests/test_tools.py | 44 ++++++++++++++++++++++++++++++++++++++ mortie/tools.py | 25 ++++++++++++++++++---- 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/mortie/tests/test_tools.py b/mortie/tests/test_tools.py index d8cdfea..dac4428 100644 --- a/mortie/tests/test_tools.py +++ b/mortie/tests/test_tools.py @@ -45,6 +45,50 @@ def test_order2res_decreasing(self): assert all(resolutions[i] > resolutions[i+1] for i in range(len(resolutions)-1)) +class TestRes2Display: + """Test the resolution-ladder printer""" + + def test_prints_all_orders_through_max(self, capsys): + """One line per order 0..MAX_ORDER -- no silent drop above 19""" + tools.res2display() + lines = capsys.readouterr().out.strip().split('\n') + assert len(lines) == tools.MAX_ORDER + 1 + # every order 0..29 appears with its trailing phrasing + for order in range(tools.MAX_ORDER + 1): + assert any( + line.endswith('at tessellation order ' + str(order)) + for line in lines + ) + + def test_max_order_argument(self, capsys): + """max_order bounds the printed range inclusively""" + tools.res2display(max_order=5) + lines = capsys.readouterr().out.strip().split('\n') + assert len(lines) == 6 + assert lines[-1].endswith('at tessellation order 5') + + def test_unit_ladder_km_m_cm(self, capsys): + """Coarse orders read in km, sub-km in m, sub-m in cm""" + tools.res2display() + lines = capsys.readouterr().out.strip().split('\n') + by_order = {int(line.rsplit(' ', 1)[1]): line for line in lines} + # order 12 = 1.589 km, order 13 = 794.456 m (the issue's examples) + assert by_order[12] == '1.589 km at tessellation order 12' + assert by_order[13] == '794.456 m at tessellation order 13' + # finest orders drop to cm rather than tiny km/m fractions + assert by_order[25] == '19.396 cm at tessellation order 25' + assert by_order[29] == '1.212 cm at tessellation order 29' + + def test_rounds_within_bracket(self, capsys): + """Values are rounded to three decimals inside the chosen unit""" + tools.res2display() + lines = capsys.readouterr().out.strip().split('\n') + for line in lines: + number = line.split(' ', 1)[0] + # at most three digits after the decimal point + assert len(number.split('.')[1]) <= 3 + + class TestUnique2Parent: """Test UNIQ to parent cell conversion""" diff --git a/mortie/tools.py b/mortie/tools.py index c31108a..bfa6026 100644 --- a/mortie/tools.py +++ b/mortie/tools.py @@ -24,10 +24,27 @@ def order2res(order): return res -def res2display(): - '''prints resolution levels''' - for res in range(20): - print(str(order2res(res)) + ' km at tessellation order ' + str(res)) +def res2display(max_order=MAX_ORDER): + '''prints resolution levels + + Prints one line per tessellation order from 0 through ``max_order`` + (default MAX_ORDER = 29, the finest order the packed-u64 kernel reaches). + Each resolution is rendered in the largest sensible unit -- km at coarse + orders, m once it drops below 1 km, cm once it drops below 1 m -- and + rounded to three decimals within that bracket, so fine orders read + naturally (e.g. order 12 -> ``1.589 km``, order 13 -> ``794.456 m``) + rather than as tiny km fractions. + ''' + for res in range(max_order + 1): + km = order2res(res) + if km >= 1.0: + value, unit = km, 'km' + elif km >= 1e-3: + value, unit = km * 1e3, 'm' + else: + value, unit = km * 1e5, 'cm' + print(str(round(value, 3)) + ' ' + unit + + ' at tessellation order ' + str(res)) def unique2parent(unique): From 794b89df07c913f2cdca134b726bb8e878b216a8 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 5 Jul 2026 11:16:31 +0000 Subject: [PATCH 2/3] phase 2 of issue #99 --- mortie/tests/test_tools.py | 8 +++++++- mortie/tools.py | 8 ++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/mortie/tests/test_tools.py b/mortie/tests/test_tools.py index dac4428..2f1f0aa 100644 --- a/mortie/tests/test_tools.py +++ b/mortie/tests/test_tools.py @@ -86,7 +86,13 @@ def test_rounds_within_bracket(self, capsys): for line in lines: number = line.split(' ', 1)[0] # at most three digits after the decimal point - assert len(number.split('.')[1]) <= 3 + assert '.' in number and len(number.split('.')[1]) <= 3 + + def test_out_of_range_raises(self): + """max_order outside 0..MAX_ORDER is rejected""" + for bad in (-1, tools.MAX_ORDER + 1): + with pytest.raises(ValueError, match="max_order must be"): + tools.res2display(max_order=bad) class TestUnique2Parent: diff --git a/mortie/tools.py b/mortie/tools.py index bfa6026..d232a6f 100644 --- a/mortie/tools.py +++ b/mortie/tools.py @@ -34,7 +34,15 @@ def res2display(max_order=MAX_ORDER): rounded to three decimals within that bracket, so fine orders read naturally (e.g. order 12 -> ``1.589 km``, order 13 -> ``794.456 m``) rather than as tiny km fractions. + + ``max_order`` must lie in 0..MAX_ORDER; the km/m/cm ladder bottoms out + at cm, which only stays legible while resolutions stay at or above the + order-29 floor. ''' + if not 0 <= max_order <= MAX_ORDER: + raise ValueError( + 'max_order must be between 0 and %d, got %r' + % (MAX_ORDER, max_order)) for res in range(max_order + 1): km = order2res(res) if km >= 1.0: From a316426fa7987b9da3202fabfe66a1d74d30bac1 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 5 Jul 2026 11:19:38 +0000 Subject: [PATCH 3/3] phase 3 of issue #99 --- mortie/tools.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/mortie/tools.py b/mortie/tools.py index d232a6f..3c80971 100644 --- a/mortie/tools.py +++ b/mortie/tools.py @@ -35,14 +35,12 @@ def res2display(max_order=MAX_ORDER): naturally (e.g. order 12 -> ``1.589 km``, order 13 -> ``794.456 m``) rather than as tiny km fractions. - ``max_order`` must lie in 0..MAX_ORDER; the km/m/cm ladder bottoms out - at cm, which only stays legible while resolutions stay at or above the - order-29 floor. + ``max_order`` must lie in 0..MAX_ORDER, the order range the packed-u64 + kernel encodes. ''' if not 0 <= max_order <= MAX_ORDER: raise ValueError( - 'max_order must be between 0 and %d, got %r' - % (MAX_ORDER, max_order)) + f"max_order must be between 0 and {MAX_ORDER}, got {max_order!r}") for res in range(max_order + 1): km = order2res(res) if km >= 1.0: