TheAlgorithms/Python · error · ValueError

Expecting a list of points but got {points}

Error message

Expecting a list of points but got {points}

What it means

Raised by _validate_input in the convex hull module when the passed points object is iterable but empty (falsy). The function first requires an object with __iter__, then rejects anything that iterates to nothing, because a convex hull of zero points is undefined. This is a ValueError used to guard the divide-and-conquer hull algorithm from empty input.

Source

Thrown at divide_and_conquer/convex_hull.py:183

    >>> _validate_input([Point(2, 1), Point(-1, 2)])
    [(2.0, 1.0), (-1.0, 2.0)]
    >>> _validate_input([])
    Traceback (most recent call last):
        ...
    ValueError: Expecting a list of points but got []
    >>> _validate_input(1)
    Traceback (most recent call last):
        ...
    ValueError: Expecting an iterable object but got an non-iterable type 1
    """

    if not hasattr(points, "__iter__"):
        msg = f"Expecting an iterable object but got an non-iterable type {points}"
        raise ValueError(msg)

    if not points:
        msg = f"Expecting a list of points but got {points}"
        raise ValueError(msg)

    return _construct_points(points)


def _det(a: Point, b: Point, c: Point) -> float:
    """
    Computes the sign perpendicular distance of a 2d point c from a line segment
    ab. The sign indicates the direction of c relative to ab.
    A Positive value means c is above ab (to the left), while a negative value
    means c is below ab (to the right). 0 means all three points are on a straight line.

    As a side note, 0.5 * abs|det| is the area of triangle abc

    Parameters
    ----------
    a: point, the point on the left end of line segment ab
    b: point, the point on the right end of line segment ab
    c: point, the point for which the direction and location is desired.

View on GitHub (pinned to f5988cc097)

Solutions

  1. Check that the points collection is non-empty before calling the hull function: if points: hull = convex_hull(points).
  2. Fix the upstream data source if empty input is unexpected (empty file path, wrong query, failed parse).
  3. Wrap the call in try/except ValueError and treat empty input as a no-op hull if your use case allows it.

Example fix

# before
hull = convex_hull(points)  # points == [] raises ValueError

# after
if not points:
    hull = []
else:
    hull = convex_hull(points)
Defensive patterns

Strategy: validation

Validate before calling

def has_points(points) -> bool:
    return hasattr(points, '__iter__') and len(list(points)) > 0

if has_points(points):
    hull = convex_hull(points)

Type guard

def is_non_empty_points(points: object) -> bool:
    return hasattr(points, '__iter__') and bool(list(points))

Try / catch

try:
    hull = convex_hull(points)
except ValueError as exc:
    if 'list of points' in str(exc):
        hull = []
    else:
        raise

Prevention

When it happens

Trigger: Calling the public convex hull entry point (e.g. convex_hull([]) or convex_hull(())) with an empty list/tuple, or with a generator/set that yields no elements. Note that a non-iterable argument raises the earlier 'Expecting an iterable object' error instead.

Common situations: Pipelines that read points from a file, database, or sensor feed that legitimately returns zero rows; filtering datasets before hull computation; passing an empty test fixture during unit testing.

Related errors


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