From 59ae27fd123c84bfa4271d71c8436a35108c69a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=B0=E8=A8=80?= Date: Mon, 29 Jun 2026 13:14:22 +0800 Subject: [PATCH] feat(conversions): add input validation and fix bugs in Roman Numerals --- conversions/roman_numerals.py | 38 ++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/conversions/roman_numerals.py b/conversions/roman_numerals.py index 75af2ac72882..fe35759ea7f8 100644 --- a/conversions/roman_numerals.py +++ b/conversions/roman_numerals.py @@ -24,8 +24,25 @@ def roman_to_int(roman: str) -> int: >>> tests = {"III": 3, "CLIV": 154, "MIX": 1009, "MMD": 2500, "MMMCMXCIX": 3999} >>> all(roman_to_int(key) == value for key, value in tests.items()) True + >>> roman_to_int("iii") + 3 + >>> roman_to_int("") + Traceback (most recent call last): + ... + ValueError: Input cannot be an empty string + >>> roman_to_int("MIX-abc") + Traceback (most recent call last): + ... + ValueError: Invalid Roman numeral character: - """ vals = {"I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000} + roman = roman.upper() + if not roman: + raise ValueError("Input cannot be an empty string") + for char in roman: + if char not in vals: + raise ValueError(f"Invalid Roman numeral character: {char}") + total = 0 place = 0 while place < len(roman): @@ -40,12 +57,31 @@ def roman_to_int(roman: str) -> int: def int_to_roman(number: int) -> str: """ - Given a integer, convert it to an roman numeral. + Given an integer, convert it to a roman numeral. https://en.wikipedia.org/wiki/Roman_numerals >>> tests = {"III": 3, "CLIV": 154, "MIX": 1009, "MMD": 2500, "MMMCMXCIX": 3999} >>> all(int_to_roman(value) == key for key, value in tests.items()) True + >>> int_to_roman(0) + Traceback (most recent call last): + ... + ValueError: Input must be an integer between 1 and 3999 + >>> int_to_roman(-5) + Traceback (most recent call last): + ... + ValueError: Input must be an integer between 1 and 3999 + >>> int_to_roman(4000) + Traceback (most recent call last): + ... + ValueError: Input must be an integer between 1 and 3999 + >>> int_to_roman(1.5) # type: ignore[arg-type] + Traceback (most recent call last): + ... + ValueError: Input must be an integer between 1 and 3999 """ + if not isinstance(number, int) or not (0 < number < 4000): + raise ValueError("Input must be an integer between 1 and 3999") + result = [] for arabic, roman in ROMAN: (factor, number) = divmod(number, arabic)