Дюйма <-> программа преобразования см


Я просто написал этот небольшой дюйма <-> программа преобразования см. Он работает просто отлично, хотя я знаю, что я сделал некоторые вещи в довольно глупым образом и, что он может быть улучшен.

def conversion():
    try: amount = int(raw_input("Please enter the value: "))
    except ValueError:
        print "Please specify a valid amount."
        return conversion()
    answer = raw_input("Please choose between converting FROM kilograms/pounds: ")
    if answer == "kilograms":
        return amount * 2.2
    elif answer == "pounds":
        return amount / 1.45
    else:
        print "Please choose between kilograms and pounds."
        restart = raw_input("Try again? ")
        if restart == "yes":
            return conversion()
        elif restart == "y":
            return conversion()
        else:
            print "Okay, bye."
            return

print conversion()


628
5
задан 18 апреля 2011 в 02:04 Источник Поделиться
Комментарии
3 ответа

Первая точка будет разделение: каждый объект (функция, класс ...) должен нести ответственность только за одну задачу (кроме, как ни странно, печать результата).

В коде одной функции (преобразования) отвечает за все. Попробуйте отделять различные вопросы:


  • ввод пользователя

  • преобразования

  • выход

Согласен, для такого очень маленькая программа, результат почти наверняка будет больше. Но это же будет гораздо понятнее и проще для расширения.

Далее, ваше использование рекурсии. Я люблю рекурсию столько же (даже больше!) в качестве следующего программистом, но в вашем случае несколько петель, не повредит читабельности.

Третий момент, магические константы, следует избегать. Использование переводных коэффициентов 2.2 и 1.45 это достаточно безобидными, но это только становится проблемой в больших программах. Вместо того, чтобы использовать правильно-именованные константы.

6
ответ дан 18 апреля 2011 в 03:04 Источник Поделиться

Не использовать рекурсию в данном случае. В Python не оптимизирует хвостовую рекурсию и после долгой сессии скрипт может показать ваш RuntimeError: максимальная глубина рекурсии превысил.

Не использовать арифметику с плавающей запятой в этом случае. Использование десятичной арифметике с десятичной модуль. Например:

>>> 100 * 2.2
220.00000000000003
>>> from decimal import Decimal
>>> Decimal("100") * Decimal("2.2")
Decimal('220.0')

Разделение логики и представления. Сейчас нет никакого способа, чтобы использовать этот конвертер с веб-интерфейса или в качестве библиотеки для большой программы. Например, вы можете начать с функции низкого уровня, такие как этот:

def kilograms_to_pounds(amount):
return amount * Decimal("2.2")

def pounds_to_kilograms(amount):
return amount / Decimal("1.45")

Затем вы можете создать интерфейсные функции такой:

converters = {
("kilograms", "pounds"): kilograms_to_pounds,
("pounds", "kilograms"): pounds_to_kilograms,
}

def convert(amount, from_, to):
c = converters.get((from_, to))
if c is None:
raise ValueError("converter not found")
return c(amount)

>>> convert(Decimal("100"), "pounds", "kilograms")
Decimal('68.96551724137931034482758621')

Позже вы можете добавить псевдонимы, как этот (или как функция декоратор):

aliases = {
"kg": "kilograms",
"lb": "pounds",
...
}

def convert(amount, from_, to):
from_ = aliases.get(from_, from_)
to = aliases.get(to, to)
c = converters.get((from_, to))
if c is None:
raise ValueError("converter not found")
return c(amount)

>>> convert(Decimal("100"), "lb", "kg")
Decimal('68.96551724137931034482758621')

В этой архитектуре вы можете позже добавить другие конвертеры в вашей библиотеке и вам нужно только позвонить преобразования() функцию из пользовательского интерфейса цикл.

Также мне не нравится ваш интерфейс. Например, если мне нужно, чтобы преобразовать 10 величин из килограммов в фунты мне нужно ввести значение, то мне нужно ввести "килограмм". Путем добавления режима на ваш конвертер вы можете сохранить меня 10 строк. Например, пользователей сначала введите "килограммов в фунты", а этот режим преобразования сохраняется и отображается в командной строке. Затем пользователь может ввести значения, которые будут преобразованы из килограммов в фунты. Позже пользователь может изменить режим преобразования, введя "фунты в килограммы".

4
ответ дан 18 апреля 2011 в 07:04 Источник Поделиться

Я бы не рекомендовал вам структурировать приложение таким образом. Уборщик решением (имхо) будет иметь значения, введенные аргументы в скрипт, так что вы называете это помощью ./преобразования --5.2 дюйма или ./преобразования --см 5.2. Также есть все функции объединяются в одну функцию не хорошая практика, вы должны разделить ввода/вывода и функции, по крайней мере.

Однако я сделал свою собственную версию, которая должна быть довольно равным, насколько функциональность идет, хотя я подозреваю, что некоторые вещи отличаются. И это не лучшее решение... просто разные.

#!/usr/bin/python2

def convert(value, frm):
try:
amount = int(value)
except:
throw Exception("Value is not an numeric")
return amount * 2.2 if frm == "kilograms" else (1/1.45) if frm == "pounds" else throw Exception("Can only convert from kilograms or pounds")

def ask_user():
while(True):
amount = raw_input("Please enter the value: ");
frm = raw_input("Please choose between converting FROM kilograms/pounds: ")
try:
result = convert(amount, frm)
print "The result is " + result + " " + "pounds" if frm == "kilograms" else "kilograms"
except Exception as e:
print e
print "Please try again"
continue
restart = raw_input("Try again? ");
if restart[0] == 'y':
continue
else:
print "Okey, bye."
break

if __name__ = '__main__': # This row is to be able to import the file without the question being asked on import.
ask_user()

2
ответ дан 18 апреля 2011 в 03:04 Источник Поделиться