Как упростить функцию с помощью нескольких операторов if и нескольких условий?

У меня есть функция, которая должна выводить результаты тестов, которые значительно выше, чем результаты других тестов. Всего существует четыре теста (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».

Я предполагаю, что есть лучший способ сделать это... Пока ничего не могу найти в предыдущих предложенных сообщениях. Есть предположения?

Спасибо!

Используйте типы последовательностей (например, list, dict) вместо последовательности переменных.

Klaus D. 24.05.2024 16:26

Спасибо за ваш ответ. Не могли бы вы проиллюстрировать, как это сделать, на небольшом примере? Я знаком со списками и диктовками, но не для этого.

Cartilago 24.05.2024 16:36

Ну, Stack Overflow — это не учебник. Вам действительно придется выучить язык, если вы хотите программировать на нем. Список и словари — это две очень простые и важные вещи, которые нужно знать в Python.

Klaus D. 24.05.2024 21:31

Справедливо. Однако я бы сказал, что переход от базового понимания словарей и списков к решению, подобному представленному @acw1668, может быть не для всех интуитивным. Но я могу ошибаться.

Cartilago 25.05.2024 09:13
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
4
55
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Прежде всего, вы всегда должны размещать «условия проверки данных» в начале методов. Под «условиями проверки данных» я подразумеваю условия, которые вы проверяете, чтобы иметь возможность правильно выполнить все, что необходимо для запуска метода.

Например:

# 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)

Спасибо! Это было именно то, что я искал. Работало как шарм. Очень элегантно (и поучительно).

Cartilago 25.05.2024 09:08

Другие вопросы по теме