fix(coordinate_compression): raise exceptions instead of returning -1 - #14555
Conversation
Previously `compress()` and `decompress()` returned -1 on invalid input while `coordinate_map[...]` raised KeyError, giving inconsistent error semantics. This change makes error handling uniform: `compress` raises KeyError and `decompress` raises IndexError, matching Python conventions and the underlying dict/list. Docstrings and doctests updated. Fixes TheAlgorithms#13509
|
@priya-sundaram-dev, your review, please, as a fix to |
priya-sundaram-dev
left a comment
There was a problem hiding this comment.
Thanks @AshrafHosam — the direction here is right: replacing the silent -1 returns with real exceptions is what #13509 asks for, and the doctests are self-verifying and pass locally (18 tests). Two things to consider before this fully closes the issue:
1. Silent -1 still leaks for duplicate inputs. compress_coordinates() sizes reverse_map as [-1] * len(arr) but only fills one slot per unique value, so duplicates leave trailing -1 sentinels that are still in range for decompress:
>>> cc = CoordinateCompressor([10, 10, 52])
>>> cc.reverse_map
[10, 52, -1]
>>> cc.decompress(2) # in range (0 <= 2 < 3), so no IndexError
-1So the "silent failure" this PR removes from the no-duplicates path is reintroduced on the duplicate path. Building the maps from sorted(set(arr)) (so reverse_map has exactly the unique count) closes that hole.
2. Consistency of exception type. The issue title is about a mix of behaviors; compress now raises KeyError while decompress raises IndexError. Both are exceptions (good), but a single type — e.g. ValueError for both — reads as more "consistent" and is easier to document/catch.
Heads-up that #14873 takes the sorted(set(...)) approach and raises ValueError uniformly, which covers both points above — worth a look to align with, or borrow from. Nice work either way.
priya-sundaram-dev
left a comment
There was a problem hiding this comment.
LGTM — this is exactly what #13509 asked for. Replacing the -1 sentinels with real exceptions is the right call:
compressnow surfaces aKeyErrorfor unknown values instead of a magic number a caller could silently treat as a valid coordinate.decompressraisesIndexErrorwith a helpful message rather than returning-1(which collided with a legitimate value/type domain).
The Raises: sections and the Traceback (most recent call last): doctests are correct — I ran them locally and both the KeyError: 7 and IndexError: compressed coordinate 5 is out of range cases reproduce cleanly. No behavioural gaps: every previous -1 return path is now covered by an exception. Nice, minimal diff.
Describe your change:
Fixes inconsistent error handling in
data_compression/coordinate_compression.pyreported in #13509.Previously:
compress(x)returned-1on missing input (silent failure)decompress(n)returned-1on out-of-range input (silent failure)coordinate_map[x]raisedKeyError(exception)This mix of sentinels and exceptions made errors easy to miss and hard to debug.
This PR unifies the behavior to raise exceptions consistently:
compress(x)now raisesKeyError(same as the underlyingcoordinate_mapdict)decompress(n)now raisesIndexErrorwith a descriptive messageRaises:contractFixes #13509
Checklist: