:orphan: Roman numeral to integer - Solutions ==================================== .. contents:: :local: .. _pwp-rn2i-ex1: Exercise 1 ---------- Solution ^^^^^^^^ .. interactive_code_block:: :caption: A function that converts a roman numeral to an integer def roman_numeral_to_integer(roman_numeral): """Convert a roman numeral to an integer.""" # Create a dict with the roman symbols and their integer values roman_symbols = { 'M':1000, 'D':500, 'C': 100, 'L': 50, 'X': 10, 'V': 5, 'I': 1 } result = 0 for index, current_symbol in enumerate(roman_numeral): # Get the value of the current symbol current_symbol_value = roman_symbols[current_symbol] # Use the index to test if there is still a symbol follwing the current one if index < len(roman_numeral) - 1: # Get the value of the next symbol next_symbol = roman_numeral[index + 1] next_symbol_value = roman_symbols[next_symbol] # If the value of the current symbol is lower than the one of the next... if current_symbol_value < next_symbol_value: # ...than substract the value to the result... result -= current_symbol_value else: # ...otherwise add the value to the result result += current_symbol_value else: # There is no next symbol left: add the value of the current symbol result += current_symbol_value return result # Create a dict with test values test_values = {'CXXIII': 123, 'CCCXXI':321, 'CDXLIV':444, 'CMXCIX': 999, 'MMXXI': 2021} # Print a table with test values and the result of the function print(' Test values | Result') print('------------------+-------') for roman_numeral, result in test_values.items(): print('{:>8} | {:6} | {:6}'.format(roman_numeral, result, roman_numeral_to_integer(roman_numeral))) Shorter but less explicit solution ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The code above can be shortened by using less variables and by replacing the nested ``if`` statements with a more elaborate condition. The line continuation character ``\`` within the condition is used here to avoid a very long line of code. Another option would be to enclose the condition in round brackets ``()``. .. interactive_code_block:: :caption: A function that converts a roman numeral to an integer - shorter but less explicit version def roman_numeral_to_integer(roman_numeral): """Convert a roman numeral to an integer.""" # Create a dict with the roman symbols and their integer values roman_symbols = { 'M':1000, 'D':500, 'C': 100, 'L': 50, 'X': 10, 'V': 5, 'I': 1 } result = 0 for index, current_symbol in enumerate(roman_numeral): # Use the index to test if there is still a symbol follwing the current one... # ...and if the value of the current symbol is less than the next one if index < len(roman_numeral) - 1 \\ and roman_symbols[current_symbol] < roman_symbols[roman_numeral[index + 1]]: # Substract the value from the result result -= roman_symbols[current_symbol] else: # Add the value of the current symbol result += roman_symbols[current_symbol] return result # Create a dict with test values test_values = {'CXXIII': 123, 'CCCXXI':321, 'CDXLIV':444, 'CMXCIX': 999, 'MMXXI': 2021} # Print a table with test values and the result of the function print(' Test values | Result') print('------------------+-------') for roman_numeral, result in test_values.items(): print('{:>8} | {:6} | {:6}'.format(roman_numeral, result, roman_numeral_to_integer(roman_numeral))) .. _pwp-rn2i-ex2: Exercise 2 ---------- Solution ^^^^^^^^ .. interactive_code_block:: :caption: A function that converts a roman numeral to an integer def roman_numeral_to_integer(roman_numeral): """Convert a roman numeral to an integer.""" # Create a dict with the roman symbols and their integer values roman_symbols = { '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 } # Create a variable to be able to add the values of the symbols result = 0 # Create a variable to be used as index index = 0 # Iterate over the symbols of the roman numeral until the end has been reached while index < len(roman_numeral): # Test if there is not the last symbol if index < len(roman_numeral) - 1: # Test if this is a double-letter symbol if roman_numeral[index:index + 2] in roman_symbols: # Add the value for the double-letter symbol... result += roman_symbols[roman_numeral[index:index + 2]] # ...and increment the index by 2 index +=2 # Otherwise else: # Add the value for the single-letter symbol... result += roman_symbols[roman_numeral[index]] # Increment the index by 1 index +=1 # Otherwise else: # Add the value for the single-letter symbol... result += roman_symbols[roman_numeral[index]] # Increment the index by 1 index +=1 return result # Create a dict with test values test_values = {'CXXIII': 123, 'CCCXXI':321, 'CDXLIV':444, 'CMXCIX': 999, 'MMXXI': 2021} # Print a table with test values and the result of the function print(' Test values | Result') print('------------------+-------') for roman_numeral, result in test_values.items(): print('{:>8} | {:6} | {:6}'.format(roman_numeral, result, roman_numeral_to_integer( roman_numeral))) Shorter but less explicit solution ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. interactive_code_block:: :caption: A function that converts a roman numeral to an integer - shorter but less explicit version def roman_numeral_to_integer(roman_numeral): """Convert a roman numeral to an integer.""" # Create a dict with the roman symbols and their integer values roman_symbols = { '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 } # Create a variable to be able to add the values of the symbols result = 0 # Create a variable to be used as index index = 0 # Iterate over the symbols of the roman numeral until the end has been reached while index < len(roman_numeral): # Test if there is not the last symbol... # ...and if this is a double-letter symbol if index < len(roman_numeral) - 1 \\ and roman_numeral[index:index + 2] in roman_symbols: # Add the value for the double-letter symbol... result += roman_symbols[roman_numeral[index:index + 2]] # ...and increment the index by 2 index +=2 # Otherwise else: # Add the value for the single-letter symbol... result += roman_symbols[roman_numeral[index]] # Increment the index by 1 index +=1 return result # Create a dict with test values test_values = {'CXXIII': 123, 'CCCXXI':321, 'CDXLIV':444, 'CMXCIX': 999, 'MMXXI': 2021} # Print a table with test values and the result of the function print(' Test values | Result') print('------------------+-------') for roman_numeral, result in test_values.items(): print('{:>8} | {:6} | {:6}'.format(roman_numeral, result, roman_numeral_to_integer( roman_numeral)))