Если у вас есть куча повторяющихся кодов, и вам трудно понять, как удалить повторение, хорошим трюком является постепенное изменение фрагментов, чтобы они постепенно начали напоминать друг друга.Если вы все сделаете правильно, вы можете сделать так, чтобы они точно соответствовали друг другу.
Это может показаться нелепым, но хорошая вещь в этой технике заключается в том, что она не требует больших скачков понимания.Вы можете добиться этого с небольшими, постепенными изменениями, не глядя и код, и очень серьезно подумайте .
Позвольте мне показать вам, что я имею в виду.
Шаг 1: Поверните все elif
s в прямые if
s и удалите else
.Это делает их более очевидно одинаковыми, и вы должны видеть, что это не меняет поведение кода.
if n in range(0, 10):
return selection[-1]
if n in range(10, 20):
return selection[-2]
if n in range(20, 30):
return selection[-3]
if n in range(30, 40):
return selection[-4]
if n in range(40, 50):
return selection[-5]
if n in range(50, 60):
return selection[-6]
if n in range(60, 70):
return selection[-7]
if n in range(70, 80):
return selection[-8]
if n in range(80, 90):
return selection[-9]
if n in range(90, 100):
return selection[-10]
return None
Шаг 2: Рассчитайте числа на основе некоторых общихстоимость.Мы хотим извлечь новую переменную i
так, чтобы каждый случай стал буквально идентичным остальному.Если мы установим i
на 1, затем на 2, затем на 3 и т. Д., Мы можем сделать это.
Давайте рассмотрим первый случай:
if n in range(0, 10):
return selection[-1]
Если i
равно 1, тогда 10 равно i*10
, -1
равно -i
, а 0 равно (i-1)*10
.
i = 1
if n in range((i-1)*10, i*10):
return selection[-i]
Мы можем сделать то же самое для второго случая.
if n in range(10, 20):
return selection[-2]
Те же формулы работают.Все, что нам нужно сделать, это изменить i
на 2!
i = 2
if n in range((i-1)*10, i*10):
return selection[-i]
Сполоснуть и повторить 10 раз, и мы получим эту красоту:
i = 1
if n in range((i-1)*10, i*10):
return selection[-i]
i = 2
if n in range((i-1)*10, i*10):
return selection[-i]
i = 3
if n in range((i-1)*10, i*10):
return selection[-i]
i = 4
if n in range((i-1)*10, i*10):
return selection[-i]
i = 5
if n in range((i-1)*10, i*10):
return selection[-i]
i = 6
if n in range((i-1)*10, i*10):
return selection[-i]
i = 7
if n in range((i-1)*10, i*10):
return selection[-i]
i = 8
if n in range((i-1)*10, i*10):
return selection[-i]
i = 9
if n in range((i-1)*10, i*10):
return selection[-i]
i = 10
if n in range((i-1)*10, i*10):
return selection[-i]
return None
Шаг 3: Теперь, когда у нас есть 10 одинаковых if
операторов, должно быть понятно, как все это превратить в цикл.Цикл от i=1
до i=10
и мы его получили.
for i in range(1, 11):
if n in range((i-1)*10, i*10):
return selection[-i]
return None
Вот и мы!Все повторяющиеся вещи пропали.
Шаг 4: Если вы хотите пойти еще дальше, вы можете попытаться вычислить значение i
, которое соответствует n
вместо того, чтобы использовать подход угадывания и проверки выше.Я оставлю это как упражнение для вас (или для других ответов).Это хорошая оптимизация, но она находится в другой лиге, чем тот тип рефакторинга, который я только что изложил здесь.