{"record":{"id":"ac841da989cc6ba2","repo":"TheAlgorithms/Python","slug":"degrees-must-be-a-numeric-value-between-0-and-360","errorCode":null,"errorMessage":"degrees must be a numeric value between 0 and 360.","messagePattern":"degrees must be a numeric value between 0 and 360\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"geometry/geometry.py","lineNumber":34,"sourceCode":"    >>> Angle()\n    Angle(degrees=90)\n    >>> Angle(45.5)\n    Angle(degrees=45.5)\n    >>> Angle(-1)\n    Traceback (most recent call last):\n        ...\n    TypeError: degrees must be a numeric value between 0 and 360.\n    >>> Angle(361)\n    Traceback (most recent call last):\n        ...\n    TypeError: degrees must be a numeric value between 0 and 360.\n    \"\"\"\n\n    degrees: float = 90\n\n    def __post_init__(self) -> None:\n        if not isinstance(self.degrees, (int, float)) or not 0 <= self.degrees <= 360:\n            raise TypeError(\"degrees must be a numeric value between 0 and 360.\")\n\n\n@dataclass\nclass Side:\n    \"\"\"\n    A side of a two dimensional Shape such as Polygon, etc.\n    adjacent_sides: a list of sides which are adjacent to the current side\n    angle: the angle in degrees between each adjacent side\n    length: the length of the current side in meters\n\n    >>> Side(5)\n    Side(length=5, angle=Angle(degrees=90), next_side=None)\n    >>> Side(5, Angle(45.6))\n    Side(length=5, angle=Angle(degrees=45.6), next_side=None)\n    >>> Side(5, Angle(45.6), Side(1, Angle(2)))  # doctest: +ELLIPSIS\n    Side(length=5, angle=Angle(degrees=45.6), next_side=Side(length=1, angle=Angle(d...\n    >>> Side(-1)\n    Traceback (most recent call last):","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/geometry/geometry.py#L16-L52","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"# before\nimport math\nAngle(math.degrees(theta))  # theta > 2*pi gives degrees > 360\n\n# after\nAngle(math.degrees(theta) % 360)","handlingStrategy":"type-guard","validationCode":"if not isinstance(deg, (int, float)) or isinstance(deg, bool):\n    deg = float(deg)\nif not 0 <= deg <= 360:\n    deg = deg % 360\nAngle(deg)","typeGuard":"def is_valid_angle_deg(v: object) -> bool:\n    return (\n        isinstance(v, (int, float))\n        and not isinstance(v, bool)\n        and 0 <= v <= 360\n    )","tryCatchPattern":"try:\n    a = Angle(deg)\nexcept TypeError as exc:\n    if 'between 0 and 360' in str(exc):\n        a = Angle(deg % 360)\n    else:\n        raise","preventionTips":["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."],"tags":["geometry","input-validation","typeerror","dataclass"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}