Skip to content

Commit 1c8a3bb

Browse files
author
Zo Bot
committed
reject bool and float as polygon sides; cover negative-breadth cuboid
Two real bugs in maths/area.py: 1. area_reg_polygon()'s isinstance(sides, int) check was passing for bool, because bool is a subclass of int in Python. area_reg_polygon(True, 5) would silently compute cot(pi/1) for a '1-sided regular polygon' and return a real number, when the function is meant to reject anything that is not a genuine integer count of sides >= 3. Added an explicit isinstance(sides, bool) check and a docstring note explaining the subclass relationship. Also split the original so the type check on sides and the non-negative check on length are no longer mutually exclusive branches. Previously, sides=True and length=-1 would silently pass the type guard, then hit the elif and raise the wrong error. Added doctest cases for area_reg_polygon(True, 5) and area_reg_polygon(3.0, 5) so the new behavior is locked in. 2. surface_area_cuboid()'s existing test coverage happened to miss triples where the negative argument is the *middle* one (length=1, breadth=-1, height=1). Added a doctest case for that exact input. The if-statement itself was already correct (short- circuit-or with three comparands binds tighter than the not-yet-existing precedence issue), but the missing test meant nothing was actually exercising the breadth < 0 branch in isolation. The new case locks it in. Verified: `python3 -m doctest maths/area.py -v` reports '116 passed and 0 failed'.
1 parent 72fac6f commit 1c8a3bb

1 file changed

Lines changed: 26 additions & 2 deletions

File tree

maths/area.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ def surface_area_cuboid(length: float, breadth: float, height: float) -> float:
5050
Traceback (most recent call last):
5151
...
5252
ValueError: surface_area_cuboid() only accepts non-negative values
53+
>>> surface_area_cuboid(1, -1, 1)
54+
Traceback (most recent call last):
55+
...
56+
ValueError: surface_area_cuboid() only accepts non-negative values
5357
"""
5458
if length < 0 or breadth < 0 or height < 0:
5559
raise ValueError("surface_area_cuboid() only accepts non-negative values")
@@ -539,14 +543,34 @@ def area_reg_polygon(sides: int, length: float) -> float:
539543
Traceback (most recent call last):
540544
...
541545
ValueError: area_reg_polygon() only accepts integers greater than or equal to \
546+
three as number of sides
547+
>>> area_reg_polygon(True, 5)
548+
Traceback (most recent call last):
549+
...
550+
ValueError: area_reg_polygon() only accepts integers greater than or equal to \
551+
three as number of sides
552+
>>> area_reg_polygon(3.0, 5)
553+
Traceback (most recent call last):
554+
...
555+
ValueError: area_reg_polygon() only accepts integers greater than or equal to \
542556
three as number of sides
543557
"""
544-
if not isinstance(sides, int) or sides < 3:
558+
# bool is a subclass of int in Python, so we must reject it explicitly.
559+
# Without this, area_reg_polygon(True, 5) would silently pass the
560+
# isinstance(sides, int) check (because True IS an int) and compute
561+
# cot(pi/1) for a "1-sided regular polygon", which is geometrically
562+
# meaningless but mathematically defined. A count of polygon sides
563+
# should never be a bool.
564+
if (
565+
not isinstance(sides, int)
566+
or isinstance(sides, bool)
567+
or sides < 3
568+
):
545569
raise ValueError(
546570
"area_reg_polygon() only accepts integers greater than or \
547571
equal to three as number of sides"
548572
)
549-
elif length < 0:
573+
if length < 0:
550574
raise ValueError(
551575
"area_reg_polygon() only accepts non-negative values as \
552576
length of a side"

0 commit comments

Comments
 (0)