Skip to content

dpmxl.explain

Explanations of failing records: a sentence, the filled formula, both sides with their intervals and the cells involved. See Explain failures in a UI.

dpmxl.explain

Explain a failing record in words and with the formula's values filled in.

For {r0010} = {r0020} + {r0030} failing at column 0010:

  • summary: 1,204 should equal 1,197 (1,180 + 17): difference 7;
  • filled: 1,204 = 1,180 + 17;
  • left and right: each side's formula, value, filled text and cells.

Formulas are rendered from the expression tree rather than copied from the source, so spacing is uniform, negative terms read a - 226,000 (with a typographic minus) instead of a + -226,000, and long runs of zero terms collapse to + 0 (x13). Failures that are not comparisons (a value that must be reported, must be empty, must be one of a set, or must match a pattern) get a sentence of their own.

Explanation and error wording may improve in minor releases; field names and kind values may not.

VERBS module-attribute

VERBS = {
    "=": "should equal",
    "!=": "should differ from",
    "<": "should be less than",
    "<=": "should not exceed",
    ">": "should exceed",
    ">=": "should be at least",
}

The verb of a failing comparison's summary, by comparison operator.

Operand dataclass

Operand(
    source: str, value: str, points: tuple[DataPoint, ...]
)

One leaf operand of a failing record with its value and cells.

Attributes:

  • source (str) –

    The operand's text, such as {r0020}.

  • value (str) –

    Its formatted value, such as 1,180.

  • points (tuple[DataPoint, ...]) –

    The cells it read.

source instance-attribute

source: str

value instance-attribute

value: str

points instance-attribute

points: tuple[DataPoint, ...]

Side dataclass

Side(
    formula: str,
    filled: str,
    value: str,
    points: tuple[DataPoint, ...],
    terms: int,
    threshold: str | None = None,
    low: str | None = None,
    high: str | None = None,
)

One side of the failing comparison.

Attributes:

  • formula (str) –

    The side's formula, such as {r0020} + {r0030}.

  • filled (str) –

    The formula with values, such as 1,180 + 17.

  • value (str) –

    The side's formatted value.

  • points (tuple[DataPoint, ...]) –

    The cells it read.

formula instance-attribute

formula: str

filled instance-attribute

filled: str

value instance-attribute

value: str

points instance-attribute

points: tuple[DataPoint, ...]

terms instance-attribute

terms: int

Number of operands (cells, aggregates, parameters) on this side.

threshold class-attribute instance-attribute

threshold: str | None = None

Half-width of the side's interval from reported precision; None if exact.

low class-attribute instance-attribute

low: str | None = None

high class-attribute instance-attribute

high: str | None = None

single_cell property

single_cell: bool

Whether the side is exactly one reported cell.

Explanation dataclass

Explanation(
    formula: str,
    filled: str,
    summary: str,
    operands: tuple[Operand, ...],
    difference: str | None = None,
    primary: tuple[DataPoint, ...] = (),
    kind: Kind = "condition",
    relation: str | None = None,
    verb: str | None = None,
    left: Side | None = None,
    right: Side | None = None,
    gap: str | None = None,
    direction: Direction | None = None,
    tolerance: str | None = None,
)

Human-readable account of one evaluated record.

Fields whose value is formatted text (difference, gap, tolerance, the sides' values) are strings, ready for display.

Attributes:

  • formula (str) –

    The rule body as rendered from the tree, such as {r0010} = {r0020} + {r0030}.

  • filled (str) –

    The formula with the record's values, such as 1,204 = 1,180 + 17.

  • summary (str) –

    One sentence for a person, such as 1,204 should equal 1,197 (1,180 + 17): difference 7.

  • operands (tuple[Operand, ...]) –

    Every leaf operand with its value and cells.

  • difference (str | None) –

    For a comparison, the absolute difference of the sides.

  • kind (Kind) –

    comparison, missing (a value must be reported), not_empty (a value must be empty), membership (a value must be one of a set), format (a value must match a pattern) or condition (anything else).

  • relation (str | None) –

    The failing comparison operator, such as =.

  • verb (str | None) –

    The summary's verb from VERBS.

  • left (Side | None) –

    The left side of a failing comparison.

  • right (Side | None) –

    The right side of a failing comparison.

  • tolerance (str | None) –

    The sum of both sides' thresholds; None when exact.

formula instance-attribute

formula: str

filled instance-attribute

filled: str

summary instance-attribute

summary: str

operands instance-attribute

operands: tuple[Operand, ...]

difference class-attribute instance-attribute

difference: str | None = None

primary class-attribute instance-attribute

primary: tuple[DataPoint, ...] = ()

Cells on the left of the failing comparison: the values that disagree.

kind class-attribute instance-attribute

kind: Kind = 'condition'

relation class-attribute instance-attribute

relation: str | None = None

verb class-attribute instance-attribute

verb: str | None = None

left class-attribute instance-attribute

left: Side | None = None

right class-attribute instance-attribute

right: Side | None = None

gap class-attribute instance-attribute

gap: str | None = None

How far apart the two sides' intervals are: the smallest difference that remains when every value may vary within its reported precision.

direction class-attribute instance-attribute

direction: Direction | None = None

Which side is larger (too_high: left exceeds right), not a verdict on which value is wrong.

tolerance class-attribute instance-attribute

tolerance: str | None = None

explain

explain(
    evaluation: Evaluation,
    expression: str,
    key: Mapping[str, Hashable],
) -> Explanation

Explain the record of evaluation identified by key.

Parameters:

Returns:

  • Explanation ( Explanation ) –

    Summary sentence, formula, filled formula and operands.

Examples:

>>> from dpmxl import MemoryProvider, Number, TableLayout, evaluate_rule
>>> layout = TableLayout("T", rows=("0010", "0020", "0030"), columns=("0010",))
>>> provider = MemoryProvider([layout], {
...     ("T", "0010", "0010", None, ()): Number.of(1204, 0),
...     ("T", "0020", "0010", None, ()): Number.of(1180, 0),
...     ("T", "0030", "0010", None, ()): Number.of(17, 0),
... })
>>> expression = (
...     "with {tT, c0010, interval: true}: {r0010} = {r0020} + {r0030}"
... )
>>> result = evaluate_rule(expression, provider)
>>> explanation = explain(result.evaluation, expression, result.failures[0].key)
>>> print(explanation.summary)
1,204 should equal 1,197 (1,180 + 17): difference 7, at least 5.5 given the
reported precision
>>> explanation.filled, explanation.gap, explanation.direction
('1,204 = 1,180 + 17', '5.5', 'too_high')
>>> explanation.right.low, explanation.right.high
('1,196', '1,198')
>>> [point.label() for point in explanation.primary]
['{tT, r0010, c0010}']