diff --git a/src/tea3/cli.py b/src/tea3/cli.py index 31876bd..cfdca7f 100644 --- a/src/tea3/cli.py +++ b/src/tea3/cli.py @@ -1,85 +1,11 @@ from tea3.pretty_print import pretty_print +from tea3.cliutils import prompt_int, prompt_choice, prompt_list from tea3.tea3model import Tea3Model from tea3.variable_search import run_exhaustive from tea3.sbox import run_sbox from tea3.variable_xor import run_variable_xor from tea3.f31f32 import run_f31f32 -def prompt_int(message: str, lo: int, hi: int) -> int: - while True: - raw = input(message).strip() - try: - value = int(raw) - except ValueError: - print("Please enter a number.") - continue - if lo <= value <= hi: - return value - print(f"Value must be between {lo} and {hi} (inclusive).") - - -def prompt_choice(message: str, choices: set[int]) -> int: - choices_str = ", ".join(map(str, sorted(choices))) - while True: - raw = input(message).strip() - try: - value = int(raw) - except ValueError: - print("Please enter a number.") - continue - if value in choices: - return value - print(f"Value must be one of: {choices_str}") - -def prompt_list(prompt: str, item_name: str, min_value: int, max_value: int): - while True: - raw = input(prompt).strip() - if not raw: - print(f"Please enter at least one {item_name}.") - continue - - values = [] - ok = True - - for token in raw.split(): - if "-" in token: - parts = token.split("-", 1) - if len(parts) != 2 or not parts[0].isdigit() or not parts[1].isdigit(): - ok = False - break - - start = int(parts[0]) - end = int(parts[1]) - - if start > end: - print(f"Invalid range '{token}': start must be <= end.") - ok = False - break - - values.extend(range(start, end + 1)) - else: - if not token.isdigit(): - ok = False - break - values.append(int(token)) - - if not ok: - print("Please enter only numbers and ranges (like 3-7), separated by spaces.") - continue - - if any(v < min_value or v > max_value for v in values): - print(f"Each {item_name} must be between {min_value} and {max_value}.") - continue - - seen = set() - values = [v for v in values if not (v in seen or seen.add(v))] - - if not values: - print(f"Please enter at least one valid {item_name}.") - continue - - return values - def run_classic_cli(): print("\nR registers are indexed 0–7; bits within each register are 0–7.") diff --git a/src/tea3/cliutils.py b/src/tea3/cliutils.py new file mode 100644 index 0000000..bbf3501 --- /dev/null +++ b/src/tea3/cliutils.py @@ -0,0 +1,75 @@ + +def prompt_int(message: str, lo: int, hi: int) -> int: + while True: + raw = input(message).strip() + try: + value = int(raw) + except ValueError: + print("Please enter a number.") + continue + if lo <= value <= hi: + return value + print(f"Value must be between {lo} and {hi} (inclusive).") + + +def prompt_choice(message: str, choices: set[int]) -> int: + choices_str = ", ".join(map(str, sorted(choices))) + while True: + raw = input(message).strip() + try: + value = int(raw) + except ValueError: + print("Please enter a number.") + continue + if value in choices: + return value + print(f"Value must be one of: {choices_str}") + +def prompt_list(prompt: str, item_name: str, min_value: int, max_value: int): + while True: + raw = input(prompt).strip() + if not raw: + print(f"Please enter at least one {item_name}.") + continue + + values = [] + ok = True + + for token in raw.split(): + if "-" in token: + parts = token.split("-", 1) + if len(parts) != 2 or not parts[0].isdigit() or not parts[1].isdigit(): + ok = False + break + + start = int(parts[0]) + end = int(parts[1]) + + if start > end: + print(f"Invalid range '{token}': start must be <= end.") + ok = False + break + + values.extend(range(start, end + 1)) + else: + if not token.isdigit(): + ok = False + break + values.append(int(token)) + + if not ok: + print("Please enter only numbers and ranges (like 3-7), separated by spaces.") + continue + + if any(v < min_value or v > max_value for v in values): + print(f"Each {item_name} must be between {min_value} and {max_value}.") + continue + + seen = set() + values = [v for v in values if not (v in seen or seen.add(v))] + + if not values: + print(f"Please enter at least one valid {item_name}.") + continue + + return values diff --git a/src/tea3/variable_xor.py b/src/tea3/variable_xor.py index 95a7a1a..d8538ce 100644 --- a/src/tea3/variable_xor.py +++ b/src/tea3/variable_xor.py @@ -23,6 +23,3 @@ def run_variable_xor(steps, target_reg, bits_to_xor): print(f"XOR of R_bits[{target_reg}][{bits_to_xor}] =") print(pretty_print(xor_poly)) print() - - print("\n" + "=" * 50) - print("Done.")