TheAlgorithms/Python · error · TypeError

length must be a positive numeric value.

Error message

length must be a positive numeric value.

What it means

Raised by Side.__post_init__ in geometry/geometry.py when length is not int/float or is <= 0 (TypeError). A Side represents a polygon edge in meters; zero or negative lengths make perimeter/area math meaningless, so construction fails fast. As with Angle, TypeError is used for both type and range problems — unconventional but consistent within this module.

Source

Thrown at geometry/geometry.py:71

        ...
    TypeError: length must be a positive numeric value.
    >>> Side(5, None)
    Traceback (most recent call last):
        ...
    TypeError: angle must be an Angle object.
    >>> Side(5, Angle(90), "Invalid next_side")
    Traceback (most recent call last):
        ...
    TypeError: next_side must be a Side or None.
    """

    length: float
    angle: Angle = field(default_factory=Angle)
    next_side: Side | None = None

    def __post_init__(self) -> None:
        if not isinstance(self.length, (int, float)) or self.length <= 0:
            raise TypeError("length must be a positive numeric value.")
        if not isinstance(self.angle, Angle):
            raise TypeError("angle must be an Angle object.")
        if not isinstance(self.next_side, (Side, NoneType)):
            raise TypeError("next_side must be a Side or None.")


@dataclass
class Ellipse:
    """
    A geometric Ellipse on a 2D surface

    >>> Ellipse(5, 10)
    Ellipse(major_radius=5, minor_radius=10)
    >>> Ellipse(5, 10) is Ellipse(5, 10)
    False
    >>> Ellipse(5, 10) == Ellipse(5, 10)
    True
    """

View on GitHub (pinned to f5988cc097)

Solutions

  1. Pass a positive number: Side(5) or Side(2.5).
  2. If the side comes from two vertices, check for duplicate vertices first — they produce length 0.
  3. Convert numeric strings at the parse boundary.

Example fix

# before
import math
Side(math.dist(p1, p2))  # 0.0 when p1 == p2 after simplification

# after
length = math.dist(p1, p2)
if length <= 0:
    raise ValueError(f'degenerate edge between {p1} and {p2}')
Side(length)
Defensive patterns

Strategy: type-guard

Validate before calling

if not isinstance(length, (int, float)) or isinstance(length, bool) or length <= 0:
    raise TypeError('side length must be a positive number')
Side(length)

Type guard

def is_valid_side_length(v: object) -> bool:
    return isinstance(v, (int, float)) and not isinstance(v, bool) and v > 0

Try / catch

try:
    s = Side(length)
except TypeError as exc:
    if 'positive numeric' in str(exc):
        raise ValueError(f'degenerate side: {length}') from exc
    raise

Prevention

When it happens

Trigger: Constructing Side(0), Side(-5), or Side('5'). Fired from __post_init__, i.e. at object creation, not when the side is later used in shape math.

Common situations: Zero-length sides from degenerate/duplicate consecutive vertices (common when simplifying polygons), sentinel defaults of 0, or numeric strings from imported geometry data.

Related errors


AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14). Data as JSON: /api/errors/2a781fd3f0cd8944. Report an issue: GitHub.