укоротить код возможно?
можно ли эту часть кода как то "оптимизировать"?
def on_press_true_button(self):
global numbering_text_t1,numbering_text_t2,numbering_text_t3,numbering_text_t4,numbering_text_t5,numbering_text_t6,numbering_text_t7,Item_id
#print(Item_id)
if Item_id == "Стандарт +14":
if numbering_text_t2 < limit_t2 -1:
numbering_text_t2 += 1
self.screen.ids.scroll_text.text = str(text_t2[numbering_text_t2])
else:
numbering_text_t2= 0
self.screen.ids.scroll_text.text = str(text_t2[numbering_text_t2])
elif Item_id == "Подростки +16":
if numbering_text_t3 < limit_t3 -1:
numbering_text_t3 += 1
self.screen.ids.scroll_text.text = str(text_t3[numbering_text_t3])
else:
numbering_text_t3= 0
self.screen.ids.scroll_text.text = str(text_t3[numbering_text_t3])
elif Item_id == "Экстрим +18":
if numbering_text_t4 < limit_t4 -1:
numbering_text_t4 += 1
self.screen.ids.scroll_text.text = str(text_t4[numbering_text_t4])
else:
numbering_text_t4= 0
self.screen.ids.scroll_text.text = str(text_t4[numbering_text_t4])
elif Item_id == "Безумие +21":
if numbering_text_t5 < limit_t5 -1:
numbering_text_t5 += 1
self.screen.ids.scroll_text.text = str(text_t5[numbering_text_t5])
else:
numbering_text_t5= 0
self.screen.ids.scroll_text.text = str(text_t5[numbering_text_t5])
else:
if numbering_text_t1 < limit_t1 -1:
numbering_text_t1 += 1
self.screen.ids.scroll_text.text = str(text_t1[numbering_text_t1])
else:
numbering_text_t1= 0
self.screen.ids.scroll_text.text = str(text_t1[numbering_text_t1])
def on_press_action_button(self):
global numbering_text_y1,numbering_text_y2,numbering_text_y3,numbering_text_y4,numbering_text_y5,numbering_text_y6,numbering_text_y7
if Item_id == "Стандарт +14":
if numbering_text_y2 < limit_y2 -1:
numbering_text_y2 += 1
self.screen.ids.scroll_text.text = str(text_y2[numbering_text_y2])
else:
numbering_text_y2= 0
self.screen.ids.scroll_text.text = str(text_y2[numbering_text_y2])
elif Item_id == "Подростки +16":
if numbering_text_y3 < limit_y3 -1:
numbering_text_y3 += 1
self.screen.ids.scroll_text.text = str(text_y3[numbering_text_y3])
else:
numbering_text_y3= 0
self.screen.ids.scroll_text.text = str(text_y3[numbering_text_y3])
elif Item_id == "Экстрим +18":
if numbering_text_y4 < limit_y4 -1:
numbering_text_y4 += 1
self.screen.ids.scroll_text.text = str(text_y4[numbering_text_y4])
else:
numbering_text_y4= 0
self.screen.ids.scroll_text.text = str(text_y4[numbering_text_y4])
elif Item_id == "Безумие +21":
if numbering_text_y5 < limit_y5 -1:
numbering_text_y5 += 1
self.screen.ids.scroll_text.text = str(text_y5[numbering_text_y5])
else:
numbering_text_y5= 0
self.screen.ids.scroll_text.text = str(text_y4[numbering_text_y5])
else:
if numbering_text_y1 < limit_y1 -1:
numbering_text_y1 += 1
self.screen.ids.scroll_text.text = str(text_y1[numbering_text_y1])
else:
numbering_text_y1= 0
self.screen.ids.scroll_text.text = str(text_y2[numbering_text_y1])
Ответы (2 шт):
Замечания
Налицо изначально неправильный дизайн приложения, из-за чего простой, казалось бы, рефакторинг, превращается в сложную задачу. Притом, используемые для рефакторинга способы, тоже неоптимальны и непрозрачны, что повлечёт за собой проблемы в будущем.
Основные проблемы
чрезмерное использование глобальных переменных. Гуглите "Почему глобальные переменные зло".
использование переменных вида
variable_1,variable_2,variable_3, наводит на мысль, что их можно было бы заменить одной переменной типаsequence, например словарём:вместо 7 переменных
numbering_text_y1 = "text" numbering_text_y2 = "text" numbering_text_y3 = "text" numbering_text_y4 = "text" numbering_text_y5 = "text" numbering_text_y6 = "text" numbering_text_y7 = "text"можно использовать одну
dct = { "numbering_text_y1" : "text", "numbering_text_y2" : "text", "numbering_text_y3" : "text", "numbering_text_y4" : "text", "numbering_text_y5" : "text", "numbering_text_y6" : "text", "numbering_text_y7" : "text" }Кроме снижения количества переменных, это решает проблему с передачей переменной в другую функцию и её изменение там. В случае же с глобальными переменными, в другую функцию приходится передавать имя этой переменной в виде строки и использовать там
globals()(что я и сделал в своём решении), ведь в Python нельзя передавать переменную по ссылке.Как вы сами заметили, много
if-ов и дублирования, что является следствием (и показателем) плохого дизайна - повторное использование кода (вынесение повторяющихся действий в отдельную функцию) затруднено из-за того, что глобальные переменные являются объектами неизменяемого типа -int,str. Мы не можем передатьnumbering_text_y1в другую функцию и там изменить его значение. Чтобы это сделать, надо чтобыnumbering_text_y1был объектом изменяемого типа - либо встроенного (list,dict, ...), либо самодельного, созданного с помощьюclass.
Трудно сказать, как стоило бы спроектировать ваше приложение, не видя всего кода и не зная его логики. Рекомендую почитать что-нибудь по проектированию и паттернам, мне нравится "Фримен Эр., Фримен Эл., Сьерра К., Бейтс Б. Паттерны проектирования". Несмотря на то, что там в примерах используется Java, они легко переводятся на Python. Основные же принципы ООП объяснены хорошо.
Рефакторинг
Если нет возможности или желания переделывать всё приложение, а сократить дублирование хочется, то можно сделать так (не тестировал):
def numbering_text(self, numbering_text_n, limit_n, text_n):
number = globals()[numbering_text_n]
number = (number + 1) if (number < limit_n - 1) else 0
self.screen.ids.scroll_text.text = str(text_n[number])
globals()[numbering_text_n] = number
def on_press_true_button(self):
global Item_id
if Item_id == "Стандарт +14":
self.numbering_text("numbering_text_t2", limit_t2, text_t2)
elif Item_id == "Подростки +16":
self.numbering_text("numbering_text_t3", limit_t3, text_t3)
elif Item_id == "Экстрим +18":
self.numbering_text("numbering_text_t4", limit_t4, text_t4)
elif Item_id == "Безумие +21":
self.numbering_text("numbering_text_t5", limit_t5, text_t5)
else:
self.numbering_text("numbering_text_t1", limit_t1, text_t1)
def on_press_action_button(self):
global Item_id
if Item_id == "Стандарт +14":
self.numbering_text("numbering_text_y2", limit_y2, text_y2)
elif Item_id == "Подростки +16":
self.numbering_text("numbering_text_y3", limit_y3, text_y3)
elif Item_id == "Экстрим +18":
self.numbering_text("numbering_text_y4", limit_y4, text_y4)
elif Item_id == "Безумие +21":
self.numbering_text("numbering_text_y5", limit_y5, text_y5)
else:
self.numbering_text("numbering_text_y1", limit_y1, text_y1)
Версию от @MiniMax можно сократить до следующего вида:
def _numbering_text(self, letter):
global Item_id
postfix = "1"
if Item_id == "Стандарт +14":
postfix = "2"
elif Item_id == "Подростки +16":
postfix = "3"
elif Item_id == "Экстрим +18":
postfix = "4"
elif Item_id == "Безумие +21":
postfix = "5"
postfix = letter + postfix
numbering_text = "numbering_text_"+postfix
limit_n = "limit_"+postfix
text_n = "text_"+postfix
number = globals()[numbering_text]
limit = globals()[limit_n]
text = globals()[text_n]
number = (number + 1) if (number < limit - 1) else 0
self.screen.ids.scroll_text.text = str(text[number])
globals()[numbering_text] = number
def on_press_true_button(self):
self._numbering_text("t")
def on_press_action_button(self):
self._numbering_text("y")