TheAlgorithms/Python · error · TypeError
degrees must be a numeric value between 0 and 360.
Error message
degrees must be a numeric value between 0 and 360.
What it means
Raised by Angle.__post_init__ in geometry/geometry.py when degrees is not int/float or lies outside [0, 360] (inclusive both ends). Angle is a dataclass used by Side to orient polygon edges; the check runs at construction. Quirk: it raises TypeError even for pure range violations (Angle(361)), which is unconventional — most libraries use ValueError for out-of-range values.
Source
Thrown at geometry/geometry.py:34
>>> Angle()
Angle(degrees=90)
>>> Angle(45.5)
Angle(degrees=45.5)
>>> Angle(-1)
Traceback (most recent call last):
...
TypeError: degrees must be a numeric value between 0 and 360.
>>> Angle(361)
Traceback (most recent call last):
...
TypeError: degrees must be a numeric value between 0 and 360.
"""
degrees: float = 90
def __post_init__(self) -> None:
if not isinstance(self.degrees, (int, float)) or not 0 <= self.degrees <= 360:
raise TypeError("degrees must be a numeric value between 0 and 360.")
@dataclass
class Side:
"""
A side of a two dimensional Shape such as Polygon, etc.
adjacent_sides: a list of sides which are adjacent to the current side
angle: the angle in degrees between each adjacent side
length: the length of the current side in meters
>>> Side(5)
Side(length=5, angle=Angle(degrees=90), next_side=None)
>>> Side(5, Angle(45.6))
Side(length=5, angle=Angle(degrees=45.6), next_side=None)
>>> Side(5, Angle(45.6), Side(1, Angle(2))) # doctest: +ELLIPSIS
Side(length=5, angle=Angle(degrees=45.6), next_side=Side(length=1, angle=Angle(d...
>>> Side(-1)
Traceback (most recent call last):View on GitHub (pinned to f5988cc097)
Solutions
- Normalize before constructing: Angle(deg % 360).
- Convert types at the boundary: Angle(float(raw)) for string inputs.
- Be aware both bounds are inclusive — 360 is accepted, so normalize to [0, 360] not [0, 360).
Example fix
# before import math Angle(math.degrees(theta)) # theta > 2*pi gives degrees > 360 # after Angle(math.degrees(theta) % 360)
Defensive patterns
Strategy: type-guard
Validate before calling
if not isinstance(deg, (int, float)) or isinstance(deg, bool):
deg = float(deg)
if not 0 <= deg <= 360:
deg = deg % 360
Angle(deg) Type guard
def is_valid_angle_deg(v: object) -> bool:
return (
isinstance(v, (int, float))
and not isinstance(v, bool)
and 0 <= v <= 360
) Try / catch
try:
a = Angle(deg)
except TypeError as exc:
if 'between 0 and 360' in str(exc):
a = Angle(deg % 360)
else:
raise Prevention
- Catch TypeError, not ValueError, for range violations here.
- Normalize degree inputs with % 360 at the conversion point.
- 360 is legal; 361 is not — off-by-one at the boundary.
When it happens
Trigger: Constructing Angle(361), Angle(-0.5), or Angle('90'). Angle(0) and Angle(360) are both valid. The doctests show Angle(361) producing this exact TypeError.
Common situations: Converting angles from radians via math.degrees without normalizing (theta > 2*pi gives degrees > 360), compass headings that arrive above 360 after adding offsets, or string values from UI/config.
Related errors
- length must be a positive numeric value.
- angle must be an Angle object.
- next_side must be a Side or None.
- num_cuts must be a positive numeric value.
- epsilon must be non-negative, got {epsilon!r}
AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14).
Data as JSON: /api/errors/ac841da989cc6ba2.
Report an issue: GitHub.