Предложения по улучшению скрипта

не могли бы вы дать мне отзыв об этом небольшом скрипте Python. Если вы можете предложить лучший способ преобразования римских цифр в целые числа, пожалуйста, дайте мне знать. Для простоты пока нет обработки ошибок. Большое Вам спасибо.

#Script to convert Roman numeral to Integer.
#Note no error handling yet for simplicity.

def roman(mystring):
    roman_dict = {'I':'1',
                  'V':'5', 
                  'X':'10',
                  'L':'50',
                  'C':'100',
                  'D':'500',
                  'M':'1000'}
    x = roman_dict[mystring]
    return (x)

def get_myinput(myinput):
    sum = 0
    char_before = ''
    for char in myinput:
        if char_before  == '':
            subtract = 0
            pass
        elif char_before == 'I' and (char == 'V' or char == 'X'):
            subtract = 1
        elif char_before == 'X' and (char == 'L' or char == 'C'):
            subtract = 10
        elif char_before == 'C' and (char == 'D' or char == 'M'):
            subtract = 100
        else:
            subtract = 0
            pass

        converted = int(roman(char)) - subtract
        sum = sum + int(converted) - subtract
        char_before = char
    return (sum)

if __name__ == "__main__" :
    myinteger = get_myinput('MCMXCIV')
    print(myinteger)

Если это рабочий код, который вы хотите проверить, есть специальный сайт CodeReview StackExchange для этого; это не подходит для StackOverflow.

ShadowRanger 01.02.2019 07:24

Я голосую за то, чтобы закрыть этот вопрос как не относящийся к теме, потому что он требует проверки рабочего кода и, как таковой, относится к CodeReview.

ShadowRanger 01.02.2019 07:25

Извините, если пишу не на тот форум. Конечно. Спасибо.

Mr Bright 01.02.2019 08:27
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
3
57
1

Ответы 1

Добро пожаловать в СО. На самом деле намек на то, чтобы перенести это в CodeReview, правильный. Однако эта задача была для меня слишком интересной, чтобы не думать о том, как я начну, так что вот она.
Идея состоит в том, чтобы сначала сопоставить латинские буквы с «0» ... «6», чтобы было легче определить, меньше ли текущее значение, чем следующее, или нет. Это достигается str.translate с использованием изначально определенной карты, созданной с помощью str.maketrans.
. Затем итерация немного упрощается за счет конкатенации '0' в конце только для сравнения, так что последнее значение может обрабатываться так же, как и другие в середине (и всегда добавляется):

def roman2dec(rn_string):
    m = str.maketrans('IVXLCDM', '0123456')
    d = {'0':1, '1':5, '2':10, '3':50, '4':100, '5':500, '6':1000}

    rtran = rn_string.upper().translate(m)
    value = 0
    for i, c in enumerate(rtran):
        if rtran[i] < (rtran+'0')[i+1]:
            value = value - d[c]
        else:
            value = value + d[c]
    return(value)

str.upper() вставлен только для удобства тестирования...

Некоторые тесты:

roman2dec('MDCLXVI')
#1666
roman2dec('MCMXCIV')
#1994
roman2dec('xlii')
#42

Редактировать:
Это можно даже сжать до довольно короткой функции:

def r2d(rn):
    d = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000}
    values = [d[c] for c in rn.upper()]
    signs = ([1, -1][a < b] for a, b in zip(values, values[1:]+[0]))
    return sum(a*b for a, b in zip(signs, values))

или даже

def r2d2(rn):
    d = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000}
    return sum(d[a] * [1, -1][d[a] < d[b]] for a, b in zip(rn.upper(), rn.upper()[1:]+'I'))

или подход numpy:

def r2d_np(rn):
    import numpy as np
    d = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000}
    values = np.array([d[c] for c in rn.upper()])
    signs = np.append(np.where(np.diff(values)>0, -1, 1), 1)
    return sum(values*signs)

Другие вопросы по теме