Я написал следующую функцию, которая работает, как ожидалось, но все же вижу, что есть место для улучшения ее читабельности.
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 ответ
Функция кажется непоследовательной; Я не знаю, для чего он предназначен, поэтому, если вы скажете, что он работает так, как ожидалось, вероятно, вы можете потерять некоторые функции из-за ненужного «украшения» кода.
О какой непоследовательности я говорю: центральная (и самая длинная) часть кода преобразует 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