У меня есть функция, которая должна выводить результаты тестов, которые значительно выше, чем результаты других тестов. Всего существует четыре теста (a, b, c и d). Пользователь вводит результаты тестов и проверяет различные кнопки проверки, если между какими-либо результатами тестов существуют значительные различия. Всего 6 кнопок-галочек: «a и b», «a и c», «a и d» и так далее. Пользователь заранее получит доступ ко всей этой информации.
Проблема
Моя текущая функция работает, но чтобы охватить все возможные варианты, мне пришлось бы написать много-много операторов if:
def my_function (A_test_score, B_test_score, C_test_score, D_test_score, A_B_state, A_C_state, A_D_state, B_C_state, B_D_state, C_D_state):
A_test_score = int(a.get())
B_test_score = int(b.get())
C_test_score = int(c.get())
D_test_score = int(d.get())
# Retrieving state of the checkboxes (1 = checked)
A_B_state = A_B_var.get()
A_C_state = A_C_var.get()
A_D_state = A_D_var.get()
B_C_state = B_C_var.get()
B_D_state = B_D_var.get()
C_D_state = C_D_var.get()
final_text = ""
if A_B_state == 1:
if (A_test_score - B_test_score) > 0:
final_text += "A is significantly larger than B"
elif (A_test_score - B_test_score) < 0:
final_text += "B is significantly larger than A"
if A_C_state == 1:
if (A_test_score - C_test_score) > 0:
final_text += "\nA is significantly larger than C"
elif (A_test_score - C_test_score) < 0:
final_text += "\nC is significantly larger than A"
… # and so on…
if A_B_state == 1 and (A_test_score - B_test_score) > 0 and A_C_state == 1 and (A_test_score - C_test_score) > 0 and A_D_state == 1 and (A_test_score - D_test_score) > 0:
return "A is significantly larger than B, C and D"
if A_B_state == 1 and (A_test_score - B_test_score) > 0 and A_C_state == 1 and (A_test_score - C_test_score) > 0:
return "A is significantly larger than B and C"
return final_text
Отключенный выход
Если, например, баллы по тестам a и b значительно больше, чем баллы по тестам c и d: «a и b значительно больше, чем c и d».
А если, например, a больше b, c и d, а b больше d: «a значительно больше, чем b, c и d. b больше, чем d».
Таким образом, цель состоит в том, чтобы избежать избыточных выходных данных, подобных этому: «а значительно больше, чем b. а значительно больше, чем с. а значительно больше, чем d».
Я предполагаю, что есть лучший способ сделать это... Пока ничего не могу найти в предыдущих предложенных сообщениях. Есть предположения?
Спасибо!
Спасибо за ваш ответ. Не могли бы вы проиллюстрировать, как это сделать, на небольшом примере? Я знаком со списками и диктовками, но не для этого.
Ну, Stack Overflow — это не учебник. Вам действительно придется выучить язык, если вы хотите программировать на нем. Список и словари — это две очень простые и важные вещи, которые нужно знать в Python.
Справедливо. Однако я бы сказал, что переход от базового понимания словарей и списков к решению, подобному представленному @acw1668, может быть не для всех интуитивным. Но я могу ошибаться.
Прежде всего, вы всегда должны размещать «условия проверки данных» в начале методов. Под «условиями проверки данных» я подразумеваю условия, которые вы проверяете, чтобы иметь возможность правильно выполнить все, что необходимо для запуска метода.
Например:
# in an imaginary case where 9 is not a number you want to compute
def add_but_not_nine(a, b):
result = a + b
if a == 9 or b == 9:
return "can't compute nines"
return result
Не очень читабельно, тогда как:
# in an imaginary case where 9 is not a number you want to compute
def add_but_not_nine(a, b):
if a == 9 or b == 9:
return "can't compute nines"
return a + b
Это лучше. Это не очень хороший пример, но я надеюсь, что он донесет суть.
Итак, в вашем случае вам следует изменить свой код на это:
def my_function (A_test_score, B_test_score, C_test_score, D_test_score, A_B_state, A_C_state, A_D_state, B_C_state, B_D_state, C_D_state):
A_test_score = int(a.get())
B_test_score = int(b.get())
C_test_score = int(c.get())
D_test_score = int(d.get())
# Retrieving state of the checkboxes (1 = checked)
A_B_state = A_B_var.get()
A_C_state = A_C_var.get()
A_D_state = A_D_var.get()
B_C_state = B_C_var.get()
B_D_state = B_D_var.get()
C_D_state = C_D_var.get()
if A_B_state == 1 and (A_test_score - B_test_score) > 0 and A_C_state == 1 and (A_test_score - C_test_score) > 0 and A_D_state == 1 and (A_test_score - D_test_score) > 0:
return "A is significantly larger than B, C and D"
if A_B_state == 1 and (A_test_score - B_test_score) > 0 and A_C_state == 1 and (A_test_score - C_test_score) > 0:
return "A is significantly larger than B and C"
final_text = ""
if A_B_state == 1:
if (A_test_score - B_test_score) > 0:
final_text += "A is significantly larger than B"
elif (A_test_score - B_test_score) < 0:
final_text += "B is significantly larger than A"
if A_C_state == 1:
if (A_test_score - C_test_score) > 0:
final_text += "\nA is significantly larger than C"
elif (A_test_score - C_test_score) < 0:
final_text += "\nC is significantly larger than A"
… # and so on…
return final_text
Я считаю, что вы можете внести и другие улучшения, но это то, что меня особенно выделяет.
Вы можете использовать список result_a
для хранения элементов, размер которых меньше A. То же самое для B, C и D. Затем вы можете использовать эти списки для создания окончательного текста:
def my_function():
A_test_score = int(a.get())
B_test_score = int(b.get())
C_test_score = int(c.get())
D_test_score = int(d.get())
# Retrieving state of the checkboxes (1 = checked)
A_B_state = A_B_var.get()
A_C_state = A_C_var.get()
A_D_state = A_D_var.get()
B_C_state = B_C_var.get()
B_D_state = B_D_var.get()
C_D_state = C_D_var.get()
# lists to store checking result
result_a = []
result_b = []
result_c = []
result_d = []
if A_B_state:
if A_test_score > B_test_score:
result_a.append("B")
elif B_test_score > A_test_score:
result_b.append("A")
if A_C_state:
if A_test_score > C_test_score:
result_a.append("C")
elif C_test_score > A_test_score:
result_c.append("A")
if A_D_state:
if A_test_score > D_test_score:
result_a.append("D")
elif D_test_score > A_test_score:
result_d.append("A")
if B_C_state:
if B_test_score > C_test_score:
result_b.append("C")
elif C_test_score > B_test_score:
result_c.append("B")
if B_D_state:
if B_test_score > D_test_score:
result_b.append("D")
elif D_test_score > B_test_score:
result_d.append("B")
if C_D_state:
if C_test_score > D_test_score:
result_c.append("D")
elif D_test_score > C_test_score:
result_d.append("C")
# list to construct the final text
final_result = []
if result_a:
final_result.append(f"A is significantly larger than {' and '.join(result_a)}")
if result_b:
final_result.append(f"B is significantly larger than {' and '.join(result_b)}")
if result_c:
final_result.append(f"C is significantly larger than {' and '.join(result_c)}")
if result_d:
final_result.append(f"D is significantly larger than {' and '.join(result_d)}")
# return the final text
return "\n".join(final_result)
Спасибо! Это было именно то, что я искал. Работало как шарм. Очень элегантно (и поучительно).
Используйте типы последовательностей (например,
list
,dict
) вместо последовательности переменных.