iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
A Python fix can work on an ordinary input and still fail at the edge: the first or last index, a negative value, or a number close to zero. The key is to define the behavior you need, then test the boundary values—not just a typical example. Here are three illustrative fixes and the cases that expose their limits.
1. Adding 1 to a range stop can create an invalid index
Suppose a sequence has length n. Its valid nonnegative indexes are 0 through n - 1. Because range() excludes its stop, range(n) already produces exactly those indexes. Changing a loop to range(len(items) + 1) includes len(items), which is not a valid index.
items = ["a", "b", "c"]
for i in range(len(items) + 1):
print(items[i]) # IndexError when i == 3
The extra iteration can look like a reasonable way to include the final item, but the stop value is not itself included. Python’s range tutorial explains the excluded endpoint and shows that range(10) covers the legal indexes for a sequence of length ten. The built-in types reference documents ranges and sequence indexing.
Use the sequence directly when you need its values
If the loop only needs each item, iterate over the sequence rather than building indexes:
#1 Best Overall
for item in items:
print(item)
If you need both an index and its value, use enumerate(items). Keep an indexed range when the index itself is needed for the operation.
Test empty, singleton, and ordinary sequences
A useful boundary check includes lengths zero and one as well as a longer sequence. In particular, confirm that an empty sequence causes zero iterations and that the final valid index is len(items) - 1 for a nonempty sequence.
2. Subtracting one from an index can silently select the last item
Changing an index from i to i - 1 may seem to select the preceding item. But when i is zero, the result is -1, and Python sequences interpret -1 as the last item—not as an invalid position. A mistaken calculation can therefore return a plausible but wrong value instead of raising an error.
Rank #2
items = ["first", "middle", "last"]
i = 0
previous = items[i - 1] # "last"
Negative indexes count backward from the end of a sequence; this behavior is described in Python’s sequence operations reference. If wrapping around is intended, a negative index may be appropriate. If it is not, check the lower bound before indexing.
Make the boundary rule explicit
For a previous-item operation that should reject the first position, validate the index before subtracting:
if not 0 <= i < len(items):
raise IndexError("index out of range")
if i == 0:
raise IndexError("there is no previous item")
previous = items[i - 1]
The right response depends on the contract: an application might instead return a sentinel, skip the operation, or deliberately wrap to the last item. The important distinction is whether wrapping is intended.
Do not assume slicing behaves like indexing
A slice uses a start-inclusive, stop-exclusive interval and clamps overlarge endpoints to sequence bounds. That can make a slice appear to handle an edge safely when a direct index would fail, but it does not prove that the selected range matches the intended rule. Test the first position, last position, empty sequence, and a position outside the valid range.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstall3. Replacing truncation with floor division changes negative results
int(a / b) and a // b can agree for positive inputs but differ for negative nonintegers. Converting a float to int truncates toward zero; floor division rounds down toward negative infinity. For example, int(-1 / 2) is 0, while -1 // 2 is -1.
print(int(-1 / 2)) # 0: truncates toward zero
print(-1 // 2) # -1: floors toward negative infinity
Python documents floor division and float-to-integer conversion in its numeric types reference. Neither operation is a universal fix for the other: the correct choice depends on the mathematical contract.
Choose the rounding rule the problem requires
- Use
int(x)when truncation toward zero is intended. - Use
a // bwhen the quotient must be rounded down toward negative infinity. - For exact integer quotient and remainder behavior, reason about integer operands directly rather than converting through floating point unnecessarily.
If the calculation must preserve exact rational relationships, converting through binary floating point can introduce a separate approximation. Python’s tutorial on floating-point arithmetic explains why many decimal fractions are not represented exactly; the fractions module is an option when exact rational arithmetic is required.
Test both sides of zero
Include positive and negative nonmultiples, exact multiples, and values around zero. A test set containing only positive values can miss the difference between truncation and flooring.
Free tools Windows power users keep installed
One-click scans. No signup required.
How to make a boundary test useful
A boundary test should encode the rule the code promises, not merely repeat the implementation’s current behavior. Identify the valid input range and expected outcome just inside, at, and just outside its limits. For sequence code, that often means the first and last valid positions, the first invalid position, and empty or singleton inputs. For numeric code, include negative values and zero when they are in scope.
Best Value
- State the invariant: for example, “every index passed to this operation is between zero and the sequence length minus one.”
- Choose edge inputs: include the lowest and highest valid values and the nearest invalid values; add negative or zero cases for arithmetic.
- Assert the contract: check the returned value or the expected exception, not just that the code completes.
- Keep precision in scope: if a comparison allows error, define the acceptable error in the units and scale of the problem.
These are practical testing choices, not a Python-mandated checklist. The shared principle is to test the values at which the rule changes.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.When the boundary involves floating-point values
Exact equality can fail after apparently simple decimal arithmetic because binary floating point cannot represent many decimal fractions exactly. Python’s tutorial illustrates this with 0.1 + 0.1 + 0.1 == 0.3, which is false, and notes that math.isclose() can compare inexact values. The tutorial describes this as a property of binary floating point, not a Python defect.
math.isclose() uses relative and absolute tolerances. Its default absolute tolerance is zero, so a nonzero difference from zero does not become close just because the relative tolerance is nonzero. For a near-zero comparison, choose an abs_tol that reflects the application’s acceptable error rather than assuming the default is suitable. See the math.isclose reference for the comparison formula and defaults.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsFor values that must obey exact decimal rules, consider decimal; for exact rational relationships, consider fractions. Tolerance-based comparison is appropriate only when a small discrepancy is acceptable under the problem’s requirements.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

