Простая функция в Python


Мне было интересно, если этот код может быть закодирован лучше с точки зрения семантики или дизайн. Я должен вернуться в Лос как цифры? я должен иметь константы считываются из БД в случае, если пользователь или я хочу изменить их в будущем?

def get_LOS(headway = None, frequency = None, veh_per_hr = None):
  if frequency != None and headway = veh_per_hr == None:
    headway = 1 / frequency

  if headway!= None or veh_per_hr != None:
    if headway 10 < or veh_per_hr > 6:
      return 'A'
    elif 10 <= headway < 15 or 5 < veh_per_hr <= 6:
      return 'B'
    elif 15 <= headway < 20 or 3 < veh_per_hr <= 5:
      return 'C'
    elif 20 <= headway < 31 or 2 < veh_per_hr <= 3:
      return 'D'
    elif 31 <= headway < 60 or 1 <= veh_per_hr < 2:
      return 'E'
    elif headway >= 60 or veh_per_hr < 1:
      return 'F'
    else:
      return 'Error'


416
3
задан 26 июля 2011 в 07:07 Источник Поделиться
Комментарии
2 ответа

def get_LOS(headway = None, frequency = None, veh_per_hr = None):

У вас нет строкой документации. Что бы помочь в объяснении, что параметры, делают.

  if frequency != None and headway = veh_per_hr == None:

При проверке ли что-то не рекомендуется использовать ни одного или нет ни у кого

    headway = 1 / frequency

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

  if headway!= None or veh_per_hr != None:
if headway 10 < or veh_per_hr > 6:

Я уверен, что не будет компилироваться

       return 'A'
elif 10 <= headway < 15 or 5 < veh_per_hr <= 6:
return 'B'
elif 15 <= headway < 20 or 3 < veh_per_hr <= 5:
return 'C'
elif 20 <= headway < 31 or 2 < veh_per_hr <= 3:
return 'D'
elif 31 <= headway < 60 or 1 <= veh_per_hr < 2:
return 'E'
elif headway >= 60 or veh_per_hr < 1:
return 'F'

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

    else:
return 'Error'

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

Как я хотел бы сделать это:

import bisect
def get_los_from_frequency(frequency):
return get_los(1 / frequency)

HEADWAY_LIMITS = [10, 15, 20, 31, 60]
VEH_PER_HR_LIMITS = [1,2,3,5,6]
GRADES = "ABCDEF"

def get_los(headway = None, veh_per_hr = None):
if headway is None:
headway_score = len(GRADES)
else:
headway_score = bisect.bisect_left(HEADWAY_LIMITS, headway)

if veh_pr_hr is None:
veh_pr_hr_score = len(GRADES)
else:
veh_pr_hr_score = len(GRADES) - bisect.bisect_left(VEH_PR_HR_LIMITS, veh_pr_hr)

return GRADES[min(headway_score, veh_pr_hr_score)]

8
ответ дан 27 июля 2011 в 04:07 Источник Поделиться

А не:

if frequency != None and headway = veh_per_hr == None:
headway = 1 / frequency

Вы должны переместить задание из оператора if:

if frequency is not None:
headway = veh_per_hr
if veh_per_hr is None:
headway = 1 / frequency

Это позволит сделать его более ясным, что вы делаете, не делая будущий читатель не поверили своим глазам, когда они видят задание на Оператор if. Это также может указывать на то, что это может быть лучше написать так:

headway = veh_per_hr
if veh_per_hr is None and frequency is not None:
headway = 1 / frequency

Кроме того, если вы хотите знать, почему, чтобы использовать это нет или нет ни у кого вместо == нет или != Нет, одна из причин-это:

>>> import timeit
>>> timeit.Timer('x=1; x != None').timeit()
0: 0.18491316633818045
>>> timeit.Timer('x=1; x is not None').timeit()
1: 0.17909091797979926

Еще может быть тот факт, что это намного проще, чтобы случайно не типа = вместо == и незаметно проскользнуть мимо задания в условных (а это еще один аргумент за то, что не делаете это нарочно, как впоследствии хранитель может кажется, что опечатка).

2
ответ дан 27 июля 2011 в 03:07 Источник Поделиться