Получите список требований по приоритетам

Я написал следующую функцию, которая работает, как ожидалось, но все же вижу, что есть место для улучшения ее читабельности.

def get_claims_to_search():
    claims = []
    database_priority = DatabasePriority.objects.first()

    low_priority_claims_databases = ClaimsDatabase.objects.filter(
        deleted=False, priority="low"
    )
    normal_priority_claims_databases = ClaimsDatabase.objects.filter(
        deleted=False, priority="normal"
    )
    high_priority_claims_databases = ClaimsDatabase.objects.filter(
        deleted=False, priority="high"
    )

    low_priority_count = normal_priority_count = high_priority_count = 0
    if low_priority_claims_databases.count() == 0:
        if normal_priority_claims_databases.count() > 0:
            normal_priority_count += int(
                database_priority.normal
                / (database_priority.normal + database_priority.high)
                * database_priority.low
            )
        if high_priority_claims_databases.count() > 0:
            high_priority_count += int(
                database_priority.high
                / (database_priority.normal + database_priority.high)
                * database_priority.low
            )

    if normal_priority_claims_databases.count() == 0:
        if low_priority_claims_databases.count() > 0:
            low_priority_count += int(
                database_priority.low
                / (database_priority.low + database_priority.high)
                * database_priority.normal
            )
        if high_priority_claims_databases.count() > 0:
            high_priority_count += int(
                database_priority.high
                / (database_priority.low + database_priority.high)
                * database_priority.normal
            )

    if high_priority_claims_databases.count() == 0:
        if low_priority_claims_databases.count() > 0:
            low_priority_count += int(
                database_priority.low
                / (database_priority.low + database_priority.high)
                * database_priority.normal
            )
        if normal_priority_claims_databases.count() > 0:
            normal_priority_count += int(
                database_priority.normal
                / (database_priority.normal + database_priority.high)
                * database_priority.high
            )

    if low_priority_count:
        low_priority_count = (
            low_priority_count // low_priority_claims_databases.count()
        ) * settings.DEBUNKBOT_SEARCHEABLE_CLAIMS_COUNT
        for claim_database in low_priority_claims_databases:
            claims.append(
                claim_database.claims.filter(processed=False, rating=False).values(
                    "claim_first_appearance"
                )[:low_priority_count]
            )
    if normal_priority_count:
        normal_priority_count = (
            normal_priority_count // normal_priority_claims_databases.count()
        ) * settings.DEBUNKBOT_SEARCHEABLE_CLAIMS_COUNT
        for claim_database in normal_priority_claims_databases:
            claims.append(
                claim_database.claims.filter(processed=False, rating=False).values(
                    "claim_first_appearance"
                )[:normal_priority_count]
            )

    if high_priority_count:
        high_priority_count = (
            high_priority_count // high_priority_claims_databases.count()
        ) * settings.DEBUNKBOT_SEARCHEABLE_CLAIMS_COUNT
        for claim_database in high_priority_claims_databases:
            claims.append(
                claim_database.claims.filter(processed=False, rating=False).values(
                    "claim_first_appearance"
                )[:high_priority_count]
            )

    return claims

есть предложения, как я могу его улучшить / переписать?

1 ответ
1

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

О какой непоследовательности я говорю: центральная (и самая длинная) часть кода преобразует 6 входных значений, *_priority_claims_databases.count() а также database_priority.* (где * — низкий, нормальный и высокий) на 3 выходных значения, *_priority_count, используя что-то вроде одной формулы. Я буду использовать короткие имена $ dl $ для database_priority.low а также $ pl $ для low_priority_count и т.д., чтобы сделать формулы более читабельными. Итак, мы имеем (без учета условий):

pn += int( dn / (dn + dh) * dl )
ph += int( dh / (dn + dh) * dl )
pl += int( dl / (dl + dh) * dn )
ph += int( dh / (dl + dh) * dn )
pl += int( dl / (dl + dh) * dn ) #<--!!!!!
pn += int( dn / (dn + dh) * dh )

На данный момент ясно, что первые две строки (в if low_priority_claims_databases.count() == 0: закончить с dl), вторые две строки — с dn, 6 линия — с dh, что соответствует условию, но выделяется 5-я строка. Если мы изменим dh+dh в s-dl (куда s=dh+dn+dl) проблема усугубится:

pn += int( dn / (s - dl) * dl )
ph += int( dh / (s - dl) * dl )
pl += int( dl / (s - dn) * dn )
ph += int( dh / (s - dn) * dn )
pl += int( dl / (s - dn) * dn ) #<--!!!!!
pn += int( dn / (s - dl) * dh ) #<--!!!!!

Теперь две линии вышли из строя. Извините, тут ничего не могу поделать без описания.

Тем не менее, мы можем что-то сделать с последней частью кода. Создадим словари с ключами «низкий», «нормальный» и «высокий» (или список и константы) вместо групп переменных; так что у нас будет

if priority_count["low"]:
    priority_count["low"] = (
        priority_count["low"] // priority_claims_databases["low"].count()
    ) * settings.DEBUNKBOT_SEARCHEABLE_CLAIMS_COUNT
    for claim_database in priority_claims_databases["low"]:
        claims.append(
            claim_database.claims.filter(processed=False, rating=False).values(
                "claim_first_appearance"
            )[:priority_count["low"]]

и два других фрагмента кода с единственным изменением «низкий» на «нормальный» и «высокий». Это можно изменить в цикле:

for priority in ["low","normal","high"]:
    if priority_count[priority]:
        priority_count[priority] = (
            priority_count[priority] // priority_claims_databases[priority].count()
        ) * settings.DEBUNKBOT_SEARCHEABLE_CLAIMS_COUNT
        for claim_database in priority_claims_databases[priority]:
            claims.append(
                claim_database.claims.filter(processed=False, rating=False).values(
                    "claim_first_appearance"
                )[:priority_count[priority]]

Он по крайней мере так же читабелен, как и ваш код, но почти в 3 раза короче.

Еще один вопрос: что произойдет, если все * _priority_claims_databases.count () больше нуля? Предполагается ли, что код вернет пустой список?

  • Спасибо за это. Для более подробной информации, функция должна построить список claims исходя из разных приоритетов. У меня есть 3 типа баз данных (низкий, нормальный и высокий), и каждый уровень имеет определенный процент, например, низкий может быть 15%, нормальный 35% и т. Д. Если у нас нет базы данных с низким приоритетом, мы хотим повторно распределить 15% и на Нормальный, и на Высокий, т.е. Нормальный теперь будет 35+ (35 / (35 + 50) * 15), где 50 — это% возраст высокого приоритета. Если все счетчики больше 0, то все если * _priority_count: будет истинным и, следовательно, не будет возвращен пустой список.

    — Esir Kings


Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *