Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/packvium/compression.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
Every value on this path is an exact integer or a reduced rational. Pressure is carried as a
numerator/denominator pair rather than a `Fraction` for two reasons: the hard limit is a
comparison, which cross multiplication answers without dividing at all, and PHP, Rust and
JavaScript have no rational type to port a `Fraction` to ( through ).
JavaScript have no rational type to port a `Fraction` to (through).
"""

from __future__ import annotations
Expand Down
6 changes: 3 additions & 3 deletions src/packvium/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ class Axle:
max_load: Weight | None = None


#: The largest `stop_index` every engine can carry identically ( /KI defect found
#: under ). Route order is decided by comparing stop indices, and JavaScript holds
#: The largest `stop_index` every engine can carry identically (/KI defect found
#: under). Route order is decided by comparing stop indices, and JavaScript holds
#: numbers as doubles: `JSON.parse` already collapses 2**53 + 1 to 2**53 before any
#: constraint sees it, so two consecutive stops above this bound become one number there
#: and one engine silently disagrees with the other three. Since the value cannot cross
Expand Down Expand Up @@ -316,7 +316,7 @@ class Container:
axles: tuple[Axle, Axle] | None = None
# Which walls this container can be unloaded through. Empty means the
# horizontal half of route order is not enforced for it -- not that it is sealed.
# A container with no stated doors is the pre- default, and defaulting to all
# A container with no stated doors is the pre-default, and defaulting to all
# six instead would enforce a rule true of no real vehicle: a box is almost always
# free through *some* face, so six doors is nearly the same as none, but it is a
# *different* nearly-nothing and it would change answers for every caller who never
Expand Down
4 changes: 2 additions & 2 deletions src/packvium/packer.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def pack(self, items, containers) -> PackingResult:
# is a static property of the request, unlike a billed weight past the last
# bracket, which depends on how the search filled the box and loses a candidate
# instead. Rust and the JavaScript fallback refuse both at admission with these
# same sentences ( review); the scorer's late checks stay as the backstop
# same sentences (review); the scorer's late checks stay as the backstop
# for callers who bypass `Packer.pack`.
if (
self.config.objective in ("shipping_cost", "lowest_landed_cost")
Expand Down Expand Up @@ -179,7 +179,7 @@ def pack(self, items, containers) -> PackingResult:
# The sentinel is a search device, never an answer -- alternatives included.
# A runner-up the tariff cannot price is dropped before the slice, so up to
# top_k-1 usable packings survive when priceable runners exist beyond an
# unpriceable one ( review).
# unpriceable one (review).
tuple(
runner for runner in selected[1:]
if unpriceable_container(runner.containers, self.config) is None
Expand Down
2 changes: 1 addition & 1 deletion src/packvium/rebalance.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ def rebalance_weight(
continue
# A move that prices the destination past its tariff is not an
# improvement: the sentinel must never ride out through a rebalanced
# packing any more than through a packed one ( review).
# packing any more than through a packed one (review).
if unpriceable_container(tuple(trial), config) is not None:
continue
committed = (trial, source.placements[placement_index].instance.id, source.id, working[dest_index].id)
Expand Down
6 changes: 3 additions & 3 deletions src/packvium/serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,13 @@ class UnsupportedFeatureError(ValueError):
"request": (),
"configuration": (),
# `hull_vertices`, `compression_ratio` and `max_compression_pressure_kpa` left this list
# in , when Python gained both the solver behaviour and the independent validation
# in, when Python gained both the solver behaviour and the independent validation
# the staged rollout requires. PHP, Rust and the JavaScript fallback still carry them.
"item": (),
# `pallet_overhang_limit` was reserved in the schema by at the 1.1.0 contract
# freeze and is refused everywhere until an engine implements it from a request: a field
# a caller can set and the solver ignores is worse than a refusal.
# `access_directions` left this list in , which wired the reserved field through
# `access_directions` left this list in, which wired the reserved field through
# to `StopAccessibilityConstraint` in all four engines at once.
"container": ("pallet_overhang_limit",),
}
Expand All @@ -153,7 +153,7 @@ class UnsupportedFeatureError(ValueError):
#: is unimplemented is a *value*, and the refusal has to name it -- an engine that packed a
#: `convex_hull` item as its bounding box would return a plan that looks valid and does not
#: physically fit.
#: Empty since : this engine implements every value the schema defines. The guard
#: Empty since: this engine implements every value the schema defines. The guard
#: stays because the next reserved value will need it, and because `reject_unsupported` takes
#: its lists as parameters precisely so it remains testable when they are empty.
UNSUPPORTED_SHAPE_TYPES: tuple[str, ...] = ()
Expand Down
7 changes: 4 additions & 3 deletions src/packvium/solvers.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ class SearchStats:
# `exact_small` or global-beam solve. Internal for the same reason as
# `hull_refinements` above, and for one more: reporting a gap to a caller is a new public
# result field, and this project reserves and rejects such a field before a contract
# freeze rather than adding it mid-line ('s precedent, restated by ).
# freeze rather than adding it mid-line, following the precedent set for the reserved
# container field and restated by the objective-bound wave.
# `None` when no bound was computed -- a non-default objective keys its score vector
# differently, so a bound compared against it would compare different quantities.
objective_lower_bound: "tuple[int, ...] | None" = None
Expand Down Expand Up @@ -1574,7 +1575,7 @@ def state_rank(state: ContainerState, state_volume: int) -> tuple[int, ...]:

Landed cost precedes unused volume in the public objective. A promotional
bracket may make a heavier equal-count subset cheaper, so the historical
count/volume rank was wrong for this objective ( second review).
count/volume rank was wrong for this objective (second review).
"""
count = len(state.placements)
if config.objective != "lowest_landed_cost":
Expand Down Expand Up @@ -2507,7 +2508,7 @@ def _across_containers_greedy(self, solver, items, containers, config, stats, de
config.dimensional_weight_weight_unit,
).ticks
# `payload_ticks` and `placement_count` are lattice-aware: the
# compact path carries no per-item placements, so summing
# compact path carries no per-item placements, so summing
# `state.placements` here priced a quantity-compressed trial as
# tare alone and let an unpriceable container win the round.
gross = container.tare_weight.ticks + one.state.payload_ticks
Expand Down
2 changes: 1 addition & 1 deletion tests/test_access_directions_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def test_every_legal_direction_survives_canonicalisation():


def test_a_container_states_no_doors_by_default():
"""The pre- default, and it is *inert* rather than permissive: six walls and
"""The pre-default, and it is *inert* rather than permissive: six walls and
none are both nearly-vacuous, but they are different nearly-vacuous, and defaulting to
six would switch a real constraint on for every caller who never set the field."""
assert crate().access_directions == ()
Expand Down
2 changes: 1 addition & 1 deletion tests/test_constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -1417,7 +1417,7 @@ def test_the_corridor_base_is_reused_for_a_second_candidate_on_the_same_state():


def test_a_container_states_its_own_doors_and_a_silent_one_inherits_the_default():
""" . The field is per container because two doors on one trailer and none on
""". The field is per container because two doors on one trailer and none on
another is the case that makes the rule worth having; the constructor argument stays as
the default so the library callers who predate the field keep working."""
early, early_x = _wide("early", 60, 40, stop=0)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_irregular_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

These are the numbers the document commits to in prose. Pinning them here means a later
optimisation of the axis set or the compression arithmetic has to keep answering the
published examples, and it means PHP, Rust and JavaScript ( through ) have a
published examples, and it means PHP, Rust and JavaScript (through) have a
concrete target rather than a paragraph to interpret.

The cross-implementation property tests live in `conformance/tests/test_irregular_items.py`,
Expand Down
4 changes: 2 additions & 2 deletions tests/test_objective.py
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ def test_a_bracket_step_makes_the_cheaper_shipment_the_heavier_one():


def test_a_quantity_compressed_round_still_prices_the_true_payload():
""" compact states carry no per-item `Placement`s, so a round key that sums
"""compact states carry no per-item `Placement`s, so a round key that sums
`state.placements` prices a quantity-compressed trial as tare alone. Eight 2000 g
cubes bill 16000 g -- past alpha's last bracket -- but alpha's dimensional 5400 g
is not, so a tare-only key committed alpha and refused a request that beta ships
Expand Down Expand Up @@ -784,7 +784,7 @@ def test_alternatives_never_quote_the_sentinel():
"""The refusal guarded only the winner; `alternatives` (top_k defaults to 3) could
carry a feasible-status packing of an unpriceable container with the sentinel as
its landed cost -- the exact number this objective exists to never invent. Runner-
ups the tariff cannot price are dropped before the slice ( review)."""
ups the tariff cannot price are dropped before the slice (review)."""
from packvium.config import PackingConfig, SolverProfile
from packvium.extensions import UNPRICEABLE_MINOR, unpriceable_container
from packvium.models import RateTable
Expand Down
6 changes: 3 additions & 3 deletions tests/test_rebalance.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ def test_a_rebalance_move_never_prices_a_container_past_its_bracket():
"""The only spread-improving move -- one brick into the lighter box -- would bill it
at 2000 g, past its 1500 g card. Under lowest_landed_cost that is not an
improvement: the sentinel must never ride out through a rebalanced packing any more
than through a packed one ( review)."""
than through a packed one (review)."""
from packvium import Container, Dimensions, Item
from packvium.models import RateTable
from packvium.packer import Packer
Expand Down Expand Up @@ -273,7 +273,7 @@ def test_a_rebalance_move_never_prices_a_container_past_its_bracket():
def test_rebalance_refuses_an_unpriceable_input():
"""A caller handing rebalance a packing whose container already bills past its
bracket gets the same refusal `Packer.pack` gives on the way out, not a rebalanced
version of a shipment with no published price ( review)."""
version of a shipment with no published price (review)."""
from packvium import Container, Dimensions, Item
from packvium.models import RateTable, UnratedWeightError
from packvium.packer import Packer
Expand Down Expand Up @@ -308,7 +308,7 @@ def test_rebalance_refuses_an_unpriceable_input():
def test_rebalance_applies_the_same_landed_cost_admission_as_pack():
"""The public rebalance entry point must not accept a request the pack entry point
rejects: pricing requires a divisor and a rate card on every available container,
including a container the current packing did not happen to use ( review)."""
including a container the current packing did not happen to use (review)."""
from packvium import Container, Dimensions, Item
from packvium.extensions import UnknownObjectiveError
from packvium.models import RateTable
Expand Down
Loading