I have been thinking on how to make a script to convert roman numerals to arabic and backwards, and after a whole day of optimizing and compressing the code, i came up with this:
V={'_M': 10**6, '_C_M': 900000, '_D': 500000, '_C_D': 400000, '_C': 10**5, '_X_C': 90000, '_L': 50000, '_X_L': 40000, '_X': 10**4, '_I_X': 9000, '_V': 5000, '_I_V': 4000, 'M': 1000, 'CM': 900, 'D': 500, 'CD': 400, 'C': 100, 'XC': 90, 'L': 50, 'XL': 40, 'X': 10, 'IX': 9, 'V': 5, 'IV': 4, 'I': 1} # Roman numerals/pairs to arabic def ro(a): # Function to convert arabic to roman numerals return ''.join(k for k in V for _ in iter(lambda: a >= V[k], False) if (a := a - V[k]) >= 0) # for every key(k)(letter/pair) in values(V), try to subtract the value associated with that letter/pair from the input(arabic number) and if the end result is 0 or more, append the letter/pair. for example, if we have 900 as input, it stops at 'CM' and appends it and since 900 - 900 is 0, it should stop iterating while True: r = 3999999 # range n = input(f"Enter Rom/Arab number (1-{r}) or 'q': ").upper() # input - arabic or roman number or quit if n == "Q": break else: #there used to be a separate function to convert roman to arabic but i decided it was unnecessary and it took extra lines of space, now it's all here: a = i = 0 # set arabic number and index to 0 while i < len(n): p = i+1<len(n) and V.get(n[i:i+2]) # check if a pair of index and index + 1 letters exists in the values dictionary a += V[n[i:i+2]] if p else V.get(n[i], 0) # if the pair exists, add the pair value, else add the single number value i += 2 if p else 1 # jump forward 2 steps if a pair is decoded, else jump 1 step if a single letter is decoded print(f"{ro(int(n))}" if n.isdigit() and 1 <= int(n) <= r else f"{a}" if ro(a) == n and 1 <= a <= r else "OUT OF RANGE") # prints out the result. if user_input is an integer (arabic number) and is in range, prints the result of conversion to roman numerals. otherwise if user_input is not an integer(is a roman numeral), tries to decode it into an arabic number, then encode it again and if the encoded value == original value then the number is valid and it prints it, else input is invalidi was wondering if there is a way to compress it even further? i couldnt find a way to do that